├── .gitignore
├── .metadata
├── .vscode
└── settings.json
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── heyanle
│ │ │ │ └── easy_book
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.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
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── sakiko_error.png
├── sakiko_loading.gif
├── sakiko_ok.png
└── sakiko_pull.png
├── build.yaml
├── devtools_options.yaml
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── 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-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.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
└── RunnerTests
│ └── RunnerTests.swift
├── lib
├── app.dart
├── c.dart
├── database
│ ├── dao
│ │ ├── manga
│ │ │ ├── manga_dao.dart
│ │ │ └── manga_dao.g.dart
│ │ └── novel
│ │ │ ├── novel_dao.dart
│ │ │ └── novel_dao.g.dart
│ ├── database.dart
│ ├── database.g.dart
│ └── db
│ │ ├── manga
│ │ ├── manga_db.dart
│ │ └── manga_db.g.dart
│ │ └── novel
│ │ ├── novel_db.dart
│ │ └── novel_db.g.dart
├── entity
│ ├── book
│ │ ├── cover
│ │ │ ├── book_cover.dart
│ │ │ ├── book_cover.freezed.dart
│ │ │ └── book_cover.g.dart
│ │ └── home_tab
│ │ │ ├── book_home_tab.dart
│ │ │ ├── book_home_tab.freezed.dart
│ │ │ └── book_home_tab.g.dart
│ ├── extension
│ │ ├── extension_data
│ │ │ ├── extension_data.dart
│ │ │ ├── extension_data.freezed.dart
│ │ │ └── extension_data.g.dart
│ │ └── extension_info
│ │ │ ├── extension_info.dart
│ │ │ ├── extension_info.freezed.dart
│ │ │ └── extension_info.g.dart
│ ├── manga
│ │ ├── manga_chapter
│ │ │ ├── manga_chapter.dart
│ │ │ ├── manga_chapter.freezed.dart
│ │ │ └── manga_chapter.g.dart
│ │ ├── manga_cover
│ │ │ ├── manga_cover.dart
│ │ │ ├── manga_cover.freezed.dart
│ │ │ └── manga_cover.g.dart
│ │ ├── manga_detailed
│ │ │ ├── manga_detailed.dart
│ │ │ ├── manga_detailed.freezed.dart
│ │ │ └── manga_detailed.g.dart
│ │ ├── manga_enum.dart
│ │ ├── manga_info
│ │ │ └── manga_info.dart
│ │ ├── manga_picture
│ │ │ ├── manga_picture.dart
│ │ │ ├── manga_picture.freezed.dart
│ │ │ └── manga_picture.g.dart
│ │ └── manga_summary
│ │ │ ├── manga_summary.dart
│ │ │ ├── manga_summary.freezed.dart
│ │ │ └── manga_summary.g.dart
│ ├── novel
│ │ ├── novel_chapter
│ │ │ ├── novel_chapter.dart
│ │ │ ├── novel_chapter.freezed.dart
│ │ │ └── novel_chapter.g.dart
│ │ ├── novel_cover
│ │ │ ├── novel_cover.dart
│ │ │ ├── novel_cover.freezed.dart
│ │ │ └── novel_cover.g.dart
│ │ ├── novel_detailed
│ │ │ ├── novel_detailed.dart
│ │ │ ├── novel_detailed.freezed.dart
│ │ │ └── novel_detailed.g.dart
│ │ ├── novel_enum.dart
│ │ ├── novel_info
│ │ │ └── novel_info.dart
│ │ ├── novel_summary
│ │ │ ├── novel_summary.dart
│ │ │ ├── novel_summary.freezed.dart
│ │ │ └── novel_summary.g.dart
│ │ └── novel_volume
│ │ │ ├── novel_volume.dart
│ │ │ ├── novel_volume.freezed.dart
│ │ │ └── novel_volume.g.dart
│ └── source
│ │ ├── source_data
│ │ └── source_data.dart
│ │ └── source_info
│ │ ├── source_info.dart
│ │ ├── source_info.freezed.dart
│ │ └── source_info.g.dart
├── hive_registrar.g.dart
├── l10n
│ ├── arb
│ │ └── intl_zh_CN.arb
│ ├── intl
│ │ ├── messages_all.dart
│ │ └── messages_zh_CN.dart
│ └── l10n.dart
├── plugin
│ ├── component
│ │ ├── api
│ │ │ ├── component.dart
│ │ │ ├── manga
│ │ │ │ ├── detailed
│ │ │ │ │ ├── manga_detailed_component.dart
│ │ │ │ │ └── resp
│ │ │ │ │ │ ├── detailed_resp.dart
│ │ │ │ │ │ ├── detailed_resp.freezed.dart
│ │ │ │ │ │ └── detailed_resp.g.dart
│ │ │ │ ├── home
│ │ │ │ │ ├── manga_home_component.dart
│ │ │ │ │ ├── page
│ │ │ │ │ │ ├── home_page.dart
│ │ │ │ │ │ ├── home_page.freezed.dart
│ │ │ │ │ │ └── home_page.g.dart
│ │ │ │ │ ├── resp
│ │ │ │ │ │ ├── home_resp.dart
│ │ │ │ │ │ ├── home_resp.freezed.dart
│ │ │ │ │ │ └── home_resp.g.dart
│ │ │ │ │ └── tab
│ │ │ │ │ │ ├── home_tab.dart
│ │ │ │ │ │ ├── home_tab.freezed.dart
│ │ │ │ │ │ └── home_tab.g.dart
│ │ │ │ ├── read
│ │ │ │ │ ├── manga_read_component.dart
│ │ │ │ │ └── resp
│ │ │ │ │ │ ├── read_resp.dart
│ │ │ │ │ │ ├── read_resp.freezed.dart
│ │ │ │ │ │ └── read_resp.g.dart
│ │ │ │ └── search
│ │ │ │ │ ├── manga_search_component.dart
│ │ │ │ │ └── resp
│ │ │ │ │ ├── search_resp.dart
│ │ │ │ │ ├── search_resp.freezed.dart
│ │ │ │ │ └── search_resp.g.dart
│ │ │ ├── novel
│ │ │ │ ├── detailed
│ │ │ │ │ ├── novel_detailed_component.dart
│ │ │ │ │ └── resp
│ │ │ │ │ │ ├── detailed_resp.dart
│ │ │ │ │ │ ├── detailed_resp.freezed.dart
│ │ │ │ │ │ └── detailed_resp.g.dart
│ │ │ │ ├── home
│ │ │ │ │ ├── novel_home_component.dart
│ │ │ │ │ ├── page
│ │ │ │ │ │ ├── home_page.dart
│ │ │ │ │ │ ├── home_page.freezed.dart
│ │ │ │ │ │ └── home_page.g.dart
│ │ │ │ │ ├── resp
│ │ │ │ │ │ ├── home_resp.dart
│ │ │ │ │ │ ├── home_resp.freezed.dart
│ │ │ │ │ │ └── home_resp.g.dart
│ │ │ │ │ └── tab
│ │ │ │ │ │ ├── home_tab.dart
│ │ │ │ │ │ ├── home_tab.freezed.dart
│ │ │ │ │ │ └── home_tab.g.dart
│ │ │ │ ├── read
│ │ │ │ │ ├── novel_read_component.dart
│ │ │ │ │ └── resp
│ │ │ │ │ │ ├── read_resp.dart
│ │ │ │ │ │ ├── read_resp.freezed.dart
│ │ │ │ │ │ └── read_resp.g.dart
│ │ │ │ └── search
│ │ │ │ │ ├── novel_search_component.dart
│ │ │ │ │ └── resp
│ │ │ │ │ ├── search_resp.dart
│ │ │ │ │ ├── search_resp.freezed.dart
│ │ │ │ │ └── search_resp.g.dart
│ │ │ └── payload
│ │ │ │ ├── component_payload.dart
│ │ │ │ ├── component_payload.freezed.dart
│ │ │ │ └── component_payload.g.dart
│ │ └── core
│ │ │ └── js
│ │ │ ├── js_component.dart
│ │ │ ├── manga
│ │ │ ├── detailed
│ │ │ │ └── js_manga_detailed_component.dart
│ │ │ ├── home
│ │ │ │ └── js_manga_home_component.dart
│ │ │ ├── read
│ │ │ │ └── js_manga_read_component.dart
│ │ │ └── search
│ │ │ │ └── js_manga_search_component.dart
│ │ │ ├── novel
│ │ │ ├── detailed
│ │ │ │ └── js_novel_detailed_component.dart
│ │ │ ├── home
│ │ │ │ └── js_novel_home_component.dart
│ │ │ ├── read
│ │ │ │ └── js_novel_read_component.dart
│ │ │ └── search
│ │ │ │ └── js_novel_search_component.dart
│ │ │ └── utils
│ │ │ └── js_component_utils.dart
│ ├── extension
│ │ ├── controller
│ │ │ ├── extension_controller.dart
│ │ │ ├── extension_controller.freezed.dart
│ │ │ └── extension_controller.g.dart
│ │ ├── loader
│ │ │ ├── extension_loader.dart
│ │ │ ├── inner
│ │ │ │ └── inner_extension_loader.dart
│ │ │ ├── js
│ │ │ │ └── js_extension_loader.dart
│ │ │ └── mygopack
│ │ │ │ ├── manifest
│ │ │ │ ├── mygopack_manifest_info.dart
│ │ │ │ ├── mygopack_manifest_info.freezed.dart
│ │ │ │ └── mygopack_manifest_info.g.dart
│ │ │ │ └── mygopack_extension_loader.dart
│ │ └── utils
│ │ │ └── extension_utils.dart
│ ├── inner
│ │ ├── inner_source.dart
│ │ └── test
│ │ │ ├── component
│ │ │ ├── manga
│ │ │ │ └── manga_test_component.dart
│ │ │ └── novel
│ │ │ │ └── novel_test_component.dart
│ │ │ └── test_inner_source.dart
│ └── source
│ │ ├── config_controller
│ │ ├── source_config_controller.dart
│ │ ├── source_config_controller.freezed.dart
│ │ └── source_config_controller.g.dart
│ │ ├── controller
│ │ ├── source_controller.dart
│ │ └── source_controller.g.dart
│ │ ├── load_controller
│ │ ├── source_load_controller.dart
│ │ └── source_load_controller.g.dart
│ │ ├── loader
│ │ ├── inner
│ │ │ └── inner_source_loader.dart
│ │ ├── js
│ │ │ ├── js_source_loader.dart
│ │ │ └── js_source_utils.dart
│ │ └── source_loader.dart
│ │ └── utils
│ │ ├── action
│ │ ├── buffer_action.dart
│ │ ├── entity
│ │ │ ├── web_view_resp
│ │ │ │ ├── web_view_resp.dart
│ │ │ │ ├── web_view_resp.freezed.dart
│ │ │ │ └── web_view_resp.g.dart
│ │ │ └── web_view_strategy
│ │ │ │ ├── web_view_strategy.dart
│ │ │ │ ├── web_view_strategy.freezed.dart
│ │ │ │ └── web_view_strategy.g.dart
│ │ ├── html_action.dart
│ │ ├── source_action.dart
│ │ ├── web_view_action.dart
│ │ └── xpath_action.dart
│ │ ├── buffer_utils.dart
│ │ └── source_utils_scope.dart
├── repository
│ └── book_cover
│ │ ├── book_cover_repository
│ │ └── book_cover_repository.dart
│ │ └── page
│ │ ├── book_cover_page.dart
│ │ ├── manga_cover_page.dart
│ │ └── novel_cover_page.dart
├── router.dart
├── router.g.dart
├── theme
│ ├── theme.dart
│ ├── theme.freezed.dart
│ └── theme.g.dart
├── ui
│ ├── common
│ │ ├── cover_card.dart
│ │ ├── custom_sliver_grid.dart
│ │ └── loading_icon.dart
│ ├── main
│ │ ├── history
│ │ │ └── history.dart
│ │ ├── home
│ │ │ ├── home.dart
│ │ │ ├── page
│ │ │ │ ├── home_book_page.dart
│ │ │ │ └── view_model
│ │ │ │ │ ├── home_page_view_model.dart
│ │ │ │ │ ├── home_page_view_model.freezed.dart
│ │ │ │ │ └── home_page_view_model.g.dart
│ │ │ └── view_model
│ │ │ │ ├── home_view_model.dart
│ │ │ │ ├── home_view_model.freezed.dart
│ │ │ │ └── home_view_model.g.dart
│ │ ├── library
│ │ │ └── library.dart
│ │ ├── main.dart
│ │ └── more
│ │ │ └── more.dart
│ └── splash
│ │ └── splash.dart
└── utils
│ ├── cancelable_task
│ └── cancelable_task.dart
│ ├── file_index
│ ├── file_index_utils.dart
│ └── item
│ │ ├── file_index_item.dart
│ │ ├── file_index_item.freezed.dart
│ │ └── file_index_item.g.dart
│ ├── hive
│ └── hive.dart
│ ├── json.dart
│ ├── platform.dart
│ └── zip
│ └── zip_utils.dart
├── linux
├── .gitignore
├── CMakeLists.txt
├── flutter
│ └── CMakeLists.txt
├── main.cc
├── my_application.cc
└── my_application.h
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ └── Flutter-Release.xcconfig
├── 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
└── RunnerTests
│ └── RunnerTests.swift
├── make
├── README.md
├── bin
│ └── make.dart
└── pubspec.yaml
├── pubspec.yaml
├── test
└── widget_test.dart
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── index.html
└── manifest.json
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
└── CMakeLists.txt
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.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 and should not be manually edited.
5 |
6 | version:
7 | revision: "0d074ced6cd64f39f586aaa115b2e4c993d74cb7"
8 | channel: "beta"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
17 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
18 | - platform: android
19 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
20 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
21 | - platform: ios
22 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
23 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
24 | - platform: linux
25 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
26 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
27 | - platform: macos
28 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
29 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
30 | - platform: web
31 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
32 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
33 | - platform: windows
34 | create_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
35 | base_revision: 0d074ced6cd64f39f586aaa115b2e4c993d74cb7
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/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cmake.ignoreCMakeListsMissing": true
3 | }
--------------------------------------------------------------------------------
/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 | analyzer:
28 | plugins:
29 | - custom_lint
30 | errors:
31 | invalid_annotation_target: ignore
32 | # Additional information about this file can be found at
33 | # https://dart.dev/guides/language/analysis-options
34 |
--------------------------------------------------------------------------------
/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/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
9 |
10 |
14 |
22 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/heyanle/easy_book/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.heyanle.easy_mygo
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/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/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.3.0'
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 | tasks.register("clean", 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.5-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 |
--------------------------------------------------------------------------------
/assets/sakiko_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/assets/sakiko_error.png
--------------------------------------------------------------------------------
/assets/sakiko_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/assets/sakiko_loading.gif
--------------------------------------------------------------------------------
/assets/sakiko_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/assets/sakiko_ok.png
--------------------------------------------------------------------------------
/assets/sakiko_pull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/assets/sakiko_pull.png
--------------------------------------------------------------------------------
/build.yaml:
--------------------------------------------------------------------------------
1 | targets:
2 | $default:
3 | builders:
4 | riverpod_generator:
5 | options:
6 | provider_name_suffix: "Pod" # (default)
7 | provider_family_name_suffix: "Provider"
8 |
--------------------------------------------------------------------------------
/devtools_options.yaml:
--------------------------------------------------------------------------------
1 | description: This file stores settings for Dart & Flutter DevTools.
2 | documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
3 | extensions:
4 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easybangumiorg/EasyMyGo/8f9a7163c5d4c9744f32b1f2b8a68577fa8e3fce/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/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 | Easy Book
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | easy_mygo
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 |
51 |
52 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/lib/c.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'dart:io';
3 |
4 | import 'package:path/path.dart';
5 | import 'package:path_provider/path_provider.dart';
6 |
7 | class EasyConstant {
8 | static const versionName = String.fromEnvironment("VERSION_NAME", defaultValue: "dev");
9 | static final versionCode = int.tryParse(const String.fromEnvironment("VERSION_CODE", defaultValue: "0")) ?? 0;
10 |
11 | static final applicationPath = Future(() async {
12 | final rootPath = await getApplicationSupportDirectory();
13 | final dir = Directory(join(rootPath.absolute.path, "files"));
14 | await dir.create(recursive: true);
15 | return dir;
16 | });
17 |
18 | static final tempPath = Future(() async {
19 | final rootPath = await getApplicationSupportDirectory();
20 | final dir = Directory(join(rootPath.absolute.path, "temp"));
21 | await dir.create(recursive: true);
22 | return dir;
23 | });
24 |
25 | static final cachePath = Future(() async {
26 | final rootPath = await getApplicationSupportDirectory();
27 | final dir = Directory(join(rootPath.absolute.path, "cache"));
28 | await dir.create(recursive: true);
29 | return dir;
30 | });
31 | }
32 |
--------------------------------------------------------------------------------
/lib/database/dao/manga/manga_dao.dart:
--------------------------------------------------------------------------------
1 | import 'package:drift/drift.dart';
2 | import 'package:easy_mygo/database/db/manga/manga_db.dart';
3 | import 'package:easy_mygo/entity/manga/manga_info/manga_info.dart';
4 |
5 | part 'manga_dao.g.dart';
6 |
7 | @DriftAccessor(tables: [MangaTable])
8 | class MangaDao extends DatabaseAccessor with _$MangaDaoMixin {
9 | // Rthis constructor is required so that the main database can create an instance
10 | // of this object.
11 | MangaDao(super.db);
12 |
13 | Future> selectAll() async {
14 | return await select(mangaTable).get();
15 | }
16 |
17 | Stream> watchAll() {
18 | return select(mangaTable).watch();
19 | }
20 |
21 | Stream> watchStar() {
22 | return (select(mangaTable)
23 | ..where((tbl) => tbl.starTime.isBiggerThan(const Constant(0))))
24 | .watch();
25 | }
26 |
27 | Stream> watchHistory() {
28 | return (select(mangaTable)
29 | ..where((tbl) => tbl.lastHistoryTime.isBiggerThan(const Constant(0))))
30 | .watch();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/database/dao/manga/manga_dao.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'manga_dao.dart';
4 |
5 | // ignore_for_file: type=lint
6 | mixin _$MangaDaoMixin on DatabaseAccessor {
7 | $MangaTableTable get mangaTable => attachedDatabase.mangaTable;
8 | }
9 |
--------------------------------------------------------------------------------
/lib/database/dao/novel/novel_dao.dart:
--------------------------------------------------------------------------------
1 | import 'package:drift/drift.dart';
2 | import 'package:easy_mygo/database/db/novel/novel_db.dart';
3 | import 'package:easy_mygo/entity/novel/novel_info/novel_info.dart';
4 |
5 | part 'novel_dao.g.dart';
6 |
7 | @DriftAccessor(tables: [NovelTable])
8 | class NovelDao extends DatabaseAccessor with _$NovelDaoMixin {
9 | // Rthis constructor is required so that the main database can create an instance
10 | // of this object.
11 | NovelDao(super.db);
12 |
13 | // Future> selectAll() async {
14 | // return await select(mangaTable).get();
15 | // }
16 | //
17 | // Stream> watchAll() {
18 | // return select(mangaTable).watch();
19 | // }
20 | //
21 | // Stream> watchStar() {
22 | // return (select(mangaTable)
23 | // ..where((tbl) => tbl.starTime.isBiggerThan(const Constant(0))))
24 | // .watch();
25 | // }
26 | //
27 | // Stream> watchHistory() {
28 | // return (select(mangaTable)
29 | // ..where((tbl) => tbl.lastHistoryTime.isBiggerThan(const Constant(0))))
30 | // .watch();
31 | // }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/database/dao/novel/novel_dao.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'novel_dao.dart';
4 |
5 | // ignore_for_file: type=lint
6 | mixin _$NovelDaoMixin on DatabaseAccessor {
7 | $NovelTableTable get novelTable => attachedDatabase.novelTable;
8 | }
9 |
--------------------------------------------------------------------------------
/lib/database/database.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'database.dart';
4 |
5 | // **************************************************************************
6 | // RiverpodGenerator
7 | // **************************************************************************
8 |
9 | String _$databaseControllerHash() =>
10 | r'c3b5726e447d53a150aeb916bc620e81ecab4695';
11 |
12 | /// See also [DatabaseController].
13 | @ProviderFor(DatabaseController)
14 | final databaseControllerPod =
15 | NotifierProvider.internal(
16 | DatabaseController.new,
17 | name: r'databaseControllerPod',
18 | debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
19 | ? null
20 | : _$databaseControllerHash,
21 | dependencies: null,
22 | allTransitiveDependencies: null,
23 | );
24 |
25 | typedef _$DatabaseController = Notifier;
26 | // ignore_for_file: type=lint
27 | // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
28 |
--------------------------------------------------------------------------------
/lib/database/db/manga/manga_db.dart:
--------------------------------------------------------------------------------
1 | import 'package:drift/drift.dart';
2 | import 'package:drift/native.dart';
3 | import 'package:easy_mygo/database/dao/manga/manga_dao.dart';
4 | import 'package:easy_mygo/entity/manga/manga_enum.dart';
5 | import 'package:easy_mygo/entity/manga/manga_info/manga_info.dart';
6 |
7 | part 'manga_db.g.dart';
8 |
9 | @DriftDatabase(tables: [MangaTable], daos: [MangaDao])
10 | class MangaDB extends _$MangaDB {
11 | // we tell the database where to store the data with this constructor
12 |
13 | // you should bump this number whenever you change or add a table definition. Migrations
14 | // are covered later in this readme.
15 | @override
16 | int get schemaVersion => 1;
17 |
18 | @override
19 | MigrationStrategy get migration => MigrationStrategy(onCreate: (Migrator m) {
20 | return m.createAll();
21 | }, onUpgrade: (Migrator m, int from, int to) async {
22 | // 版本更新
23 | });
24 |
25 | MangaDB(NativeDatabase super.database);
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/lib/database/db/novel/novel_db.dart:
--------------------------------------------------------------------------------
1 | import 'package:drift/drift.dart';
2 | import 'package:drift/native.dart';
3 | import 'package:easy_mygo/database/dao/novel/novel_dao.dart';
4 | import 'package:easy_mygo/entity/novel/novel_info/novel_info.dart';
5 | import 'package:easy_mygo/entity/novel/novel_enum.dart';
6 |
7 | part 'novel_db.g.dart';
8 |
9 | @DriftDatabase(tables: [NovelTable], daos: [NovelDao])
10 | class NovelDB extends _$NovelDB {
11 | // we tell the database where to store the data with this constructor
12 |
13 | // you should bump this number whenever you change or add a table definition. Migrations
14 | // are covered later in this readme.
15 | @override
16 | int get schemaVersion => 1;
17 |
18 | @override
19 | MigrationStrategy get migration => MigrationStrategy(onCreate: (Migrator m) {
20 | return m.createAll();
21 | }, onUpgrade: (Migrator m, int from, int to) async {
22 | // 版本更新
23 | });
24 |
25 | NovelDB(NativeDatabase super.database);
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/lib/entity/book/cover/book_cover.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:easy_mygo/entity/manga/manga_cover/manga_cover.dart';
3 | import 'package:easy_mygo/entity/novel/novel_cover/novel_cover.dart';
4 | import 'package:easy_mygo/entity/source/source_info/source_info.dart';
5 | import 'package:freezed_annotation/freezed_annotation.dart';
6 |
7 | part 'book_cover.g.dart';
8 | part 'book_cover.freezed.dart';
9 |
10 | // 一本书的封面,主要是把 MangaCover 和 NovelCover 合并一波
11 | // 在封面显示
12 | @freezed
13 | class BookCover with _$BookCover {
14 |
15 | factory BookCover({
16 | required SourceType type,
17 | required String id,
18 | required String label,
19 | required String cover,
20 | required String intro,
21 | @JsonKey(name: "jump_url") required String jumpUrl,
22 | required String source,
23 | required String ext,
24 | }) = _BookCover;
25 |
26 | factory BookCover.fromJson(Map json) => _$BookCoverFromJson(json);
27 |
28 | factory BookCover.fromNovelCover(NovelCover novelCover) {
29 | return BookCover(
30 | type: SourceType.novel,
31 | id: novelCover.id,
32 | label: novelCover.label,
33 | cover: novelCover.cover,
34 | intro: novelCover.intro,
35 | jumpUrl: novelCover.jumpUrl,
36 | source: novelCover.source,
37 | ext: novelCover.ext,
38 | );
39 | }
40 |
41 | factory BookCover.fromMangaCover(MangaCover mangaCover) {
42 | return BookCover(
43 | type: SourceType.manga,
44 | id: mangaCover.id,
45 | label: mangaCover.label,
46 | cover: mangaCover.cover,
47 | intro: mangaCover.intro,
48 | jumpUrl: mangaCover.jumpUrl,
49 | source: mangaCover.source,
50 | ext: mangaCover.ext,
51 | );
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/lib/entity/book/cover/book_cover.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'book_cover.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$BookCoverImpl _$$BookCoverImplFromJson(Map json) =>
10 | _$BookCoverImpl(
11 | type: $enumDecode(_$SourceTypeEnumMap, json['type']),
12 | id: json['id'] as String,
13 | label: json['label'] as String,
14 | cover: json['cover'] as String,
15 | intro: json['intro'] as String,
16 | jumpUrl: json['jump_url'] as String,
17 | source: json['source'] as String,
18 | ext: json['ext'] as String,
19 | );
20 |
21 | Map _$$BookCoverImplToJson(_$BookCoverImpl instance) =>
22 | {
23 | 'type': _$SourceTypeEnumMap[instance.type]!,
24 | 'id': instance.id,
25 | 'label': instance.label,
26 | 'cover': instance.cover,
27 | 'intro': instance.intro,
28 | 'jump_url': instance.jumpUrl,
29 | 'source': instance.source,
30 | 'ext': instance.ext,
31 | };
32 |
33 | const _$SourceTypeEnumMap = {
34 | SourceType.manga: 'manga',
35 | SourceType.novel: 'novel',
36 | };
37 |
--------------------------------------------------------------------------------
/lib/entity/book/home_tab/book_home_tab.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'book_home_tab.freezed.dart';
6 | part 'book_home_tab.g.dart';
7 |
8 | @freezed
9 | class BookHomeTab with _$BookHomeTab {
10 | factory BookHomeTab({
11 | required String id,
12 | required String label,
13 | // 是否有 二级 tab
14 | @JsonKey(name: "has_second_tab") required bool hasSecondTab,
15 |
16 | // 可以让源透传一些信息
17 | @Default('') String ext,
18 | }) = _BookHomeTab;
19 |
20 | factory BookHomeTab.fromJson(Map json) =>
21 | _$BookHomeTabFromJson(json);
22 | }
23 |
24 | @freezed
25 | class BookSecondTab with _$BookSecondTab {
26 | factory BookSecondTab({
27 | required String id,
28 | required String label,
29 |
30 | // 可以让源透传一些信息
31 | @Default('') String ext,
32 | }) = _BookSecondTab;
33 |
34 | factory BookSecondTab.fromJson(Map json) =>
35 | _$BookSecondTabFromJson(json);
36 | }
--------------------------------------------------------------------------------
/lib/entity/book/home_tab/book_home_tab.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'book_home_tab.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$BookHomeTabImpl _$$BookHomeTabImplFromJson(Map json) =>
10 | _$BookHomeTabImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | hasSecondTab: json['has_second_tab'] as bool,
14 | ext: json['ext'] as String? ?? '',
15 | );
16 |
17 | Map _$$BookHomeTabImplToJson(_$BookHomeTabImpl instance) =>
18 | {
19 | 'id': instance.id,
20 | 'label': instance.label,
21 | 'has_second_tab': instance.hasSecondTab,
22 | 'ext': instance.ext,
23 | };
24 |
25 | _$BookSecondTabImpl _$$BookSecondTabImplFromJson(Map json) =>
26 | _$BookSecondTabImpl(
27 | id: json['id'] as String,
28 | label: json['label'] as String,
29 | ext: json['ext'] as String? ?? '',
30 | );
31 |
32 | Map _$$BookSecondTabImplToJson(_$BookSecondTabImpl instance) =>
33 | {
34 | 'id': instance.id,
35 | 'label': instance.label,
36 | 'ext': instance.ext,
37 | };
38 |
--------------------------------------------------------------------------------
/lib/entity/extension/extension_data/extension_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/extension/extension_info/extension_info.dart';
2 | import 'package:easy_mygo/entity/source/source_info/source_info.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'extension_data.g.dart';
6 |
7 | part 'extension_data.freezed.dart';
8 |
9 | /// ExtensionInfo 加载结果
10 | /// 拓展管理界面依赖的实体
11 |
12 | enum ExtensionLoadState { loaded, error }
13 |
14 | @freezed
15 | class ExtensionData with _$ExtensionData {
16 | factory ExtensionData({
17 | required ExtensionInfo info,
18 | @Default(null) List? sources,
19 | @Default(ExtensionLoadState.loaded) ExtensionLoadState state,
20 | @JsonKey(name: "error_msg") @Default("") String errorMsg,
21 | // 该插件的文件夹
22 | @JsonKey(name: "folder_path") required String folderPath,
23 | }) = _ExtensionData;
24 |
25 | factory ExtensionData.fromJson(Map json) =>
26 | _$ExtensionDataFromJson(json);
27 | }
28 |
--------------------------------------------------------------------------------
/lib/entity/extension/extension_data/extension_data.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'extension_data.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$ExtensionDataImpl _$$ExtensionDataImplFromJson(Map json) =>
10 | _$ExtensionDataImpl(
11 | info: ExtensionInfo.fromJson(json['info'] as Map),
12 | sources: (json['sources'] as List?)
13 | ?.map((e) => SourceInfo.fromJson(e as Map))
14 | .toList() ??
15 | null,
16 | state: $enumDecodeNullable(_$ExtensionLoadStateEnumMap, json['state']) ??
17 | ExtensionLoadState.loaded,
18 | errorMsg: json['error_msg'] as String? ?? "",
19 | folderPath: json['folder_path'] as String,
20 | );
21 |
22 | Map _$$ExtensionDataImplToJson(_$ExtensionDataImpl instance) =>
23 | {
24 | 'info': instance.info,
25 | 'sources': instance.sources,
26 | 'state': _$ExtensionLoadStateEnumMap[instance.state]!,
27 | 'error_msg': instance.errorMsg,
28 | 'folder_path': instance.folderPath,
29 | };
30 |
31 | const _$ExtensionLoadStateEnumMap = {
32 | ExtensionLoadState.loaded: 'loaded',
33 | ExtensionLoadState.error: 'error',
34 | };
35 |
--------------------------------------------------------------------------------
/lib/entity/extension/extension_info/extension_info.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'extension_info.freezed.dart';
4 |
5 | part 'extension_info.g.dart';
6 |
7 | enum ExtensionLoaderType {
8 | // 单个纯 js 文件
9 | js,
10 | // mygo 包,包里的文件格式交给 loader 去处理了
11 | mygopack,
12 |
13 | // 内置拓展,统一一个
14 | inner,
15 | }
16 |
17 | @freezed
18 | class ExtensionInfo with _$ExtensionInfo {
19 | factory ExtensionInfo({
20 | // 包名唯一
21 | required String package,
22 | required String label,
23 | @JsonKey(name: 'version_name') required String versionName,
24 | @JsonKey(name: 'version_code') required int versionCode,
25 | @JsonKey(name: 'lib_version') required int libVersion,
26 | @JsonKey(name: 'extension_load_type') required ExtensionLoaderType loadType,
27 | required String path,
28 | @Default("") String readme,
29 | }) = _ExtensionInfo;
30 |
31 | factory ExtensionInfo.fromJson(Map json) =>
32 | _$ExtensionInfoFromJson(json);
33 | }
34 |
--------------------------------------------------------------------------------
/lib/entity/extension/extension_info/extension_info.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'extension_info.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$ExtensionInfoImpl _$$ExtensionInfoImplFromJson(Map json) =>
10 | _$ExtensionInfoImpl(
11 | package: json['package'] as String,
12 | label: json['label'] as String,
13 | versionName: json['version_name'] as String,
14 | versionCode: (json['version_code'] as num).toInt(),
15 | libVersion: (json['lib_version'] as num).toInt(),
16 | loadType: $enumDecode(
17 | _$ExtensionLoaderTypeEnumMap, json['extension_load_type']),
18 | path: json['path'] as String,
19 | readme: json['readme'] as String? ?? "",
20 | );
21 |
22 | Map _$$ExtensionInfoImplToJson(_$ExtensionInfoImpl instance) =>
23 | {
24 | 'package': instance.package,
25 | 'label': instance.label,
26 | 'version_name': instance.versionName,
27 | 'version_code': instance.versionCode,
28 | 'lib_version': instance.libVersion,
29 | 'extension_load_type': _$ExtensionLoaderTypeEnumMap[instance.loadType]!,
30 | 'path': instance.path,
31 | 'readme': instance.readme,
32 | };
33 |
34 | const _$ExtensionLoaderTypeEnumMap = {
35 | ExtensionLoaderType.js: 'js',
36 | ExtensionLoaderType.mygopack: 'mygopack',
37 | ExtensionLoaderType.inner: 'inner',
38 | };
39 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_chapter/manga_chapter.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/manga/manga_enum.dart';
2 | import 'package:freezed_annotation/freezed_annotation.dart';
3 |
4 | part 'manga_chapter.freezed.dart';
5 |
6 | part 'manga_chapter.g.dart';
7 |
8 | @freezed
9 | class MangaChapter with _$MangaChapter {
10 | factory MangaChapter({
11 | // 章节名称
12 | required String label,
13 |
14 | // 章节 Id
15 | required String id,
16 |
17 | // 展示类型
18 | @Default(ChapterShowType.normal)
19 | @JsonKey(name: "show_type")
20 | ChapterShowType showType,
21 |
22 | // 最终会传递给阅读器的参数,这里先预埋
23 | @Default({}) Map parameter,
24 |
25 | // 交给源维护,可以用于透传一些东西
26 | @Default('') String ext,
27 | }) = _MangaChapter;
28 |
29 | factory MangaChapter.fromJson(Map json) =>
30 | _$MangaChapterFromJson(json);
31 | }
32 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_chapter/manga_chapter.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'manga_chapter.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaChapterImpl _$$MangaChapterImplFromJson(Map json) =>
10 | _$MangaChapterImpl(
11 | label: json['label'] as String,
12 | id: json['id'] as String,
13 | showType:
14 | $enumDecodeNullable(_$ChapterShowTypeEnumMap, json['show_type']) ??
15 | ChapterShowType.normal,
16 | parameter: (json['parameter'] as Map?)?.map(
17 | (k, e) => MapEntry(k, e as String),
18 | ) ??
19 | const {},
20 | ext: json['ext'] as String? ?? '',
21 | );
22 |
23 | Map _$$MangaChapterImplToJson(_$MangaChapterImpl instance) =>
24 | {
25 | 'label': instance.label,
26 | 'id': instance.id,
27 | 'show_type': _$ChapterShowTypeEnumMap[instance.showType]!,
28 | 'parameter': instance.parameter,
29 | 'ext': instance.ext,
30 | };
31 |
32 | const _$ChapterShowTypeEnumMap = {
33 | ChapterShowType.normal: 'normal',
34 | ChapterShowType.singlePicture: 'singlePicture',
35 | };
36 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_cover/manga_cover.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:easy_mygo/entity/manga/manga_summary/manga_summary.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'manga_cover.g.dart';
6 | part 'manga_cover.freezed.dart';
7 |
8 | /// 漫画封面,一般在首页或者搜索页展示
9 |
10 | @freezed
11 | class MangaCover with _$MangaCover {
12 |
13 | factory MangaCover({
14 |
15 | required String id,
16 |
17 | // cover 信息
18 | required String label,
19 | required String cover,
20 | required String intro,
21 |
22 | @JsonKey(name: "jump_url")
23 | required String jumpUrl,
24 |
25 | // 必要信息,但是由 Component 填充
26 | @Default("") String source,
27 |
28 | // 额外字段
29 | @Default("") String ext,
30 | }) = _MangaCover;
31 |
32 | factory MangaCover.fromJson(Map json) =>
33 | _$MangaCoverFromJson(json);
34 | }
35 |
36 | extension MangaCoverExt on MangaCover {
37 |
38 | static final _identifyValues = Expando();
39 | String get identify {
40 | return _identifyValues[this] ??= "$id-|-$source";
41 | }
42 |
43 | static final _summaryValues = Expando();
44 | MangaSummary get mangaSummary {
45 | return _summaryValues[this] ??= MangaSummary(source: source, id: id);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_cover/manga_cover.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'manga_cover.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaCoverImpl _$$MangaCoverImplFromJson(Map json) =>
10 | _$MangaCoverImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | cover: json['cover'] as String,
14 | intro: json['intro'] as String,
15 | jumpUrl: json['jump_url'] as String,
16 | source: json['source'] as String? ?? "",
17 | ext: json['ext'] as String? ?? "",
18 | );
19 |
20 | Map _$$MangaCoverImplToJson(_$MangaCoverImpl instance) =>
21 | {
22 | 'id': instance.id,
23 | 'label': instance.label,
24 | 'cover': instance.cover,
25 | 'intro': instance.intro,
26 | 'jump_url': instance.jumpUrl,
27 | 'source': instance.source,
28 | 'ext': instance.ext,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_detailed/manga_detailed.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:easy_mygo/entity/manga/manga_enum.dart';
3 | import 'package:easy_mygo/entity/manga/manga_summary/manga_summary.dart';
4 | import 'package:freezed_annotation/freezed_annotation.dart';
5 |
6 | part 'manga_detailed.g.dart';
7 | part 'manga_detailed.freezed.dart';
8 |
9 | /// 漫画详细信息,一般在漫画详情页展示
10 |
11 | @freezed
12 | class MangaDetailed with _$MangaDetailed {
13 |
14 | factory MangaDetailed({
15 | required String id,
16 |
17 | // cover 信息
18 | required String label,
19 | required String cover,
20 | required String intro,
21 | @JsonKey(name: "jump_url") required String jumpUrl,
22 |
23 | // detailed
24 | @Default(false) @JsonKey(name: "is_detailed_load") bool isDetailedLoad,
25 | @Default("") String genre,
26 | @Default("") String description,
27 | @JsonKey(name: "update_strategy") @Default(MangaUpdateStrategy.always) MangaUpdateStrategy updateStrategy,
28 | @Default(false) bool isUpdate,
29 | @Default(MangaStatus.unknown) MangaStatus status,
30 |
31 | // 额外字段
32 | @Default("") String ext,
33 |
34 | // 必要信息,但是由 Component 填充
35 | @Default("") String source,
36 | }) = _MangaDetailed;
37 |
38 | factory MangaDetailed.fromJson(Map json) =>
39 | _$MangaDetailedFromJson(json);
40 | }
41 |
42 | extension MangaDetailedExt on MangaDetailed {
43 |
44 | static final _identifyValues = Expando();
45 | String get identify {
46 | return _identifyValues[this] ??= "$id-|-$source";
47 | }
48 |
49 | static final _summaryValues = Expando();
50 | MangaSummary get mangaSummary {
51 | return _summaryValues[this] ??= MangaSummary(source: source, id: id);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_detailed/manga_detailed.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'manga_detailed.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaDetailedImpl _$$MangaDetailedImplFromJson(Map json) =>
10 | _$MangaDetailedImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | cover: json['cover'] as String,
14 | intro: json['intro'] as String,
15 | jumpUrl: json['jump_url'] as String,
16 | isDetailedLoad: json['is_detailed_load'] as bool? ?? false,
17 | genre: json['genre'] as String? ?? "",
18 | description: json['description'] as String? ?? "",
19 | updateStrategy: $enumDecodeNullable(
20 | _$MangaUpdateStrategyEnumMap, json['update_strategy']) ??
21 | MangaUpdateStrategy.always,
22 | isUpdate: json['isUpdate'] as bool? ?? false,
23 | status: $enumDecodeNullable(_$MangaStatusEnumMap, json['status']) ??
24 | MangaStatus.unknown,
25 | ext: json['ext'] as String? ?? "",
26 | source: json['source'] as String? ?? "",
27 | );
28 |
29 | Map _$$MangaDetailedImplToJson(_$MangaDetailedImpl instance) =>
30 | {
31 | 'id': instance.id,
32 | 'label': instance.label,
33 | 'cover': instance.cover,
34 | 'intro': instance.intro,
35 | 'jump_url': instance.jumpUrl,
36 | 'is_detailed_load': instance.isDetailedLoad,
37 | 'genre': instance.genre,
38 | 'description': instance.description,
39 | 'update_strategy': _$MangaUpdateStrategyEnumMap[instance.updateStrategy]!,
40 | 'isUpdate': instance.isUpdate,
41 | 'status': _$MangaStatusEnumMap[instance.status]!,
42 | 'ext': instance.ext,
43 | 'source': instance.source,
44 | };
45 |
46 | const _$MangaUpdateStrategyEnumMap = {
47 | MangaUpdateStrategy.always: 'always',
48 | MangaUpdateStrategy.onlyStrict: 'onlyStrict',
49 | MangaUpdateStrategy.never: 'never',
50 | };
51 |
52 | const _$MangaStatusEnumMap = {
53 | MangaStatus.ongoing: 'ongoing',
54 | MangaStatus.complete: 'complete',
55 | MangaStatus.unknown: 'unknown',
56 | };
57 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_enum.dart:
--------------------------------------------------------------------------------
1 |
2 | enum MangaStatus {
3 | ongoing,
4 | complete,
5 | unknown
6 | }
7 |
8 | enum MangaUpdateStrategy {
9 | always,
10 | onlyStrict,
11 | never
12 | }
13 |
14 | // 章节展示的类型
15 | enum ChapterShowType {
16 | normal, // 普通类型,一个 Chapter 分为多个 Picture
17 | singlePicture // 单图片类型,一章只有一张大的 Picture,展示端需要适配(裁切或者只支持上下滑动模式)
18 | }
19 |
20 | // 图片加载类型,后续可能添加裁切功能?
21 | enum PictureLoadType {
22 | normal, // 普通类型,直接加载 MangaPicture 中 url 的图片(网络或本地)
23 | }
--------------------------------------------------------------------------------
/lib/entity/manga/manga_picture/manga_picture.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:easy_mygo/entity/manga/manga_enum.dart';
4 | import 'package:freezed_annotation/freezed_annotation.dart';
5 |
6 | part 'manga_picture.g.dart';
7 | part 'manga_picture.freezed.dart';
8 |
9 | /// 漫画某章节里的一页数据
10 | /// parameter 为额外参数,最终会传给特定 type 的加载器
11 |
12 | @freezed
13 | class MangaPicture with _$MangaPicture {
14 | factory MangaPicture({
15 | // 图片 Url
16 | @Default("") String url,
17 | @Default(PictureLoadType.normal) PictureLoadType type,
18 | @Default({}) Map parameter,
19 |
20 | }) = _MangaPicture;
21 |
22 | factory MangaPicture.fromJson(Map json)
23 | => _$MangaPictureFromJson(json);
24 | }
--------------------------------------------------------------------------------
/lib/entity/manga/manga_picture/manga_picture.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'manga_picture.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaPictureImpl _$$MangaPictureImplFromJson(Map json) =>
10 | _$MangaPictureImpl(
11 | url: json['url'] as String? ?? "",
12 | type: $enumDecodeNullable(_$PictureLoadTypeEnumMap, json['type']) ??
13 | PictureLoadType.normal,
14 | parameter: (json['parameter'] as Map?)?.map(
15 | (k, e) => MapEntry(k, e as String),
16 | ) ??
17 | const {},
18 | );
19 |
20 | Map _$$MangaPictureImplToJson(_$MangaPictureImpl instance) =>
21 | {
22 | 'url': instance.url,
23 | 'type': _$PictureLoadTypeEnumMap[instance.type]!,
24 | 'parameter': instance.parameter,
25 | };
26 |
27 | const _$PictureLoadTypeEnumMap = {
28 | PictureLoadType.normal: 'normal',
29 | };
30 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_summary/manga_summary.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'manga_summary.g.dart';
4 | part 'manga_summary.freezed.dart';
5 |
6 | /// 决定一部漫画的最小单元
7 |
8 | @freezed
9 | class MangaSummary with _$MangaSummary {
10 | factory MangaSummary({
11 | // 必要信息
12 | required String source,
13 | required String id,
14 |
15 | // 额外字段
16 | @Default("") String ext,
17 | }) = _MangaSummary;
18 |
19 | factory MangaSummary.fromJson(Map json) =>
20 | _$MangaSummaryFromJson(json);
21 | }
22 |
--------------------------------------------------------------------------------
/lib/entity/manga/manga_summary/manga_summary.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'manga_summary.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaSummaryImpl _$$MangaSummaryImplFromJson(Map json) =>
10 | _$MangaSummaryImpl(
11 | source: json['source'] as String,
12 | id: json['id'] as String,
13 | ext: json['ext'] as String? ?? "",
14 | );
15 |
16 | Map _$$MangaSummaryImplToJson(_$MangaSummaryImpl instance) =>
17 | {
18 | 'source': instance.source,
19 | 'id': instance.id,
20 | 'ext': instance.ext,
21 | };
22 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_chapter/novel_chapter.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_enum.dart';
2 | import 'package:freezed_annotation/freezed_annotation.dart';
3 |
4 | part 'novel_chapter.freezed.dart';
5 |
6 | part 'novel_chapter.g.dart';
7 |
8 | @freezed
9 | class NovelChapter with _$NovelChapter {
10 | factory NovelChapter({
11 | // 章节标题
12 | required String label,
13 |
14 | // 章节 id
15 | required String id,
16 |
17 | // 根据加载方式不同有不同含义
18 | required String src,
19 |
20 | // 加载方式
21 | @Default(NovelChapterLoadFrom.direct)
22 | @JsonKey(name: "load_from")
23 | NovelChapterLoadFrom loadFrom,
24 |
25 | // 加载类型
26 | @Default(NovelChapterLoadType.html)
27 | @JsonKey(name: "load_type")
28 | NovelChapterLoadType loadType,
29 |
30 | // 最终会传递给阅读器的参数,这里先预埋
31 | @Default({}) Map parameter,
32 | }) = _NovelChapter;
33 |
34 | factory NovelChapter.fromJson(Map json) =>
35 | _$NovelChapterFromJson(json);
36 | }
37 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_chapter/novel_chapter.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'novel_chapter.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelChapterImpl _$$NovelChapterImplFromJson(Map json) =>
10 | _$NovelChapterImpl(
11 | label: json['label'] as String,
12 | id: json['id'] as String,
13 | src: json['src'] as String,
14 | loadFrom: $enumDecodeNullable(
15 | _$NovelChapterLoadFromEnumMap, json['load_from']) ??
16 | NovelChapterLoadFrom.direct,
17 | loadType: $enumDecodeNullable(
18 | _$NovelChapterLoadTypeEnumMap, json['load_type']) ??
19 | NovelChapterLoadType.html,
20 | parameter: (json['parameter'] as Map?)?.map(
21 | (k, e) => MapEntry(k, e as String),
22 | ) ??
23 | const {},
24 | );
25 |
26 | Map _$$NovelChapterImplToJson(_$NovelChapterImpl instance) =>
27 | {
28 | 'label': instance.label,
29 | 'id': instance.id,
30 | 'src': instance.src,
31 | 'load_from': _$NovelChapterLoadFromEnumMap[instance.loadFrom]!,
32 | 'load_type': _$NovelChapterLoadTypeEnumMap[instance.loadType]!,
33 | 'parameter': instance.parameter,
34 | };
35 |
36 | const _$NovelChapterLoadFromEnumMap = {
37 | NovelChapterLoadFrom.url: 'url',
38 | NovelChapterLoadFrom.direct: 'direct',
39 | };
40 |
41 | const _$NovelChapterLoadTypeEnumMap = {
42 | NovelChapterLoadType.epub: 'epub',
43 | NovelChapterLoadType.txt: 'txt',
44 | NovelChapterLoadType.pdf: 'pdf',
45 | NovelChapterLoadType.html: 'html',
46 | };
47 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_cover/novel_cover.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_summary/novel_summary.dart';
2 | import 'package:freezed_annotation/freezed_annotation.dart';
3 |
4 | part 'novel_cover.g.dart';
5 | part 'novel_cover.freezed.dart';
6 |
7 | /// 小说封面,一般在首页或者搜索页展示
8 |
9 | @freezed
10 | class NovelCover with _$NovelCover {
11 | factory NovelCover({
12 | // 必要信息
13 | required String id,
14 |
15 | // cover 信息
16 | required String label,
17 | required String cover,
18 | required String intro,
19 | @JsonKey(name: "jump_url") required String jumpUrl,
20 |
21 | // 必要信息,但是由 Component 填充
22 | @Default("") String source,
23 |
24 | // 额外字段
25 | @Default("") String ext,
26 | }) = _NovelCover;
27 |
28 | factory NovelCover.fromJson(Map json) =>
29 | _$NovelCoverFromJson(json);
30 | }
31 |
32 | extension MangaCoverExt on NovelCover {
33 | static final _identifyValues = Expando();
34 | String get identify {
35 | return _identifyValues[this] ??= "$id-|-$source";
36 | }
37 |
38 | static final _summaryValues = Expando();
39 | NovelSummary get mangaSummary {
40 | return _summaryValues[this] ??= NovelSummary(source: source, id: id);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_cover/novel_cover.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'novel_cover.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelCoverImpl _$$NovelCoverImplFromJson(Map json) =>
10 | _$NovelCoverImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | cover: json['cover'] as String,
14 | intro: json['intro'] as String,
15 | jumpUrl: json['jump_url'] as String,
16 | source: json['source'] as String? ?? "",
17 | ext: json['ext'] as String? ?? "",
18 | );
19 |
20 | Map _$$NovelCoverImplToJson(_$NovelCoverImpl instance) =>
21 | {
22 | 'id': instance.id,
23 | 'label': instance.label,
24 | 'cover': instance.cover,
25 | 'intro': instance.intro,
26 | 'jump_url': instance.jumpUrl,
27 | 'source': instance.source,
28 | 'ext': instance.ext,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_detailed/novel_detailed.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_enum.dart';
2 | import 'package:easy_mygo/entity/novel/novel_summary/novel_summary.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'novel_detailed.g.dart';
6 | part 'novel_detailed.freezed.dart';
7 |
8 | /// 小说详细信息,一般在详情页展示
9 |
10 | @freezed
11 | class NovelDetailed with _$NovelDetailed {
12 | factory NovelDetailed({
13 | // 必要信息
14 | required String source,
15 | required String id,
16 |
17 | // cover 信息
18 | required String label,
19 | required String cover,
20 | required String intro,
21 | @JsonKey(name: "jump_url") required String jumpUrl,
22 |
23 | // detailed
24 | @Default(false) @JsonKey(name: "is_detailed_load") bool isDetailedLoad,
25 | @Default("") String genre,
26 | @Default("") String description,
27 | @JsonKey(name: "update_strategy")
28 | @Default(NovelUpdateStrategy.always)
29 | NovelUpdateStrategy updateStrategy,
30 | @Default(false) bool isUpdate,
31 | @Default(NovelStatus.unknown) NovelStatus status,
32 |
33 | // 额外字段
34 | @Default("") String ext,
35 | }) = _NovelDetailed;
36 |
37 | factory NovelDetailed.fromJson(Map json) =>
38 | _$NovelDetailedFromJson(json);
39 | }
40 |
41 | extension MangaDetailedExt on NovelDetailed {
42 | static final _identifyValues = Expando();
43 | String get identify {
44 | return _identifyValues[this] ??= "$id-|-$source";
45 | }
46 |
47 | static final _summaryValues = Expando();
48 | NovelSummary get mangaSummary {
49 | return _summaryValues[this] ??= NovelSummary(source: source, id: id);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_detailed/novel_detailed.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'novel_detailed.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelDetailedImpl _$$NovelDetailedImplFromJson(Map json) =>
10 | _$NovelDetailedImpl(
11 | source: json['source'] as String,
12 | id: json['id'] as String,
13 | label: json['label'] as String,
14 | cover: json['cover'] as String,
15 | intro: json['intro'] as String,
16 | jumpUrl: json['jump_url'] as String,
17 | isDetailedLoad: json['is_detailed_load'] as bool? ?? false,
18 | genre: json['genre'] as String? ?? "",
19 | description: json['description'] as String? ?? "",
20 | updateStrategy: $enumDecodeNullable(
21 | _$NovelUpdateStrategyEnumMap, json['update_strategy']) ??
22 | NovelUpdateStrategy.always,
23 | isUpdate: json['isUpdate'] as bool? ?? false,
24 | status: $enumDecodeNullable(_$NovelStatusEnumMap, json['status']) ??
25 | NovelStatus.unknown,
26 | ext: json['ext'] as String? ?? "",
27 | );
28 |
29 | Map _$$NovelDetailedImplToJson(_$NovelDetailedImpl instance) =>
30 | {
31 | 'source': instance.source,
32 | 'id': instance.id,
33 | 'label': instance.label,
34 | 'cover': instance.cover,
35 | 'intro': instance.intro,
36 | 'jump_url': instance.jumpUrl,
37 | 'is_detailed_load': instance.isDetailedLoad,
38 | 'genre': instance.genre,
39 | 'description': instance.description,
40 | 'update_strategy': _$NovelUpdateStrategyEnumMap[instance.updateStrategy]!,
41 | 'isUpdate': instance.isUpdate,
42 | 'status': _$NovelStatusEnumMap[instance.status]!,
43 | 'ext': instance.ext,
44 | };
45 |
46 | const _$NovelUpdateStrategyEnumMap = {
47 | NovelUpdateStrategy.always: 'always',
48 | NovelUpdateStrategy.onlyStrict: 'onlyStrict',
49 | NovelUpdateStrategy.never: 'never',
50 | };
51 |
52 | const _$NovelStatusEnumMap = {
53 | NovelStatus.ongoing: 'ongoing',
54 | NovelStatus.complete: 'complete',
55 | NovelStatus.unknown: 'unknown',
56 | };
57 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_enum.dart:
--------------------------------------------------------------------------------
1 | enum NovelStatus {
2 | ongoing,
3 | complete,
4 | unknown,
5 | }
6 |
7 | enum NovelUpdateStrategy {
8 | // 总是检查更新,一般用于连载中
9 | always,
10 | // 只有严格模式(手动触发全体更新)才更新
11 | onlyStrict,
12 | // 永不更新
13 | never
14 | }
15 |
16 | enum NovelVolumeOrganizeType {
17 | // 最终返回的 List 是一个一个章节,一般用于 web 版,
18 | // 一个 Chapter 最终会被缓存成一个 txt,业务需要打包多个 txt 后再输入阅读器
19 | multiChapter,
20 |
21 | // 最终返回的 List 中只有一个 Chapter,
22 | // 一般用于 文库版,比如 epub 等电子书文件格式,Chapter 由文件本身区分
23 | singleChapter,
24 | }
25 |
26 | // 加载方式
27 | // url 文件或网络
28 | // 直出
29 | enum NovelChapterLoadFrom {
30 | url,
31 | direct,
32 | }
33 |
34 | // 加载类型(数据类型)
35 | enum NovelChapterLoadType {
36 | epub, // epub
37 | txt, // txt
38 | pdf, // pdf
39 | html, // 支持一些标签
40 | }
41 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_summary/novel_summary.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'novel_summary.g.dart';
4 | part 'novel_summary.freezed.dart';
5 |
6 | /// 决定一个小说的最小单元
7 |
8 | @freezed
9 | class NovelSummary with _$NovelSummary {
10 | factory NovelSummary({
11 | // 必要信息
12 | required String source,
13 | required String id,
14 |
15 | // 额外字段
16 | @Default("") String ext,
17 | }) = _NovelSummary;
18 |
19 | factory NovelSummary.fromJson(Map json) =>
20 | _$NovelSummaryFromJson(json);
21 | }
22 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_summary/novel_summary.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'novel_summary.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelSummaryImpl _$$NovelSummaryImplFromJson(Map json) =>
10 | _$NovelSummaryImpl(
11 | source: json['source'] as String,
12 | id: json['id'] as String,
13 | ext: json['ext'] as String? ?? "",
14 | );
15 |
16 | Map _$$NovelSummaryImplToJson(_$NovelSummaryImpl instance) =>
17 | {
18 | 'source': instance.source,
19 | 'id': instance.id,
20 | 'ext': instance.ext,
21 | };
22 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_volume/novel_volume.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_enum.dart';
2 | import 'package:freezed_annotation/freezed_annotation.dart';
3 |
4 | part 'novel_volume.freezed.dart';
5 |
6 | part 'novel_volume.g.dart';
7 |
8 | @freezed
9 | class NovelVolume with _$NovelVolume {
10 | factory NovelVolume({
11 | // 卷名称
12 | required String label,
13 |
14 | // 卷 id
15 | required String id,
16 |
17 | // 组织形式
18 | @Default(NovelVolumeOrganizeType.multiChapter)
19 | @JsonKey(name: "organize_type")
20 | organizeType,
21 |
22 | // 最终会传递给阅读器的参数,这里先预埋
23 | @Default({}) Map parameter,
24 |
25 | // 交给源维护,可以用于透传一些东西
26 | @Default('') String ext,
27 | }) = _NovelVolume;
28 |
29 | factory NovelVolume.fromJson(Map json) =>
30 | _$NovelVolumeFromJson(json);
31 | }
32 |
--------------------------------------------------------------------------------
/lib/entity/novel/novel_volume/novel_volume.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'novel_volume.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelVolumeImpl _$$NovelVolumeImplFromJson(Map json) =>
10 | _$NovelVolumeImpl(
11 | label: json['label'] as String,
12 | id: json['id'] as String,
13 | organizeType:
14 | json['organize_type'] ?? NovelVolumeOrganizeType.multiChapter,
15 | parameter: (json['parameter'] as Map?)?.map(
16 | (k, e) => MapEntry(k, e as String),
17 | ) ??
18 | const {},
19 | ext: json['ext'] as String? ?? '',
20 | );
21 |
22 | Map _$$NovelVolumeImplToJson(_$NovelVolumeImpl instance) =>
23 | {
24 | 'label': instance.label,
25 | 'id': instance.id,
26 | 'organize_type': instance.organizeType,
27 | 'parameter': instance.parameter,
28 | 'ext': instance.ext,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/entity/source/source_data/source_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/source/source_info/source_info.dart';
2 | import 'package:easy_mygo/plugin/component/api/component.dart';
3 |
4 |
5 | enum SourceState {
6 | loaded,
7 | error
8 | }
9 |
10 | class SourceData {
11 |
12 | SourceInfo info;
13 | List? components;
14 | SourceState state;
15 | String errorMsg;
16 |
17 | SourceData({
18 | required this.info,
19 | this.components,
20 | this.state = SourceState.loaded,
21 | this.errorMsg = "",
22 | });
23 |
24 | SourceData copyWith({
25 | SourceInfo? info,
26 | List? components,
27 | SourceState? state,
28 | String? errorMsg,
29 | }){
30 | return SourceData(
31 | info: info ?? this.info,
32 | components: components ?? this.components,
33 | state: state ?? this.state,
34 | errorMsg: errorMsg ?? this.errorMsg,
35 | );
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/lib/entity/source/source_info/source_info.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/plugin/source/utils/source_utils_scope.dart';
2 | import 'package:freezed_annotation/freezed_annotation.dart';
3 |
4 | part 'source_info.freezed.dart';
5 |
6 | part 'source_info.g.dart';
7 |
8 | enum SourceType { manga, novel }
9 | enum SourceLoaderType { js, inner }
10 |
11 | @freezed
12 | class SourceInfo with _$SourceInfo {
13 | factory SourceInfo({
14 | // 单个 Extension 里的所有 Source 的 key 需要唯一
15 | required String key,
16 | // 所在 Extension 的包名
17 | @JsonKey(name: 'from_package') required String fromPackage,
18 | required String label,
19 | required SourceType type,
20 | @JsonKey(name: 'version_name') required String versionName,
21 | @JsonKey(name: 'version_code') required int versionCode,
22 | required String path,
23 | @JsonKey(name: 'loader_type') required SourceLoaderType loaderType,
24 | @Default("") String description,
25 | @Default("") String header,
26 | }) = _SourceInfo;
27 |
28 | factory SourceInfo.fromJson(Map json) =>
29 | _$SourceInfoFromJson(json);
30 | }
31 |
32 | extension SourceInfoExt on SourceInfo {
33 | static final _identifyValues = Expando();
34 |
35 | String get identify {
36 | return _identifyValues[this] ??= "$fromPackage-|-$key";
37 | }
38 |
39 | static final _sourceUtilsScopeValues = Expando();
40 | SourceUtilsScope get sourceUtilsScope {
41 | return _sourceUtilsScopeValues[this] ??= SourceUtilsScope(this);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lib/entity/source/source_info/source_info.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'source_info.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$SourceInfoImpl _$$SourceInfoImplFromJson(Map json) =>
10 | _$SourceInfoImpl(
11 | key: json['key'] as String,
12 | fromPackage: json['from_package'] as String,
13 | label: json['label'] as String,
14 | type: $enumDecode(_$SourceTypeEnumMap, json['type']),
15 | versionName: json['version_name'] as String,
16 | versionCode: (json['version_code'] as num).toInt(),
17 | path: json['path'] as String,
18 | loaderType: $enumDecode(_$SourceLoaderTypeEnumMap, json['loader_type']),
19 | description: json['description'] as String? ?? "",
20 | header: json['header'] as String? ?? "",
21 | );
22 |
23 | Map _$$SourceInfoImplToJson(_$SourceInfoImpl instance) =>
24 | {
25 | 'key': instance.key,
26 | 'from_package': instance.fromPackage,
27 | 'label': instance.label,
28 | 'type': _$SourceTypeEnumMap[instance.type]!,
29 | 'version_name': instance.versionName,
30 | 'version_code': instance.versionCode,
31 | 'path': instance.path,
32 | 'loader_type': _$SourceLoaderTypeEnumMap[instance.loaderType]!,
33 | 'description': instance.description,
34 | 'header': instance.header,
35 | };
36 |
37 | const _$SourceTypeEnumMap = {
38 | SourceType.manga: 'manga',
39 | SourceType.novel: 'novel',
40 | };
41 |
42 | const _$SourceLoaderTypeEnumMap = {
43 | SourceLoaderType.js: 'js',
44 | SourceLoaderType.inner: 'inner',
45 | };
46 |
--------------------------------------------------------------------------------
/lib/hive_registrar.g.dart:
--------------------------------------------------------------------------------
1 | import 'package:hive_ce/hive.dart';
2 |
3 | extension HiveRegistrar on HiveInterface {
4 | void registerAdapters() {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/lib/l10n/arb/intl_zh_CN.arb:
--------------------------------------------------------------------------------
1 | {
2 | "@@locale": "zh_CN",
3 | "app_name": "纯纯 Mygo",
4 | "@app_name": {
5 | "description": "软件名称"
6 | },
7 | "home": "主页",
8 | "more": "更多",
9 | "history": "历史",
10 | "library": "书架",
11 | "pull_to_refresh": "下拉刷新",
12 | "release_ready": "释放刷新",
13 | "loading": "加载中...",
14 | "success": "成功",
15 | "last_update_time": "最后更新时间"
16 | }
--------------------------------------------------------------------------------
/lib/l10n/intl/messages_all.dart:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
2 | // This is a library that looks up messages for specific locales by
3 | // delegating to the appropriate library.
4 |
5 | // Ignore issues from commonly used lints in this file.
6 | // ignore_for_file:implementation_imports, file_names, unnecessary_new
7 | // ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
8 | // ignore_for_file:argument_type_not_assignable, invalid_assignment
9 | // ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
10 | // ignore_for_file:comment_references
11 |
12 | import 'dart:async';
13 |
14 | import 'package:flutter/foundation.dart';
15 | import 'package:intl/intl.dart';
16 | import 'package:intl/message_lookup_by_library.dart';
17 | import 'package:intl/src/intl_helpers.dart';
18 |
19 | import 'messages_zh_CN.dart' as messages_zh_cn;
20 |
21 | typedef Future LibraryLoader();
22 | Map _deferredLibraries = {
23 | 'zh_CN': () => new SynchronousFuture(null),
24 | };
25 |
26 | MessageLookupByLibrary? _findExact(String localeName) {
27 | switch (localeName) {
28 | case 'zh_CN':
29 | return messages_zh_cn.messages;
30 | default:
31 | return null;
32 | }
33 | }
34 |
35 | /// User programs should call this before using [localeName] for messages.
36 | Future initializeMessages(String localeName) {
37 | var availableLocale = Intl.verifiedLocale(
38 | localeName, (locale) => _deferredLibraries[locale] != null,
39 | onFailure: (_) => null);
40 | if (availableLocale == null) {
41 | return new SynchronousFuture(false);
42 | }
43 | var lib = _deferredLibraries[availableLocale];
44 | lib == null ? new SynchronousFuture(false) : lib();
45 | initializeInternalMessageLookup(() => new CompositeMessageLookup());
46 | messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
47 | return new SynchronousFuture(true);
48 | }
49 |
50 | bool _messagesExistFor(String locale) {
51 | try {
52 | return _findExact(locale) != null;
53 | } catch (e) {
54 | return false;
55 | }
56 | }
57 |
58 | MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) {
59 | var actualLocale =
60 | Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null);
61 | if (actualLocale == null) return null;
62 | return _findExact(actualLocale);
63 | }
64 |
--------------------------------------------------------------------------------
/lib/l10n/intl/messages_zh_CN.dart:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
2 | // This is a library that provides messages for a zh_CN locale. All the
3 | // messages from the main program should be duplicated here with the same
4 | // function name.
5 |
6 | // Ignore issues from commonly used lints in this file.
7 | // ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
8 | // ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
9 | // ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
10 | // ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
11 | // ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
12 |
13 | import 'package:intl/intl.dart';
14 | import 'package:intl/message_lookup_by_library.dart';
15 |
16 | final messages = new MessageLookup();
17 |
18 | typedef String MessageIfAbsent(String messageStr, List args);
19 |
20 | class MessageLookup extends MessageLookupByLibrary {
21 | String get localeName => 'zh_CN';
22 |
23 | final messages = _notInlinedMessages(_notInlinedMessages);
24 | static Map _notInlinedMessages(_) => {
25 | "app_name": MessageLookupByLibrary.simpleMessage("纯纯 Mygo"),
26 | "history": MessageLookupByLibrary.simpleMessage("历史"),
27 | "home": MessageLookupByLibrary.simpleMessage("主页"),
28 | "last_update_time": MessageLookupByLibrary.simpleMessage("最后更新时间"),
29 | "library": MessageLookupByLibrary.simpleMessage("书架"),
30 | "loading": MessageLookupByLibrary.simpleMessage("加载中..."),
31 | "more": MessageLookupByLibrary.simpleMessage("更多"),
32 | "pull_to_refresh": MessageLookupByLibrary.simpleMessage("下拉刷新"),
33 | "release_ready": MessageLookupByLibrary.simpleMessage("释放刷新"),
34 | "success": MessageLookupByLibrary.simpleMessage("成功")
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/component.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:easy_mygo/entity/source/source_info/source_info.dart';
4 |
5 |
6 |
7 |
8 | class Component {
9 |
10 | final SourceInfo sourceInfo;
11 | Component(this.sourceInfo);
12 | }
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/detailed/manga_detailed_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/manga/manga_summary/manga_summary.dart';
2 | import 'package:easy_mygo/plugin/component/api/component.dart';
3 | import 'package:easy_mygo/plugin/component/api/manga/detailed/resp/detailed_resp.dart';
4 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
5 |
6 | abstract class MangaDetailedComponent extends Component {
7 | MangaDetailedComponent(super.sourceInfo);
8 |
9 | Future getMangaDetailed(MangaSummary summary);
10 |
11 | Future performGetMangaDetailed(
12 | MangaSummary summary) async {
13 | try {
14 | return await getMangaDetailed(summary);
15 | } catch (e) {
16 | if (e is ComponentPayload) {
17 | return MangaDetailedResp(payload: e);
18 | } else {
19 | return MangaDetailedResp(
20 | payload: ComponentPayload(
21 | code: ComponentPayload.codeCallError,
22 | msg: e.toString(),
23 | raw: e));
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/detailed/resp/detailed_resp.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:easy_mygo/entity/manga/manga_chapter/manga_chapter.dart';
4 | import 'package:easy_mygo/entity/manga/manga_detailed/manga_detailed.dart';
5 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
6 | import 'package:freezed_annotation/freezed_annotation.dart';
7 |
8 | part 'detailed_resp.freezed.dart';
9 | part 'detailed_resp.g.dart';
10 |
11 | @freezed
12 | class MangaDetailedResp with _$MangaDetailedResp {
13 |
14 | factory MangaDetailedResp({
15 | @Default(null) MangaDetailed? detailed,
16 | @Default(null) List? chapters,
17 | required ComponentPayload payload,
18 | }) = _MangaDetailedResp;
19 |
20 | factory MangaDetailedResp.fromJson(Map json)
21 | => _$MangaDetailedRespFromJson(json);
22 | }
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/detailed/resp/detailed_resp.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'detailed_resp.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaDetailedRespImpl _$$MangaDetailedRespImplFromJson(
10 | Map json) =>
11 | _$MangaDetailedRespImpl(
12 | detailed: json['detailed'] == null
13 | ? null
14 | : MangaDetailed.fromJson(json['detailed'] as Map),
15 | chapters: (json['chapters'] as List?)
16 | ?.map((e) => MangaChapter.fromJson(e as Map))
17 | .toList() ??
18 | null,
19 | payload:
20 | ComponentPayload.fromJson(json['payload'] as Map),
21 | );
22 |
23 | Map _$$MangaDetailedRespImplToJson(
24 | _$MangaDetailedRespImpl instance) =>
25 | {
26 | 'detailed': instance.detailed,
27 | 'chapters': instance.chapters,
28 | 'payload': instance.payload,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/home/manga_home_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/book/home_tab/book_home_tab.dart';
2 | import 'package:easy_mygo/plugin/component/api/component.dart';
3 | import 'package:easy_mygo/plugin/component/api/manga/home/page/home_page.dart';
4 | import 'package:easy_mygo/plugin/component/api/manga/home/resp/home_resp.dart';
5 |
6 | abstract class MangaHomeComponent extends Component {
7 | MangaHomeComponent(super.sourceInfo);
8 |
9 | /// 获取一级 tab 列表
10 | Future getHomeTab();
11 |
12 | /// 获取二级 tab 列表
13 | Future getSecondTab(BookHomeTab tab);
14 |
15 | /// 获取一级 tab 对应的页面(如果没有二级 tab 的话)
16 | Future getPageWithHomeTab(BookHomeTab tab);
17 |
18 | /// 获取二级 tab 对应的页面
19 | Future getPageWithSecondTab(
20 | BookHomeTab homeTab, BookSecondTab secondTab);
21 |
22 | /// 获取页面中某一页的漫画数据
23 | Future loadPageData(MangaHomePage page, String key);
24 | }
25 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/home/page/home_page.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'home_page.freezed.dart';
6 | part 'home_page.g.dart';
7 |
8 | @freezed
9 | class MangaHomePage with _$MangaHomePage {
10 | factory MangaHomePage({
11 | required String id,
12 | required String label,
13 | // 是否有 封面
14 | @JsonKey(name: "has_cover") @Default(true) bool hasCover,
15 |
16 | // 初始页面 key
17 | @JsonKey(name: "init_key") @Default('') String initKey,
18 |
19 | // 可以让源透传一些信息
20 | @Default('') String ext,
21 | }) = _MangaHomePage;
22 |
23 | factory MangaHomePage.fromJson(Map json) =>
24 | _$MangaHomePageFromJson(json);
25 | }
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/home/page/home_page.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_page.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaHomePageImpl _$$MangaHomePageImplFromJson(Map json) =>
10 | _$MangaHomePageImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | hasCover: json['has_cover'] as bool? ?? true,
14 | initKey: json['init_key'] as String? ?? '',
15 | ext: json['ext'] as String? ?? '',
16 | );
17 |
18 | Map _$$MangaHomePageImplToJson(_$MangaHomePageImpl instance) =>
19 | {
20 | 'id': instance.id,
21 | 'label': instance.label,
22 | 'has_cover': instance.hasCover,
23 | 'init_key': instance.initKey,
24 | 'ext': instance.ext,
25 | };
26 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/home/resp/home_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/book/home_tab/book_home_tab.dart';
2 | import 'package:easy_mygo/entity/manga/manga_cover/manga_cover.dart';
3 | import 'package:easy_mygo/plugin/component/api/manga/home/page/home_page.dart';
4 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
5 | import 'package:freezed_annotation/freezed_annotation.dart';
6 |
7 | part 'home_resp.g.dart';
8 | part 'home_resp.freezed.dart';
9 |
10 | /// 获取一级 tab
11 | @freezed
12 | class MangaGetHomeTabResp with _$MangaGetHomeTabResp {
13 | factory MangaGetHomeTabResp({
14 | @JsonKey(name: "tab_list") @Default(null) List? tabList,
15 | required ComponentPayload payload,
16 | }) = _MangaGetHomeTabResp;
17 |
18 | factory MangaGetHomeTabResp.fromJson(Map json) =>
19 | _$MangaGetHomeTabRespFromJson(json);
20 | }
21 |
22 | /// 获取二级 tab
23 | @freezed
24 | class MangaGetSecondTabResp with _$MangaGetSecondTabResp {
25 | factory MangaGetSecondTabResp({
26 | @JsonKey(name: "tab_list") @Default(null) List? tabList,
27 | required ComponentPayload payload,
28 | }) = _MangaGetSecondTabResp;
29 |
30 | factory MangaGetSecondTabResp.fromJson(Map json) =>
31 | _$MangaGetSecondTabRespFromJson(json);
32 | }
33 |
34 | /// 获取 tab 对应的 page
35 | @freezed
36 | class MangaGetHomePageResp with _$MangaGetHomePageResp {
37 | factory MangaGetHomePageResp({
38 | @Default(null) MangaHomePage? page,
39 | required ComponentPayload payload,
40 | }) = _MangaGetHomePageResp;
41 |
42 | factory MangaGetHomePageResp.fromJson(Map json) =>
43 | _$MangaGetHomePageRespFromJson(json);
44 | }
45 |
46 | /// 加载 page 里某一页数据
47 | @freezed
48 | class MangaGetHomeCoverResp with _$MangaGetHomeCoverResp {
49 | factory MangaGetHomeCoverResp({
50 | @Default(null) List? data,
51 |
52 | // 下一页的 key,如果为空则代表最后一页
53 | @JsonKey(name: "next_key") @Default(null) String? nextKey,
54 | required ComponentPayload payload,
55 | }) = _MangaGetHomeCoverResp;
56 |
57 | factory MangaGetHomeCoverResp.fromJson(Map json) =>
58 | _$MangaGetHomeCoverRespFromJson(json);
59 | }
60 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/home/tab/home_tab.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'home_tab.freezed.dart';
4 | part 'home_tab.g.dart';
5 |
6 |
7 | /// 一级 tab
8 | @freezed
9 | class MangaHomeTab with _$MangaHomeTab {
10 | factory MangaHomeTab({
11 | required String id,
12 | required String label,
13 | // 是否有 二级 tab
14 | @JsonKey(name: "has_second_tab") required bool hasSecondTab,
15 |
16 | // 可以让源透传一些信息
17 | @Default('') String ext,
18 | }) = _MangaHomeTab;
19 |
20 | factory MangaHomeTab.fromJson(Map json) =>
21 | _$MangaHomeTabFromJson(json);
22 | }
23 |
24 | /// 二级 tab
25 | @freezed
26 | class MangaHomeSecondTab with _$MangaHomeSecondTab {
27 | factory MangaHomeSecondTab({
28 | required String id,
29 | required String label,
30 | @Default('') String ext,
31 | }) = _MangaHomeSecondTab;
32 |
33 | factory MangaHomeSecondTab.fromJson(Map json) =>
34 | _$MangaHomeSecondTabFromJson(json);
35 | }
36 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/home/tab/home_tab.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_tab.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaHomeTabImpl _$$MangaHomeTabImplFromJson(Map json) =>
10 | _$MangaHomeTabImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | hasSecondTab: json['has_second_tab'] as bool,
14 | ext: json['ext'] as String? ?? '',
15 | );
16 |
17 | Map _$$MangaHomeTabImplToJson(_$MangaHomeTabImpl instance) =>
18 | {
19 | 'id': instance.id,
20 | 'label': instance.label,
21 | 'has_second_tab': instance.hasSecondTab,
22 | 'ext': instance.ext,
23 | };
24 |
25 | _$MangaHomeSecondTabImpl _$$MangaHomeSecondTabImplFromJson(
26 | Map json) =>
27 | _$MangaHomeSecondTabImpl(
28 | id: json['id'] as String,
29 | label: json['label'] as String,
30 | ext: json['ext'] as String? ?? '',
31 | );
32 |
33 | Map _$$MangaHomeSecondTabImplToJson(
34 | _$MangaHomeSecondTabImpl instance) =>
35 | {
36 | 'id': instance.id,
37 | 'label': instance.label,
38 | 'ext': instance.ext,
39 | };
40 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/read/manga_read_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/manga/manga_chapter/manga_chapter.dart';
2 | import 'package:easy_mygo/entity/manga/manga_detailed/manga_detailed.dart';
3 | import 'package:easy_mygo/plugin/component/api/component.dart';
4 | import 'package:easy_mygo/plugin/component/api/manga/read/resp/read_resp.dart';
5 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
6 |
7 | abstract class MangaReadComponent extends Component {
8 | MangaReadComponent(super.sourceInfo);
9 |
10 | /// throws: ComponentPayload
11 | Future getMangaPicture(
12 | MangaDetailed detailed, MangaChapter chapter);
13 |
14 | Future performGetMangaPicture(
15 | MangaDetailed detailed, MangaChapter chapter) async {
16 | try {
17 | return await getMangaPicture(detailed, chapter);
18 | } catch (e) {
19 | if (e is ComponentPayload) {
20 | return MangaReadResp(payload: e);
21 | } else {
22 | return MangaReadResp(
23 | payload: ComponentPayload(
24 | code: ComponentPayload.codeCallError,
25 | msg: e.toString(),
26 | raw: e));
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/read/resp/read_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/manga/manga_picture/manga_picture.dart';
2 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'read_resp.freezed.dart';
6 | part 'read_resp.g.dart';
7 |
8 | @freezed
9 | class MangaReadResp with _$MangaReadResp {
10 | factory MangaReadResp({
11 | @Default(null) List? pictures,
12 | required ComponentPayload payload,
13 | }) = _MangaReadResp;
14 |
15 | factory MangaReadResp.fromJson(Map json) =>
16 | _$MangaReadRespFromJson(json);
17 | }
18 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/read/resp/read_resp.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'read_resp.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaReadRespImpl _$$MangaReadRespImplFromJson(Map json) =>
10 | _$MangaReadRespImpl(
11 | pictures: (json['pictures'] as List?)
12 | ?.map((e) => MangaPicture.fromJson(e as Map))
13 | .toList() ??
14 | null,
15 | payload:
16 | ComponentPayload.fromJson(json['payload'] as Map),
17 | );
18 |
19 | Map _$$MangaReadRespImplToJson(_$MangaReadRespImpl instance) =>
20 | {
21 | 'pictures': instance.pictures,
22 | 'payload': instance.payload,
23 | };
24 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/search/manga_search_component.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:easy_mygo/plugin/component/api/component.dart';
4 | import 'package:easy_mygo/plugin/component/api/manga/search/resp/search_resp.dart';
5 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
6 |
7 | abstract class MangaSearchComponent extends Component {
8 |
9 | MangaSearchComponent(super.sourceInfo);
10 |
11 | Future getInitKey(String key);
12 |
13 | Future search(String key, String keyword);
14 |
15 | Future performSearch(String key, String keyword) async {
16 | try {
17 | return await search(key, keyword);
18 | } catch (e) {
19 | if (e is ComponentPayload) {
20 | return MangaSearchResp(payload: e);
21 | } else {
22 | return MangaSearchResp(
23 | payload: ComponentPayload(
24 | code: ComponentPayload.codeCallError,
25 | msg: e.toString(),
26 | raw: e));
27 | }
28 | }
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/search/resp/search_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/manga/manga_cover/manga_cover.dart';
2 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'search_resp.g.dart';
6 | part 'search_resp.freezed.dart';
7 |
8 | @freezed
9 | class MangaSearchResp with _$MangaSearchResp {
10 |
11 | factory MangaSearchResp({
12 | // 当页结果
13 | @Default(null) List? data,
14 |
15 | // 下一页的 key,为 null 则代表没有下一页
16 | @Default(null) @JsonKey(name: "next_key") String? nextKey,
17 | required ComponentPayload payload,
18 | }) = _MangaSearchResp;
19 |
20 | factory MangaSearchResp.fromJson(Map json) =>
21 | _$MangaSearchRespFromJson(json);
22 | }
23 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/manga/search/resp/search_resp.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'search_resp.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MangaSearchRespImpl _$$MangaSearchRespImplFromJson(
10 | Map json) =>
11 | _$MangaSearchRespImpl(
12 | data: (json['data'] as List?)
13 | ?.map((e) => MangaCover.fromJson(e as Map))
14 | .toList() ??
15 | null,
16 | nextKey: json['next_key'] as String? ?? null,
17 | payload:
18 | ComponentPayload.fromJson(json['payload'] as Map),
19 | );
20 |
21 | Map _$$MangaSearchRespImplToJson(
22 | _$MangaSearchRespImpl instance) =>
23 | {
24 | 'data': instance.data,
25 | 'next_key': instance.nextKey,
26 | 'payload': instance.payload,
27 | };
28 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/detailed/novel_detailed_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_summary/novel_summary.dart';
2 | import 'package:easy_mygo/plugin/component/api/component.dart';
3 | import 'package:easy_mygo/plugin/component/api/novel/detailed/resp/detailed_resp.dart';
4 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
5 |
6 | abstract class NovelDetailedComponent extends Component {
7 | NovelDetailedComponent(super.sourceInfo);
8 |
9 | Future getNovelDetailed(NovelSummary summary);
10 |
11 | Future performGetNovelDetailed(
12 | NovelSummary summary) async {
13 | try {
14 | return await getNovelDetailed(summary);
15 | } catch (e) {
16 | if (e is ComponentPayload) {
17 | return NovelDetailedResp(payload: e);
18 | } else {
19 | return NovelDetailedResp(
20 | payload: ComponentPayload(
21 | code: ComponentPayload.codeCallError,
22 | msg: e.toString(),
23 | raw: e));
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/detailed/resp/detailed_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_detailed/novel_detailed.dart';
2 | import 'package:easy_mygo/entity/novel/novel_volume/novel_volume.dart';
3 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
4 | import 'package:freezed_annotation/freezed_annotation.dart';
5 |
6 | part 'detailed_resp.freezed.dart';
7 | part 'detailed_resp.g.dart';
8 |
9 | @freezed
10 | class NovelDetailedResp with _$NovelDetailedResp {
11 | factory NovelDetailedResp({
12 | @Default(null) NovelDetailed? detailed,
13 | @Default(null) List? volumes,
14 | required ComponentPayload payload,
15 | }) = _NovelDetailedResp;
16 |
17 | factory NovelDetailedResp.fromJson(Map json) =>
18 | _$NovelDetailedRespFromJson(json);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/detailed/resp/detailed_resp.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'detailed_resp.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelDetailedRespImpl _$$NovelDetailedRespImplFromJson(
10 | Map json) =>
11 | _$NovelDetailedRespImpl(
12 | detailed: json['detailed'] == null
13 | ? null
14 | : NovelDetailed.fromJson(json['detailed'] as Map),
15 | volumes: (json['volumes'] as List?)
16 | ?.map((e) => NovelVolume.fromJson(e as Map))
17 | .toList() ??
18 | null,
19 | payload:
20 | ComponentPayload.fromJson(json['payload'] as Map),
21 | );
22 |
23 | Map _$$NovelDetailedRespImplToJson(
24 | _$NovelDetailedRespImpl instance) =>
25 | {
26 | 'detailed': instance.detailed,
27 | 'volumes': instance.volumes,
28 | 'payload': instance.payload,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/home/novel_home_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/book/home_tab/book_home_tab.dart';
2 | import 'package:easy_mygo/plugin/component/api/component.dart';
3 | import 'package:easy_mygo/plugin/component/api/novel/home/page/home_page.dart';
4 | import 'package:easy_mygo/plugin/component/api/novel/home/resp/home_resp.dart';
5 |
6 | abstract class NovelHomeComponent extends Component {
7 | NovelHomeComponent(super.sourceInfo);
8 |
9 | /// 获取一级 tab 列表
10 | Future getHomeTab();
11 |
12 | /// 获取二级 tab 列表
13 | Future getSecondTab(BookHomeTab tab);
14 |
15 | /// 获取一级 tab 对应的页面(如果没有二级 tab 的话)
16 | Future getPageWithHomeTab(BookHomeTab tab);
17 |
18 | /// 获取二级 tab 对应的页面
19 | Future getPageWithSecondTab(
20 | BookHomeTab homeTab, BookSecondTab secondTab);
21 |
22 | /// 获取页面中某一页的漫画数据
23 | Future loadPageData(NovelHomePage page, String key);
24 | }
25 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/home/page/home_page.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'home_page.freezed.dart';
6 | part 'home_page.g.dart';
7 |
8 | @freezed
9 | class NovelHomePage with _$NovelHomePage {
10 | factory NovelHomePage({
11 | required String id,
12 | required String label,
13 | // 是否有 封面
14 | @JsonKey(name: "has_cover") @Default(true) bool hasCover,
15 |
16 | // 初始页面 key
17 | @JsonKey(name: "init_key") @Default('') String initKey,
18 |
19 | // 可以让源透传一些信息
20 | @Default('') String ext,
21 | }) = _NovelHomePage;
22 |
23 | factory NovelHomePage.fromJson(Map json) =>
24 | _$NovelHomePageFromJson(json);
25 |
26 | }
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/home/page/home_page.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_page.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelHomePageImpl _$$NovelHomePageImplFromJson(Map json) =>
10 | _$NovelHomePageImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | hasCover: json['has_cover'] as bool? ?? true,
14 | initKey: json['init_key'] as String? ?? '',
15 | ext: json['ext'] as String? ?? '',
16 | );
17 |
18 | Map _$$NovelHomePageImplToJson(_$NovelHomePageImpl instance) =>
19 | {
20 | 'id': instance.id,
21 | 'label': instance.label,
22 | 'has_cover': instance.hasCover,
23 | 'init_key': instance.initKey,
24 | 'ext': instance.ext,
25 | };
26 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/home/resp/home_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/book/home_tab/book_home_tab.dart';
2 | import 'package:easy_mygo/entity/novel/novel_cover/novel_cover.dart';
3 | import 'package:easy_mygo/plugin/component/api/novel/home/page/home_page.dart';
4 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
5 | import 'package:freezed_annotation/freezed_annotation.dart';
6 |
7 | part 'home_resp.g.dart';
8 | part 'home_resp.freezed.dart';
9 |
10 | /// 获取一级 tab
11 | @freezed
12 | class NovelGetHomeTabResp with _$NovelGetHomeTabResp {
13 | factory NovelGetHomeTabResp({
14 | @JsonKey(name: "tab_list") @Default(null) List? tabList,
15 | required ComponentPayload payload,
16 | }) = _NovelGetHomeTabResp;
17 |
18 | factory NovelGetHomeTabResp.fromJson(Map json) =>
19 | _$NovelGetHomeTabRespFromJson(json);
20 | }
21 |
22 | /// 获取二级 tab
23 | @freezed
24 | class NovelGetSecondTabResp with _$NovelGetSecondTabResp {
25 | factory NovelGetSecondTabResp({
26 | @JsonKey(name: "tab_list") @Default(null) List? tabList,
27 | required ComponentPayload payload,
28 | }) = _NovelGetSecondTabResp;
29 |
30 | factory NovelGetSecondTabResp.fromJson(Map json) =>
31 | _$NovelGetSecondTabRespFromJson(json);
32 | }
33 |
34 | /// 获取 tab 对应的 page
35 | @freezed
36 | class NovelGetHomePageResp with _$NovelGetHomePageResp {
37 | factory NovelGetHomePageResp({
38 | @JsonKey(name: 'page') @Default(null) NovelHomePage? page,
39 | required ComponentPayload payload,
40 | }) = _NovelGetHomePageResp;
41 |
42 | factory NovelGetHomePageResp.fromJson(Map json) =>
43 | _$NovelGetHomePageRespFromJson(json);
44 | }
45 |
46 | /// 加载 page 里某一页数据
47 | @freezed
48 | class NovelGetHomeCoverResp with _$NovelGetHomeCoverResp {
49 | factory NovelGetHomeCoverResp({
50 | @Default(null) List? data,
51 |
52 | // 下一页的 key,如果为空则代表最后一页
53 | @JsonKey(name: "next_key") @Default(null) String? nextKey,
54 | required ComponentPayload payload,
55 | }) = _NovelGetHomeCoverResp;
56 |
57 | factory NovelGetHomeCoverResp.fromJson(Map json) =>
58 | _$NovelGetHomeCoverRespFromJson(json);
59 | }
60 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/home/tab/home_tab.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'home_tab.freezed.dart';
4 | part 'home_tab.g.dart';
5 |
6 |
7 | /// 一级 tab
8 | @freezed
9 | class NovelHomeTab with _$NovelHomeTab {
10 | factory NovelHomeTab({
11 | required String id,
12 | required String label,
13 | // 是否有 二级 tab
14 | @JsonKey(name: "has_second_tab") required bool hasSecondTab,
15 |
16 | // 可以让源透传一些信息
17 | @Default('') String ext,
18 | }) = _NovelHomeTab;
19 |
20 | factory NovelHomeTab.fromJson(Map json) =>
21 | _$NovelHomeTabFromJson(json);
22 | }
23 |
24 | /// 二级 tab
25 | @freezed
26 | class NovelHomeSecondTab with _$NovelHomeSecondTab {
27 | factory NovelHomeSecondTab({
28 | required String id,
29 | required String label,
30 | @Default('') String ext,
31 | }) = _NovelHomeSecondTab;
32 |
33 | factory NovelHomeSecondTab.fromJson(Map json) =>
34 | _$NovelHomeSecondTabFromJson(json);
35 | }
36 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/home/tab/home_tab.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_tab.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelHomeTabImpl _$$NovelHomeTabImplFromJson(Map json) =>
10 | _$NovelHomeTabImpl(
11 | id: json['id'] as String,
12 | label: json['label'] as String,
13 | hasSecondTab: json['has_second_tab'] as bool,
14 | ext: json['ext'] as String? ?? '',
15 | );
16 |
17 | Map _$$NovelHomeTabImplToJson(_$NovelHomeTabImpl instance) =>
18 | {
19 | 'id': instance.id,
20 | 'label': instance.label,
21 | 'has_second_tab': instance.hasSecondTab,
22 | 'ext': instance.ext,
23 | };
24 |
25 | _$NovelHomeSecondTabImpl _$$NovelHomeSecondTabImplFromJson(
26 | Map json) =>
27 | _$NovelHomeSecondTabImpl(
28 | id: json['id'] as String,
29 | label: json['label'] as String,
30 | ext: json['ext'] as String? ?? '',
31 | );
32 |
33 | Map _$$NovelHomeSecondTabImplToJson(
34 | _$NovelHomeSecondTabImpl instance) =>
35 | {
36 | 'id': instance.id,
37 | 'label': instance.label,
38 | 'ext': instance.ext,
39 | };
40 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/read/novel_read_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_detailed/novel_detailed.dart';
2 | import 'package:easy_mygo/entity/novel/novel_volume/novel_volume.dart';
3 | import 'package:easy_mygo/plugin/component/api/component.dart';
4 | import 'package:easy_mygo/plugin/component/api/novel/read/resp/read_resp.dart';
5 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
6 |
7 | abstract class NovelReadComponent extends Component {
8 | NovelReadComponent(super.sourceInfo);
9 |
10 | /// throws: ComponentPayload
11 | Future getNovelChapter(
12 | NovelDetailed detailed, NovelVolume volume);
13 |
14 | Future performGetNovelChapter(
15 | NovelDetailed detailed, NovelVolume volume) async {
16 | try {
17 | return await getNovelChapter(detailed, volume);
18 | } catch (e) {
19 | if (e is ComponentPayload) {
20 | return NovelReadResp(payload: e);
21 | } else {
22 | return NovelReadResp(
23 | payload: ComponentPayload(
24 | code: ComponentPayload.codeCallError,
25 | msg: e.toString(),
26 | raw: e));
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/read/resp/read_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_chapter/novel_chapter.dart';
2 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'read_resp.freezed.dart';
6 | part 'read_resp.g.dart';
7 |
8 | @freezed
9 | class NovelReadResp with _$NovelReadResp {
10 | factory NovelReadResp({
11 | @Default(null) List? chapters,
12 | required ComponentPayload payload,
13 | }) = _NovelReadResp;
14 |
15 | factory NovelReadResp.fromJson(Map json) =>
16 | _$NovelReadRespFromJson(json);
17 | }
18 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/read/resp/read_resp.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'read_resp.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelReadRespImpl _$$NovelReadRespImplFromJson(Map json) =>
10 | _$NovelReadRespImpl(
11 | chapters: (json['chapters'] as List?)
12 | ?.map((e) => NovelChapter.fromJson(e as Map))
13 | .toList() ??
14 | null,
15 | payload:
16 | ComponentPayload.fromJson(json['payload'] as Map),
17 | );
18 |
19 | Map _$$NovelReadRespImplToJson(_$NovelReadRespImpl instance) =>
20 | {
21 | 'chapters': instance.chapters,
22 | 'payload': instance.payload,
23 | };
24 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/search/novel_search_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/plugin/component/api/component.dart';
2 | import 'package:easy_mygo/plugin/component/api/novel/search/resp/search_resp.dart';
3 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
4 |
5 | abstract class NovelSearchComponent extends Component {
6 | NovelSearchComponent(super.sourceInfo);
7 |
8 | Future getInitKey(String key);
9 |
10 | Future search(String key, String keyword);
11 |
12 | Future performSearch(String key, String keyword) async {
13 | try {
14 | return await search(key, keyword);
15 | } catch (e) {
16 | if (e is ComponentPayload) {
17 | return NovelSearchResp(payload: e);
18 | } else {
19 | return NovelSearchResp(
20 | payload: ComponentPayload(
21 | code: ComponentPayload.codeCallError,
22 | msg: e.toString(),
23 | raw: e));
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/search/resp/search_resp.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/novel/novel_cover/novel_cover.dart';
2 | import 'package:easy_mygo/plugin/component/api/payload/component_payload.dart';
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'search_resp.g.dart';
6 | part 'search_resp.freezed.dart';
7 |
8 | @freezed
9 | class NovelSearchResp with _$NovelSearchResp {
10 | factory NovelSearchResp({
11 | // 当页结果
12 | @Default(null) List? data,
13 |
14 | // 下一页的 key,为 null 则代表没有下一页
15 | @Default(null) @JsonKey(name: "next_key") String? nextKey,
16 | required ComponentPayload payload,
17 | }) = _NovelSearchResp;
18 |
19 | factory NovelSearchResp.fromJson(Map json) =>
20 | _$NovelSearchRespFromJson(json);
21 | }
22 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/novel/search/resp/search_resp.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'search_resp.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$NovelSearchRespImpl _$$NovelSearchRespImplFromJson(
10 | Map json) =>
11 | _$NovelSearchRespImpl(
12 | data: (json['data'] as List?)
13 | ?.map((e) => NovelCover.fromJson(e as Map))
14 | .toList() ??
15 | null,
16 | nextKey: json['next_key'] as String? ?? null,
17 | payload:
18 | ComponentPayload.fromJson(json['payload'] as Map),
19 | );
20 |
21 | Map _$$NovelSearchRespImplToJson(
22 | _$NovelSearchRespImpl instance) =>
23 | {
24 | 'data': instance.data,
25 | 'next_key': instance.nextKey,
26 | 'payload': instance.payload,
27 | };
28 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/payload/component_payload.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 |
3 | part 'component_payload.g.dart';
4 | part 'component_payload.freezed.dart';
5 |
6 | /// 所有 Component 的 所有方法都附带一个该负载,用于返回错误信息等
7 | @freezed
8 | class ComponentPayload with _$ComponentPayload {
9 |
10 | static ComponentPayload ok() => ComponentPayload();
11 |
12 | // 调用错误 - 插件崩溃,运行时调用错误等
13 | static const codeCallError = -10086;
14 |
15 | // 解析错误 - 插件返回的数据无法解析成对应实体
16 | static const codeParseResultError = -10085;
17 |
18 | // 业务错误 - 一般是插件手动抛出的异常
19 | static const codeBusinessError = -10084;
20 |
21 | factory ComponentPayload({
22 | @JsonKey(name: "code") @Default(0) int code,
23 | @JsonKey(name: "msg") @Default("") String msg,
24 |
25 | // 业务端返回的解析前的原始数据
26 | @JsonKey(name: "raw") @Default("") dynamic raw,
27 | }) = _ComponentPayload;
28 |
29 | factory ComponentPayload.fromJson(Map json) =>
30 | _$ComponentPayloadFromJson(json);
31 | }
32 |
33 | extension ComponentPayloadExt on ComponentPayload{
34 | static final _errorMsgValues = Expando();
35 | String get errorMsg {
36 | return _errorMsgValues[this] ??= "${
37 | code == ComponentPayload.codeCallError ? "调用错误 $msg" :
38 | code == ComponentPayload.codeParseResultError ? "解析错误 $msg" :
39 | code == ComponentPayload.codeBusinessError ? msg :
40 | "未知错误 $code $msg"
41 | } ";
42 | }
43 |
44 | bool get isError => code != 0;
45 | }
46 |
--------------------------------------------------------------------------------
/lib/plugin/component/api/payload/component_payload.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'component_payload.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$ComponentPayloadImpl _$$ComponentPayloadImplFromJson(
10 | Map json) =>
11 | _$ComponentPayloadImpl(
12 | code: (json['code'] as num?)?.toInt() ?? 0,
13 | msg: json['msg'] as String? ?? "",
14 | raw: json['raw'] ?? "",
15 | );
16 |
17 | Map _$$ComponentPayloadImplToJson(
18 | _$ComponentPayloadImpl instance) =>
19 | {
20 | 'code': instance.code,
21 | 'msg': instance.msg,
22 | 'raw': instance.raw,
23 | };
24 |
--------------------------------------------------------------------------------
/lib/plugin/component/core/js/js_component.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:easy_mygo/entity/source/source_info/source_info.dart';
3 | import 'package:easy_mygo/plugin/component/api/component.dart';
4 | import 'package:easy_mygo/plugin/component/core/js/manga/detailed/js_manga_detailed_component.dart';
5 | import 'package:easy_mygo/plugin/component/core/js/manga/home/js_manga_home_component.dart';
6 | import 'package:easy_mygo/plugin/component/core/js/manga/read/js_manga_read_component.dart';
7 | import 'package:easy_mygo/plugin/component/core/js/manga/search/js_manga_search_component.dart';
8 | import 'package:easy_mygo/plugin/component/core/js/novel/detailed/js_novel_detailed_component.dart';
9 | import 'package:easy_mygo/plugin/component/core/js/novel/home/js_novel_home_component.dart';
10 | import 'package:easy_mygo/plugin/component/core/js/novel/read/js_novel_read_component.dart';
11 | import 'package:easy_mygo/plugin/component/core/js/novel/search/js_novel_search_component.dart';
12 | import 'package:flutter_js/flutter_js.dart';
13 |
14 |
15 | abstract class JsComponent extends Component {
16 |
17 | static List create( SourceInfo sourceInfo,JavascriptRuntime runtime) => [
18 | JsMangaHomeComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
19 | JsMangaDetailedComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
20 | JsMangaSearchComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
21 | JsMangaReadComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
22 |
23 | JsNovelHomeComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
24 | JsNovelDetailedComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
25 | JsNovelSearchComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
26 | JsNovelReadComponent(sourceInfo: sourceInfo, jsRuntime: runtime),
27 | ];
28 |
29 | JsComponent(super.sourceInfo);
30 |
31 |
32 | Future isAvailable();
33 |
34 | Future onLoad();
35 |
36 | }
--------------------------------------------------------------------------------
/lib/plugin/extension/controller/extension_controller.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'extension_controller.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$ExtensionStateImpl _$$ExtensionStateImplFromJson(Map json) =>
10 | _$ExtensionStateImpl(
11 | loading: json['loading'] as bool? ?? true,
12 | extensions: (json['extensions'] as Map?)?.map(
13 | (k, e) =>
14 | MapEntry(k, ExtensionData.fromJson(e as Map)),
15 | ) ??
16 | const {},
17 | );
18 |
19 | Map _$$ExtensionStateImplToJson(
20 | _$ExtensionStateImpl instance) =>
21 | {
22 | 'loading': instance.loading,
23 | 'extensions': instance.extensions,
24 | };
25 |
26 | // **************************************************************************
27 | // RiverpodGenerator
28 | // **************************************************************************
29 |
30 | String _$extensionControllerHash() =>
31 | r'e11e3407b5ccba7171054da9106fa6ceee9d9b04';
32 |
33 | /// 负责拓展加载,只加载拓展,不加载源
34 | /// 最终源的加载在 SourceController
35 | ///
36 | /// Copied from [ExtensionController].
37 | @ProviderFor(ExtensionController)
38 | final extensionControllerPod =
39 | AutoDisposeNotifierProvider.internal(
40 | ExtensionController.new,
41 | name: r'extensionControllerPod',
42 | debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
43 | ? null
44 | : _$extensionControllerHash,
45 | dependencies: null,
46 | allTransitiveDependencies: null,
47 | );
48 |
49 | typedef _$ExtensionController = AutoDisposeNotifier;
50 | // ignore_for_file: type=lint
51 | // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
52 |
--------------------------------------------------------------------------------
/lib/plugin/extension/loader/extension_loader.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:easy_mygo/entity/extension/extension_data/extension_data.dart';
4 | import 'package:easy_mygo/entity/extension/extension_info/extension_info.dart';
5 | import 'package:easy_mygo/plugin/extension/loader/inner/inner_extension_loader.dart';
6 | import 'package:easy_mygo/plugin/extension/loader/js/js_extension_loader.dart';
7 |
8 | import 'mygopack/mygopack_extension_loader.dart';
9 |
10 | abstract class ExtensionLoader {
11 |
12 | static const libVersionMin = 1;
13 | static const libVersionMax = 1;
14 |
15 | static final _loaders = {
16 | ExtensionLoaderType.js: JsExtensionLoader(),
17 | ExtensionLoaderType.mygopack: MygopackExtensionLoader(),
18 | ExtensionLoaderType.inner: InnerExtensionLoader(),
19 | };
20 |
21 | static ExtensionLoader of(ExtensionLoaderType type) {
22 | return _loaders[type]!;
23 | }
24 |
25 | static ExtensionLoader? ofName(String name) {
26 | for (var key in _loaders.keys) {
27 | final loader = _loaders[key];
28 | if(loader?.type.name == name){
29 | return loader;
30 | }
31 | }
32 | return null;
33 | }
34 |
35 |
36 | ExtensionLoaderType get type;
37 |
38 | /// 解析拓展元数据
39 | Future parse(String file);
40 |
41 | /// 加载拓展
42 | Future load(ExtensionInfo extensionInfo);
43 |
44 | }
--------------------------------------------------------------------------------
/lib/plugin/extension/loader/inner/inner_extension_loader.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/entity/extension/extension_data/extension_data.dart';
2 | import 'package:easy_mygo/entity/extension/extension_info/extension_info.dart';
3 | import 'package:easy_mygo/entity/source/source_info/source_info.dart';
4 | import 'package:easy_mygo/plugin/extension/loader/extension_loader.dart';
5 | import 'package:easy_mygo/plugin/extension/utils/extension_utils.dart';
6 | import 'package:easy_mygo/plugin/inner/inner_source.dart';
7 | import 'package:easy_mygo/plugin/source/loader/source_loader.dart';
8 |
9 | class InnerExtensionLoader extends ExtensionLoader {
10 |
11 | @override
12 | Future load(ExtensionInfo extensionInfo) async {
13 | final folder = await ExtensionUtils.getInnerFolder();
14 | if (extensionInfo == InnerSourceFactory.innerExtensionInfo) {
15 |
16 | final keys = InnerSourceFactory.getKeys();
17 | final List sources = [];
18 | final loader = SourceLoader.of(SourceLoaderType.inner);
19 | for (var key in keys) {
20 | final sourceInfo = await loader.parse(InnerSourceFactory.innerExtensionPackage, key);
21 | if(sourceInfo == null){
22 | continue;
23 | }
24 | sources.add(sourceInfo);
25 | }
26 |
27 | return ExtensionData(
28 | info: extensionInfo,
29 | folderPath: folder,
30 | sources: sources,
31 | );
32 | }
33 | return ExtensionData(info: extensionInfo,
34 | folderPath: folder,
35 | state: ExtensionLoadState.error,
36 | errorMsg: "内置插件非法加载");
37 | }
38 |
39 | @override
40 | Future parse(String file) async {
41 | if (file == InnerSourceFactory.innerExtensionPackage) {
42 | return InnerSourceFactory.innerExtensionInfo;
43 | }
44 | return null;
45 | }
46 |
47 | @override
48 | ExtensionLoaderType get type => ExtensionLoaderType.inner;
49 |
50 | }
--------------------------------------------------------------------------------
/lib/plugin/extension/loader/js/js_extension_loader.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | import 'package:easy_mygo/entity/extension/extension_data/extension_data.dart';
5 | import 'package:easy_mygo/entity/extension/extension_info/extension_info.dart';
6 | import 'package:easy_mygo/plugin/extension/loader/extension_loader.dart';
7 |
8 | class JsExtensionLoader extends ExtensionLoader {
9 |
10 |
11 |
12 | @override
13 | Future load(ExtensionInfo extensionInfo) {
14 | throw UnimplementedError();
15 | }
16 |
17 | @override
18 | ExtensionLoaderType get type => ExtensionLoaderType.js;
19 |
20 | @override
21 | Future parse(String file) {
22 | // TODO: implement parse
23 | throw UnimplementedError();
24 | }
25 |
26 |
27 | }
--------------------------------------------------------------------------------
/lib/plugin/extension/loader/mygopack/manifest/mygopack_manifest_info.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:freezed_annotation/freezed_annotation.dart';
4 |
5 | part 'mygopack_manifest_info.g.dart';
6 | part 'mygopack_manifest_info.freezed.dart';
7 |
8 | /// Mygo 插件包清单文件解析实体
9 | @freezed
10 | class MygoPackManifest with _$MygoPackManifest {
11 | factory MygoPackManifest({
12 | // 包名唯一
13 | required String package,
14 | required String label,
15 | @JsonKey(name: 'version_name') required String versionName,
16 | @JsonKey(name: 'version_code') required int versionCode,
17 | @JsonKey(name: 'lib_version') required int libVersion,
18 | @Default("") String readme,
19 |
20 | }) = _MygoPackManifest;
21 |
22 | factory MygoPackManifest.fromJson(Map json) =>
23 | _$MygoPackManifestFromJson(json);
24 | }
--------------------------------------------------------------------------------
/lib/plugin/extension/loader/mygopack/manifest/mygopack_manifest_info.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'mygopack_manifest_info.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | _$MygoPackManifestImpl _$$MygoPackManifestImplFromJson(
10 | Map json) =>
11 | _$MygoPackManifestImpl(
12 | package: json['package'] as String,
13 | label: json['label'] as String,
14 | versionName: json['version_name'] as String,
15 | versionCode: (json['version_code'] as num).toInt(),
16 | libVersion: (json['lib_version'] as num).toInt(),
17 | readme: json['readme'] as String? ?? "",
18 | );
19 |
20 | Map _$$MygoPackManifestImplToJson(
21 | _$MygoPackManifestImpl instance) =>
22 | {
23 | 'package': instance.package,
24 | 'label': instance.label,
25 | 'version_name': instance.versionName,
26 | 'version_code': instance.versionCode,
27 | 'lib_version': instance.libVersion,
28 | 'readme': instance.readme,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/plugin/extension/utils/extension_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_mygo/c.dart';
2 | import 'package:easy_mygo/entity/extension/extension_info/extension_info.dart';
3 | import 'package:easy_mygo/plugin/inner/inner_source.dart';
4 | import 'package:easy_mygo/utils/file_index/file_index_utils.dart';
5 | import 'package:path/path.dart';
6 |
7 | class ExtensionUtils {
8 | static const extensionRootPath = "extension";
9 |
10 | /// /extension//
11 | static Future getFolder(
12 | ExtensionLoaderType loaderType, String package) async {
13 | final applicationDir = await EasyConstant.applicationPath;
14 | return join(
15 | applicationDir.path, extensionRootPath, loaderType.name, package);
16 | }
17 |
18 | static Future getInnerFolder() async {
19 | return await getFolder(
20 | ExtensionLoaderType.inner, InnerSourceFactory.innerExtensionPackage);
21 | }
22 |
23 | static Future