├── .gitattributes
├── .gradle
├── 7.2
│ ├── dependencies-accessors
│ │ ├── dependencies-accessors.lock
│ │ └── gc.properties
│ ├── executionHistory
│ │ ├── executionHistory.bin
│ │ └── executionHistory.lock
│ ├── fileChanges
│ │ └── last-build.bin
│ ├── fileHashes
│ │ ├── fileHashes.bin
│ │ ├── fileHashes.lock
│ │ └── resourceHashesCache.bin
│ └── gc.properties
├── buildOutputCleanup
│ ├── buildOutputCleanup.lock
│ ├── cache.properties
│ └── outputFiles.bin
├── checksums
│ ├── checksums.lock
│ ├── md5-checksums.bin
│ └── sha1-checksums.bin
└── vcs-1
│ └── gc.properties
├── .idea
├── .gitignore
├── compiler.xml
├── gradle.xml
├── libraries
│ ├── Gradle__androidx_activity_activity_1_2_3_aar.xml
│ ├── Gradle__androidx_annotation_annotation_1_2_0.xml
│ ├── Gradle__androidx_annotation_annotation_experimental_1_1_0_aar.xml
│ ├── Gradle__androidx_appcompat_appcompat_1_3_0_aar.xml
│ ├── Gradle__androidx_appcompat_appcompat_resources_1_3_0_aar.xml
│ ├── Gradle__androidx_arch_core_core_common_2_1_0.xml
│ ├── Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml
│ ├── Gradle__androidx_arch_core_core_runtime_2_1_0_aar.xml
│ ├── Gradle__androidx_cardview_cardview_1_0_0_aar.xml
│ ├── Gradle__androidx_collection_collection_1_1_0.xml
│ ├── Gradle__androidx_constraintlayout_constraintlayout_2_0_4_aar.xml
│ ├── Gradle__androidx_constraintlayout_constraintlayout_solver_2_0_4.xml
│ ├── Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml
│ ├── Gradle__androidx_core_core_1_7_0_aar.xml
│ ├── Gradle__androidx_core_core_ktx_1_7_0_aar.xml
│ ├── Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml
│ ├── Gradle__androidx_customview_customview_1_0_0_aar.xml
│ ├── Gradle__androidx_databinding_viewbinding_7_1_1_aar.xml
│ ├── Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml
│ ├── Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml
│ ├── Gradle__androidx_dynamicanimation_dynamicanimation_1_0_0_aar.xml
│ ├── Gradle__androidx_fragment_fragment_1_3_4_aar.xml
│ ├── Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml
│ ├── Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml
│ ├── Gradle__androidx_lifecycle_lifecycle_common_2_3_1.xml
│ ├── Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml
│ ├── Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_1_aar.xml
│ ├── Gradle__androidx_lifecycle_lifecycle_runtime_2_3_1_aar.xml
│ ├── Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_1_aar.xml
│ ├── Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_1_aar.xml
│ ├── Gradle__androidx_loader_loader_1_0_0_aar.xml
│ ├── Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml
│ ├── Gradle__androidx_print_print_1_0_0_aar.xml
│ ├── Gradle__androidx_recyclerview_recyclerview_1_1_0_aar.xml
│ ├── Gradle__androidx_savedstate_savedstate_1_1_0_aar.xml
│ ├── Gradle__androidx_test_core_1_4_0_aar.xml
│ ├── Gradle__androidx_test_espresso_espresso_core_3_4_0_aar.xml
│ ├── Gradle__androidx_test_espresso_espresso_idling_resource_3_4_0_aar.xml
│ ├── Gradle__androidx_test_ext_junit_1_1_3_aar.xml
│ ├── Gradle__androidx_test_monitor_1_4_0_aar.xml
│ ├── Gradle__androidx_test_runner_1_4_0_aar.xml
│ ├── Gradle__androidx_test_services_storage_1_4_0_aar.xml
│ ├── Gradle__androidx_transition_transition_1_2_0_aar.xml
│ ├── Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml
│ ├── Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml
│ ├── Gradle__androidx_versionedparcelable_versionedparcelable_1_1_1_aar.xml
│ ├── Gradle__androidx_viewpager2_viewpager2_1_0_0_aar.xml
│ ├── Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml
│ ├── Gradle__com_google_android_material_material_1_4_0_aar.xml
│ ├── Gradle__com_google_code_findbugs_jsr305_2_0_1.xml
│ ├── Gradle__com_squareup_javawriter_2_1_1.xml
│ ├── Gradle__javax_inject_javax_inject_1.xml
│ ├── Gradle__junit_junit_4_12.xml
│ ├── Gradle__junit_junit_4_13_2.xml
│ ├── Gradle__org_hamcrest_hamcrest_core_1_3.xml
│ ├── Gradle__org_hamcrest_hamcrest_integration_1_3.xml
│ ├── Gradle__org_hamcrest_hamcrest_library_1_3.xml
│ ├── Gradle__org_jetbrains_annotations_13_0.xml
│ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_6_10.xml
│ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_6_10.xml
│ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_6_10.xml
│ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_6_10.xml
│ └── Gradle__org_jsoup_jsoup_1_14_3.xml
├── misc.xml
├── modules.xml
├── modules
│ ├── MediaBoxPlugin.iml
│ ├── app
│ │ └── MediaBoxPlugin.app.iml
│ └── pluginApi
│ │ └── MediaBoxPlugin.pluginApi.iml
└── vcs.xml
├── LICENSE
├── README.md
├── build.gradle.kts
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── pluginApi
├── .gitignore
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── su
│ │ └── mediabox
│ │ └── pluginapi
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── su
│ │ └── mediabox
│ │ └── pluginapi
│ │ ├── Constant.kt
│ │ ├── IPluginFactory.kt
│ │ ├── action
│ │ ├── Action.kt
│ │ ├── ClassifyAction.kt
│ │ ├── CustomPageAction.kt
│ │ ├── DetailAction.kt
│ │ ├── HomeAction.kt
│ │ ├── PlayAction.kt
│ │ ├── SearchAction.kt
│ │ └── WebBrowserAction.kt
│ │ ├── components
│ │ ├── IBasePageDataComponent.kt
│ │ ├── ICustomPageDataComponent.kt
│ │ ├── IHomePageDataComponent.kt
│ │ ├── IMediaClassifyPageDataComponent.kt
│ │ ├── IMediaDetailPageDataComponent.kt
│ │ ├── IMediaSearchPageDataComponent.kt
│ │ ├── IMediaUpdateDataComponent.kt
│ │ └── IVideoPlayPageDataComponent.kt
│ │ ├── data
│ │ ├── BannerData.kt
│ │ ├── BaseData.kt
│ │ ├── ClassifyItemData.kt
│ │ ├── Cover1Data.kt
│ │ ├── EpisodeData.kt
│ │ ├── EpisodeListData.kt
│ │ ├── HorizontalListData.kt
│ │ ├── LongTextData.kt
│ │ ├── MediaInfo1Data.kt
│ │ ├── MediaInfo2Data.kt
│ │ ├── SimpleTextData.kt
│ │ ├── TagData.kt
│ │ ├── TagFlowData.kt
│ │ ├── TextData.kt
│ │ ├── VideoPlayMedia.kt
│ │ └── ViewPagerData.kt
│ │ └── util
│ │ ├── AppUtil.kt
│ │ ├── PreferenceUtil.kt
│ │ ├── TextUtil.kt
│ │ ├── UIUtil.kt
│ │ ├── WebUtil.kt
│ │ └── danmaku
│ │ ├── AnimeDanmakuParser.kt
│ │ └── BiliBiliDanmakuParser.kt
│ └── test
│ └── java
│ └── com
│ └── su
│ └── mediabox
│ └── pluginapi
│ └── ExampleUnitTest.kt
└── settings.gradle.kts
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock
--------------------------------------------------------------------------------
/.gradle/7.2/dependencies-accessors/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/dependencies-accessors/gc.properties
--------------------------------------------------------------------------------
/.gradle/7.2/executionHistory/executionHistory.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/executionHistory/executionHistory.bin
--------------------------------------------------------------------------------
/.gradle/7.2/executionHistory/executionHistory.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/executionHistory/executionHistory.lock
--------------------------------------------------------------------------------
/.gradle/7.2/fileChanges/last-build.bin:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gradle/7.2/fileHashes/fileHashes.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/fileHashes/fileHashes.bin
--------------------------------------------------------------------------------
/.gradle/7.2/fileHashes/fileHashes.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/fileHashes/fileHashes.lock
--------------------------------------------------------------------------------
/.gradle/7.2/fileHashes/resourceHashesCache.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/fileHashes/resourceHashesCache.bin
--------------------------------------------------------------------------------
/.gradle/7.2/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/7.2/gc.properties
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/buildOutputCleanup.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/buildOutputCleanup/buildOutputCleanup.lock
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/cache.properties:
--------------------------------------------------------------------------------
1 | #Sun Feb 13 11:40:23 CST 2022
2 | gradle.version=7.2
3 |
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/outputFiles.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/buildOutputCleanup/outputFiles.bin
--------------------------------------------------------------------------------
/.gradle/checksums/checksums.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/checksums/checksums.lock
--------------------------------------------------------------------------------
/.gradle/checksums/md5-checksums.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/checksums/md5-checksums.bin
--------------------------------------------------------------------------------
/.gradle/checksums/sha1-checksums.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/checksums/sha1-checksums.bin
--------------------------------------------------------------------------------
/.gradle/vcs-1/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/.gradle/vcs-1/gc.properties
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_activity_activity_1_2_3_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_annotation_annotation_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_3_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_3_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_cardview_cardview_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_2_0_4_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_solver_2_0_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_core_core_1_7_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_core_core_ktx_1_7_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_databinding_viewbinding_7_1_1_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_dynamicanimation_dynamicanimation_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_fragment_fragment_1_3_4_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_3_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_1_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_3_1_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_1_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_1_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_recyclerview_recyclerview_1_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_core_1_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_3_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_monitor_1_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_runner_1_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_test_services_storage_1_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_transition_transition_1_2_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_1_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_viewpager2_viewpager2_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_android_material_material_1_4_0_aar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__junit_junit_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__junit_junit_4_13_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_jetbrains_annotations_13_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_6_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_6_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_6_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_6_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_jsoup_jsoup_1_14_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/modules/MediaBoxPlugin.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/modules/app/MediaBoxPlugin.app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | generateDebugSources
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/.idea/modules/pluginApi/MediaBoxPlugin.pluginApi.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | generateDebugSources
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MediaBoxPlugin
2 | [**MediaBox**](https://github.com/RyensX/MediaBox)插件API
3 |
4 | ## [插件开发指南](https://github.com/RyensX/MediaBox/wiki)
5 |
6 | ## 示例
7 | - [樱花动漫](https://github.com/RyensX/SakuraAnimePlugin)
8 | - [樱花动漫2](https://github.com/RyensX/SakuraAnimePlugin)
9 | - [今热](https://github.com/RyensX/TodayHot)
10 |
11 | ## 欢迎提交插件到[插件仓库](https://github.com/RyensX/MediaBoxPluginRepository)
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id("com.android.application") version "7.1.1" apply false
4 | id("com.android.library") version "7.1.1" apply false
5 | id("org.jetbrains.kotlin.android") version "1.6.10" apply false
6 | }
7 |
8 | tasks.register("clean") {
9 | delete(rootProject.buildDir)
10 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library"s R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library"s dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RyensX/MediaBoxPlugin/4616843a940b018865e2a5fb70d4e078d61dd652/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Feb 13 11:40:16 CST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : ".*-> \(.*\)$"`
32 | if expr "$link" : "/.*" > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS=""-Xmx64m" "-Xms64m""
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be "true" or "false").
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM"s JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no "java" command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/"/"\\\\""/g;1s/^/"/;\$s/\$/" \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no "java" command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file should *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=C\:\\Users\\Ryens\\AppData\\Local\\Android\\Sdk
--------------------------------------------------------------------------------
/pluginApi/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/pluginApi/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | id("org.jetbrains.kotlin.android")
4 | }
5 |
6 | android {
7 | compileSdk = 31
8 |
9 | defaultConfig {
10 | minSdk = 21
11 | targetSdk = 31
12 |
13 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
14 | consumerProguardFiles("consumer-rules.pro")
15 | }
16 |
17 | buildTypes {
18 | release {
19 | isMinifyEnabled = false
20 | proguardFiles(
21 | getDefaultProguardFile("proguard-android-optimize.txt"),
22 | "proguard-rules.pro"
23 | )
24 | }
25 | }
26 | compileOptions {
27 | sourceCompatibility = JavaVersion.VERSION_1_8
28 | targetCompatibility = JavaVersion.VERSION_1_8
29 | }
30 | kotlinOptions {
31 | jvmTarget = "1.8"
32 | }
33 | }
34 |
35 | dependencies {
36 | compileOnly("com.kuaishou:akdanmaku:1.0.3")
37 | }
--------------------------------------------------------------------------------
/pluginApi/consumer-rules.pro:
--------------------------------------------------------------------------------
1 | # 插件系统
2 | -keep class com.su.mediabox.pluginapi.** {*;}
3 | -keep class * extends com.su.mediabox.pluginapi.data.BaseData {*;}
4 | -keep class * extends com.su.mediabox.pluginapi.components.IBasePageDataComponent {*;}
5 | -keep class * extends com.su.mediabox.pluginapi.action.Action {*;}
6 | -keep class * extends com.su.mediabox.pluginapi.IPluginFactory {*;}
--------------------------------------------------------------------------------
/pluginApi/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # 插件系统
2 | # 组件不能混淆
3 | -keep class com.su.mediabox.pluginapi.** {*;}
--------------------------------------------------------------------------------
/pluginApi/src/androidTest/java/com/su/mediabox/pluginapi/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.su.mediabox.pluginapi.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/Constant.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi
2 |
3 | import kotlin.random.Random
4 |
5 | object Constant {
6 |
7 | /**
8 | * 调试标记,在插件任意一个Activity(一般是LAUNCHER)添加一个即可让媒体盒子识别为外部插件以方便调试
9 | */
10 | const val PLUGIN_DEBUG_ACTION = "media_plugin_debug"
11 |
12 | const val DEFAULT_SPAN_COUNT = 8
13 |
14 | //默认占满一行
15 | const val DEFAULT_SPAN_SIZE = DEFAULT_SPAN_COUNT
16 |
17 | object Request {
18 | val USER_AGENT_ARRAY = arrayOf(
19 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60",
20 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36",
21 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)",
22 | "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0",
23 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36",
24 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1",
25 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
26 | "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
27 | "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
28 | "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
29 | "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
30 | "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
31 | "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
32 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
33 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
34 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
35 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
36 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
37 | "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
38 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
39 | )
40 |
41 | /**
42 | * 随机获取一个UA
43 | */
44 | fun getRandomUserAgent() = USER_AGENT_ARRAY.run { get(Random.nextInt(size)) }
45 | }
46 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/IPluginFactory.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi
2 |
3 | import com.su.mediabox.pluginapi.action.Action
4 | import com.su.mediabox.pluginapi.components.IBasePageDataComponent
5 | import com.su.mediabox.pluginapi.action.HomeAction
6 | import java.lang.annotation.Inherited
7 |
8 | /**
9 | * 插件工厂
10 | *
11 | * 每个插件都必须实现且提供一个无参构造方法
12 | */
13 | abstract class IPluginFactory {
14 |
15 | /**
16 | * 入口动作,在插件列表启动插件后执行的动作,一般用于启动初始界面
17 | *
18 | * 默认[HomeAction],即直接启动家页面
19 | */
20 | open val initAction: Action = HomeAction
21 |
22 | /**
23 | * 根据类型创建组件
24 | */
25 | abstract fun createComponent(clazz: Class): T?
26 |
27 | /**
28 | * 插件启动时被调用
29 | */
30 | open fun pluginLaunch() {}
31 |
32 | /**
33 | * 插件对应数据源域名
34 | */
35 | abstract val host: String
36 |
37 | open val imageRefererProcessor: ImageRefererProcessor? = null
38 |
39 | /**
40 | * 用于处理类似referer防盗链等情况
41 | */
42 | fun interface ImageRefererProcessor {
43 | /**
44 | * @param url 请求链接
45 | * @return referer
46 | */
47 | fun processor(url: String): String?
48 | }
49 |
50 | /**
51 | * 单例组件注解。
52 | *
53 | * 被标注次注解的组件在宿主里create时会加入组件池作为单例
54 | */
55 | @Target(AnnotationTarget.CLASS)
56 | @Retention(AnnotationRetention.RUNTIME)
57 | @Inherited
58 | annotation class SingletonComponent
59 |
60 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/Action.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 | import com.su.mediabox.pluginapi.util.AppUtil
5 | import java.io.Serializable
6 |
7 | /**
8 | * 组件数据动作
9 | *
10 | * 每个Action都必须实现一个静态的obtain公开方法生成对应动作而不是直接构造
11 | */
12 | abstract class Action : Serializable {
13 |
14 | /**
15 | * 额外数据,用于扩展Action
16 | */
17 | var extraData: Any? = null
18 |
19 | companion object {
20 | //动作池,每种动作对应一个List
21 | val actionPool by lazy(LazyThreadSafetyMode.NONE) { mutableMapOf, MutableSet>() }
22 |
23 | fun putAction(action: Action) {
24 | val set = actionPool[action.javaClass]
25 | ?: mutableSetOf().also { actionPool[action.javaClass] = it }
26 | set.add(action)
27 | }
28 |
29 | inline fun getAction(equal: A.() -> Boolean) =
30 | actionPool[A::class.java]?.find {
31 | it is A && it.equal()
32 | } as? A
33 | }
34 |
35 | /**
36 | * 动作执行
37 | *
38 | * @param context 不要持有,有需要全局可使用[AppUtil.appContext]
39 | */
40 | abstract fun go(context: Context)
41 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/ClassifyAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 |
5 | class ClassifyAction private constructor(
6 | val url: String?,
7 | val classifyCategory: String?,
8 | val classify: String?
9 | ) : Action() {
10 | companion object {
11 | //由宿主初始化
12 | lateinit var GO: ClassifyAction.(Context) -> Unit
13 |
14 | /**
15 | * @param url 分类链接,不为空时默认加载
16 | * @param classifyCategory 分类类别,如地区
17 | * @param classify 具体分类,如大陆,与classifyCategory均不为空则自动定位选中
18 | */
19 | fun obtain(
20 | url: String? = null,
21 | classifyCategory: String? = null,
22 | classify: String? = null
23 | ) =
24 | getAction { this.url == url && this.classifyCategory == classifyCategory && this.classify == classify }
25 | ?: ClassifyAction(url, classifyCategory, classify)
26 | }
27 |
28 | override fun go(context: Context) {
29 | GO(context)
30 | }
31 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/CustomPageAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 | import com.su.mediabox.pluginapi.components.ICustomPageDataComponent
5 |
6 | class CustomPageAction private constructor(val targetPageComponent: Class<*>) : Action() {
7 |
8 | companion object {
9 | //由宿主初始化
10 | lateinit var GO: CustomPageAction.(Context) -> Unit
11 |
12 | fun obtain(targetPageComponent: Class) =
13 | getAction { this.targetPageComponent == targetPageComponent }
14 | ?: CustomPageAction(targetPageComponent)
15 | }
16 |
17 | override fun go(context: Context) {
18 | GO(context)
19 | }
20 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/DetailAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 |
5 | class DetailAction private constructor(val url: String) : Action() {
6 | companion object {
7 | //由宿主初始化
8 | lateinit var GO: DetailAction.(Context) -> Unit
9 |
10 | fun obtain(url: String) = getAction { this.url == url } ?: DetailAction(url)
11 | }
12 |
13 | override fun go(context: Context) {
14 | GO(context)
15 | }
16 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/HomeAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 |
5 | object HomeAction : Action() {
6 |
7 | //由宿主初始化
8 | lateinit var GO: HomeAction.(Context) -> Unit
9 |
10 | override fun go(context: Context) {
11 | GO(context)
12 | }
13 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/PlayAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 |
5 | /**
6 | * @param playerManager 自定义解码器(Icom.shuyu.gsyvideoplayer.player.PlayerManager),为空则使用默认的
7 | * @param autoRotate 开始播放时是否支持自动旋转
8 | */
9 | class PlayAction private constructor(
10 | val episodeUrl: String,
11 | var coverUrl: String,
12 | var detailPartUrl: String,
13 | var videoName: String,
14 | var playerManager: Class<*>?,
15 | val autoRotate: Boolean
16 | ) : Action() {
17 | companion object {
18 | //由宿主初始化
19 | lateinit var GO: PlayAction.(Context) -> Unit
20 |
21 | fun obtain(
22 | episodeUrl: String,
23 | coverUrl: String = "",
24 | detailPartUrl: String = "",
25 | videoName: String = ""
26 | ) = obtain(episodeUrl, coverUrl, detailPartUrl, videoName, null)
27 |
28 | /**
29 | * @param episodeUrl 剧集链接,插件只需要提供此参数,其余数据由宿主自动填入
30 | */
31 | fun obtain(
32 | episodeUrl: String,
33 | coverUrl: String = "",
34 | detailPartUrl: String = "",
35 | videoName: String = "",
36 | playerManager: Class<*>? = null,
37 | autoRotate: Boolean = false
38 | ) = getAction {
39 | this.episodeUrl == episodeUrl &&
40 | this.playerManager == playerManager
41 | }
42 | ?: PlayAction(episodeUrl, coverUrl, detailPartUrl, videoName, playerManager, autoRotate)
43 | }
44 |
45 | override fun go(context: Context) {
46 | GO(context)
47 | }
48 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/SearchAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 |
5 | class SearchAction private constructor(val keyWork: String) : Action() {
6 | companion object {
7 | //由宿主初始化
8 | lateinit var GO: SearchAction.(Context) -> Unit
9 |
10 | fun obtain(keyWork: String = "") =
11 | getAction { this.keyWork == keyWork } ?: SearchAction(keyWork)
12 | }
13 |
14 | override fun go(context: Context) {
15 | GO(context)
16 | }
17 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/action/WebBrowserAction.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.action
2 |
3 | import android.content.Context
4 | import com.su.mediabox.pluginapi.util.WebUtil
5 |
6 | class WebBrowserAction private constructor(val url: String, val loadPolicy: WebUtil.LoadPolicy) :
7 | Action() {
8 | companion object {
9 | //由宿主初始化
10 | lateinit var GO: WebBrowserAction.(Context) -> Unit
11 |
12 | @JvmOverloads
13 | fun obtain(url: String, loadPolicy: WebUtil.LoadPolicy = WebUtil.DefaultLoadPolicy) =
14 | getAction { this.url == url } ?: WebBrowserAction(url, loadPolicy)
15 | }
16 |
17 | override fun go(context: Context) {
18 | GO(context)
19 | }
20 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IBasePageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | /**
4 | * 基页面数据组件
5 | */
6 | interface IBasePageDataComponent
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/ICustomPageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | import com.su.mediabox.pluginapi.IPluginFactory
4 | import com.su.mediabox.pluginapi.action.Action
5 | import com.su.mediabox.pluginapi.action.CustomPageAction
6 | import com.su.mediabox.pluginapi.data.BaseData
7 |
8 | /**
9 | * 自定义页面数据组件
10 | *
11 | * 由[CustomPageAction]启动,注意也必须在[IPluginFactory]的实现中注册
12 | */
13 | interface ICustomPageDataComponent : IBasePageDataComponent {
14 |
15 | /**
16 | * 在page启动时会调用,如需要获取启动本页的action的子类可重写
17 | *
18 | * 在通过它传递自定义参数时可使用[Action.extraData]
19 | */
20 | fun initPage(action: CustomPageAction) {}
21 |
22 | /**
23 | * 页面名称
24 | */
25 | val pageName: String
26 |
27 | /**
28 | * 是否左上角显示返回按钮
29 | */
30 | fun isShowBack(): Boolean = true
31 |
32 | /**
33 | * 菜单,由[Action]组成,菜单标题使用[Action.extraData]
34 | */
35 | fun menus(): List? = null
36 |
37 | /**
38 | * 获取数据
39 | * @param page 由宿主控制的页码,在刷新时重置,在上拉时递增从1开始
40 | */
41 | suspend fun getData(page: Int): List?
42 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IHomePageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | import com.su.mediabox.pluginapi.data.BaseData
4 |
5 | /**
6 | * 首页页面数据组件
7 | */
8 | interface IHomePageDataComponent : IBasePageDataComponent {
9 | /**
10 | * 获取数据
11 | * @param page 由宿主控制的页码,在刷新时重置,在上拉时递增
12 | */
13 | suspend fun getData(page: Int): List?
14 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IMediaClassifyPageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | import com.su.mediabox.pluginapi.action.ClassifyAction
4 | import com.su.mediabox.pluginapi.data.BaseData
5 | import com.su.mediabox.pluginapi.data.ClassifyItemData
6 |
7 | /**
8 | * 媒体分类页面数据组件
9 | */
10 | interface IMediaClassifyPageDataComponent : IBasePageDataComponent {
11 |
12 | /**
13 | * 获取分类页分类弹窗里的分类项数据,如:地区-大陆
14 | *
15 | * 宿主在获取所有分类项数据后会根据[ClassifyAction.classifyCategory]自动进行分类
16 | */
17 | suspend fun getClassifyItemData(): List
18 |
19 | /**
20 | * 获取分类页分类下的媒体数据,如获取地区-分类下的所有作品数据
21 | * @param classifyAction 分类数据,见内部注释[ClassifyAction]
22 | * @param page 页码,由宿主控制(成功请求+1,刷新则清0)
23 | */
24 | suspend fun getClassifyData(classifyAction: ClassifyAction, page: Int): List
25 |
26 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IMediaDetailPageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | import com.su.mediabox.pluginapi.data.BaseData
4 |
5 | /**
6 | * 媒体详情页面数据组件
7 | */
8 | interface IMediaDetailPageDataComponent : IBasePageDataComponent {
9 | /**
10 | * 获取媒体详情页数据
11 | *
12 | * @param partUrl 页面部分url
13 | * @return Triple<封面,名称,详情页其他数据集>
14 | */
15 | suspend fun getMediaDetailData(partUrl: String): Triple>
16 |
17 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IMediaSearchPageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | import com.su.mediabox.pluginapi.data.BaseData
4 | import com.su.mediabox.pluginapi.data.MediaInfo2Data
5 |
6 | /**
7 | * 媒体搜索页面数据组件
8 | */
9 | interface IMediaSearchPageDataComponent : IBasePageDataComponent {
10 | /**
11 | * 获取搜索结果数据
12 | *
13 | * @param keyWord 搜索关键词
14 | * @param page 页码,由宿主控制(成功请求+1)
15 | *
16 | * @return 推荐使用[MediaInfo2Data]
17 | */
18 | suspend fun getSearchData(
19 | keyWord: String,
20 | page: Int
21 | ): List
22 |
23 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IMediaUpdateDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | /**
4 | * 媒体更新数据组件
5 | */
6 | interface IMediaUpdateDataComponent : IBasePageDataComponent {
7 |
8 | /**
9 | * 是否开启检查更新
10 | * @param updateTag 更新标志,如“全13集”这样的即表示无需更新
11 | *
12 | * @return 是否需要检查更新
13 | */
14 | suspend fun enableUpdateCheck(updateTag: String?): Boolean =
15 | updateTag?.run { !(contains("全") || contains("完结")) } ?: true
16 |
17 | /**
18 | * 获取更新标志,在打开收藏页时触发
19 | *
20 | * @param detailUrl 目标媒体详情页链接
21 | *
22 | * @return 更新标志,为空则表示失败
23 | */
24 | suspend fun getUpdateTag(detailUrl: String): String?
25 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/components/IVideoPlayPageDataComponent.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.components
2 |
3 | import android.graphics.Color
4 | import com.kuaishou.akdanmaku.data.DanmakuItemData
5 | import com.su.mediabox.pluginapi.data.VideoPlayMedia
6 | import com.su.mediabox.pluginapi.util.danmaku.AnimeDanmakuParser
7 | import com.su.mediabox.pluginapi.util.danmaku.BiliBiliDanmakuParser
8 |
9 | /**
10 | * 视频播放页面数据组件
11 | */
12 | interface IVideoPlayPageDataComponent : IBasePageDataComponent {
13 |
14 | /**
15 | * 获取弹幕数据,需要自行实现
16 | *
17 | * 如果是B站等地方的弹幕可以参考使用[BiliBiliDanmakuParser]和[AnimeDanmakuParser]等辅助解析
18 | *
19 | * @return 弹幕数据集
20 | */
21 | suspend fun getDanmakuData(videoName: String, episodeName: String, episodeUrl: String):
22 | List? = null
23 |
24 | /**
25 | * 发送一条弹幕,如果需要登陆等验证需要自行实现逻辑
26 | *
27 | * @param danmaku 弹幕内容
28 | * @param time 弹幕显示时间(播放视频当前进度)
29 | * @param color 弹幕颜色,参考[Color]
30 | * @param type 弹幕类型,取值[DanmakuItemData]的DANMAKU_MODE,如[DanmakuItemData.DANMAKU_MODE_ROLLING]
31 | *
32 | * @return 发送结果
33 | */
34 | suspend fun putDanmaku(
35 | videoName: String,
36 | episodeName: String,
37 | episodeUrl: String,
38 | danmaku: String,
39 | time: Long,
40 | color: Int,
41 | type: Int
42 | ): Boolean = false
43 |
44 | /**
45 | * 获取播放页面相关数据
46 | */
47 | suspend fun getVideoPlayMedia(episodeUrl: String): VideoPlayMedia
48 |
49 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/BannerData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import com.su.mediabox.pluginapi.util.UIUtil.dp
4 |
5 | /**
6 | * 横幅视图组件数据
7 | * @param autoPlayInterval 自动轮播时间间隔,如果为0则不会自动轮播
8 | * @param round 圆角
9 | */
10 | data class BannerData(
11 | val bannerItems: List,
12 | val round: Int = 4.dp,
13 | val autoPlayInterval: Long = 5000
14 | ) :
15 | BaseData() {
16 |
17 | class BannerItemData(
18 | val imageUrl: String,
19 | val title: String,
20 | val desc: String,
21 | ) : BaseData() {
22 | override var paddingLeft: Int = 0.dp
23 | override var paddingTop: Int = 0.dp
24 | override var paddingRight: Int = 0.dp
25 | override var paddingBottom: Int = 0.dp
26 | }
27 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/BaseData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import com.su.mediabox.pluginapi.Constant
4 | import com.su.mediabox.pluginapi.action.Action
5 | import com.su.mediabox.pluginapi.util.UIUtil.dp
6 |
7 | /**
8 | * V2版API的数据基类
9 |
10 | */
11 | abstract class BaseData {
12 | /**
13 | * 数据动作
14 | */
15 | var action: Action? = null
16 |
17 | /**
18 | * 布局配置,默认不设置,如果有需要最好只设置在第一个数据上,用于控制数据集列表整体布局
19 | *
20 | * 注意!!!这会导致数据所在整个列表布局发生变化,请谨慎使用
21 | */
22 | var layoutConfig: LayoutConfig? = null
23 |
24 | /**
25 | * 参考[GridLayoutManager]使用
26 | */
27 | open var spanSize: Int = Constant.DEFAULT_SPAN_SIZE
28 |
29 | open var paddingTop: Int = 0.dp
30 | open var paddingBottom: Int = 0.dp
31 | open var paddingLeft: Int = 0.dp
32 | open var paddingRight: Int = 0.dp
33 |
34 | /**
35 | * @param spanCount 与[GridLayoutManager]中的spanCount用法一致
36 | * @param itemSpacing 项分隔空间
37 | */
38 | data class LayoutConfig(
39 | val spanCount: Int = Constant.DEFAULT_SPAN_COUNT,
40 | val itemSpacing: Int = 8.dp
41 | ) {
42 | @Deprecated("兼容处理,会逐步删除,请尽快更新API")
43 | constructor(
44 | spanCount: Int = Constant.DEFAULT_SPAN_COUNT,
45 | itemSpacing: Int = 8.dp,
46 | listLeftEdge: Int = itemSpacing,
47 | listRightEdge: Int = itemSpacing,
48 | ) : this(spanCount, itemSpacing)
49 | }
50 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/ClassifyItemData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import com.su.mediabox.pluginapi.action.ClassifyAction
4 |
5 | /**
6 | * 分类项数据,如大陆
7 | *
8 | * 必须提供一个[ClassifyAction]
9 | *
10 | * 宿主在获取所有分类项数据后会根据[ClassifyAction.classifyCategory]自动进行分类
11 | */
12 | class ClassifyItemData : BaseData()
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/Cover1Data.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | /**
4 | * 封面样式1视图组件数据
5 | *
6 | * 可显示封面和处于封面左上角的评分
7 | */
8 | data class Cover1Data(
9 | var coverUrl: String,
10 | var score: Float = -1F//-1表示不显示评分
11 | ) : BaseData()
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/EpisodeData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | data class EpisodeData(val name: String, val url: String) : BaseData()
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/EpisodeListData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import com.su.mediabox.pluginapi.util.UIUtil.dp
4 |
5 | /**
6 | * 剧集列表视图组件数据
7 | */
8 | data class EpisodeListData(
9 | val playList: List
10 | ) : BaseData() {
11 | override var paddingTop: Int = 0.dp
12 | override var paddingRight: Int = 0.dp
13 | override var paddingBottom: Int = 0.dp
14 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/HorizontalListData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import android.view.ViewGroup
4 | import com.su.mediabox.pluginapi.util.UIUtil.dp
5 |
6 | /**
7 | * 水平列表视图组件数据
8 | * @param widthLimit 宽度限制,可设置dp和[ViewGroup.LayoutParams.MATCH_PARENT]等
9 | */
10 | class HorizontalListData @JvmOverloads constructor(
11 | val listData: List,
12 | val itemWidthLimit: Int = 128.dp
13 | ) : BaseData()
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/LongTextData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | /**
4 | * 长文本视图组件数据
5 | */
6 | data class LongTextData(
7 | val text: String
8 | ) : TextData()
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/MediaInfo1Data.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import android.graphics.Color
4 | import android.view.Gravity
5 | import android.widget.ImageView.ScaleType
6 | import com.su.mediabox.pluginapi.util.UIUtil.dp
7 |
8 | /**
9 | * 媒体信息样式1视图组件数据
10 | * @param other 剧集信息等
11 | * @param nameColor/otherColor 默认null使用主题色
12 | * @param gravity name和other等可显示文本的gravity
13 | */
14 | data class MediaInfo1Data(
15 | val name: String,
16 | val coverUrl: String,
17 | val url: String,
18 | val other: String = "",
19 | val other2: String = "",
20 | val nameColor: Int? = Color.BLACK,
21 | val otherColor: Int? = null,
22 | val coverScaleType: ScaleType = ScaleType.CENTER_CROP,
23 | val coverHeight: Int = 150.dp,
24 | val gravity: Int = Gravity.START
25 | ) : BaseData() {
26 |
27 | override var spanSize: Int = 2
28 |
29 | override var paddingLeft: Int = 0.dp
30 | override var paddingTop: Int = 0.dp
31 | override var paddingRight: Int = 0.dp
32 | override var paddingBottom: Int = 0.dp
33 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/MediaInfo2Data.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import com.su.mediabox.pluginapi.util.UIUtil.dp
4 |
5 | /**
6 | * 媒体信息样式2视图组件数据
7 | */
8 | data class MediaInfo2Data(
9 | val name: String,
10 | val coverUrl: String,
11 | val url: String,
12 | val episodeInfo: String,
13 | val desc: String,
14 | val tagList: List? = null,
15 | //val customData: List? = null
16 | ) : BaseData(){
17 | override var paddingTop: Int = 0.dp
18 | override var paddingBottom: Int = 0.dp
19 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/SimpleTextData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | /**
4 | * 简单文本视图组件数据
5 | */
6 | data class SimpleTextData(
7 | val text: String
8 | ) : TextData()
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/TagData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import android.graphics.Color
4 | import android.view.Gravity
5 |
6 | /**
7 | * 标签视图组件数据
8 | * @param tagColor 标签整体颜色,建议用[Color.parseColor]解析,默认null,即使用主题色
9 | */
10 | data class TagData(val name: String, val tagColor: Int? = null) : TextData() {
11 | override var fontColor: Int? = Color.WHITE
12 | override var fontSize = 11F
13 | override var gravity = Gravity.CENTER
14 |
15 | override var paddingLeft = 0
16 | override var paddingTop = 0
17 | override var paddingRight = 0
18 | override var paddingBottom = 0
19 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/TagFlowData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import com.su.mediabox.pluginapi.util.UIUtil.dp
4 |
5 | /**
6 | * 标签流视图组件数据
7 | */
8 | data class TagFlowData(val tagList: List) : BaseData() {
9 | override var paddingTop: Int = 0.dp
10 | override var paddingBottom: Int = 0.dp
11 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/TextData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | import android.graphics.Color
4 | import android.graphics.Typeface
5 | import android.view.Gravity
6 |
7 | /**
8 | * 文本视图组件数据基类
9 | */
10 | abstract class TextData : BaseData() {
11 | /**
12 | * 单位SP
13 | */
14 | open var fontSize: Float = 15F
15 |
16 | /**
17 | * 颜色值,建议用[Color.parseColor]解析,默认null,即使用主题色
18 | */
19 | open var fontColor: Int? = null
20 |
21 | /**
22 | * 取Typeface内 Style的值,如[Typeface.BOLD]
23 | */
24 | open var fontStyle: Int = 0
25 |
26 | /**
27 | * 取[android.view.Gravity]内的值
28 | */
29 | open var gravity: Int = Gravity.START
30 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/VideoPlayMedia.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | data class VideoPlayMedia(
4 | val title: String,
5 | val videoPlayUrl: String
6 | )
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/data/ViewPagerData.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.data
2 |
3 | /**
4 | * 多页面视图组件数据,类似ViewPager(2)
5 | * @param pages 推荐使用同一个实例,然后通过page控制加载内容
6 | * @param defaultPage 默认打开的页,默认0
7 | */
8 | //TODO 更多自定义属性
9 | data class ViewPagerData(
10 | val pageLoaders: List,
11 | val defaultPage: Int = 0
12 | ) : BaseData() {
13 | interface PageLoader {
14 |
15 | fun pageName(page: Int): String
16 |
17 | /**
18 | * 加载数据
19 | * @param page 页码(Tab的index),从0开始
20 | */
21 | suspend fun loadData(page: Int): List
22 | }
23 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/AppUtil.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util
2 |
3 | import android.content.Context
4 |
5 | object AppUtil {
6 |
7 | lateinit var appContext: Context
8 | private set
9 |
10 | /**
11 | * 由App初始化
12 | */
13 | fun init(applicationContext: Context) {
14 | appContext = applicationContext
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/PreferenceUtil.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util
2 |
3 | /**
4 | * 插件键对存储工具,由宿主初始化,插件直接调用即可,不需要自己实现
5 | *
6 | * 注意:该工具不能在单元测试中使用
7 | */
8 | lateinit var PluginPreferenceIns: PluginPreference
9 |
10 | interface PluginPreference {
11 | /**
12 | * 获取键值
13 | *
14 | * @param defaultValue 默认值
15 | * @param isVisual 可视化,如果为真则会显示在插件菜单上并可编辑。注意:是否可视化的键对是两个不同的键对
16 | */
17 | suspend fun get(key: String, defaultValue: T, isVisual: Boolean = true): T
18 |
19 | /**
20 | * 设置键值
21 | *
22 | * @param value 只能基本类型
23 | * @param isVisual 可视化,如果为真则会显示在插件菜单上并可编辑。注意:是否可视化的键对是两个不同的键对
24 | *
25 | * @return 是否成功持久化
26 | */
27 | suspend fun set(key: String, value: T, isVisual: Boolean = true): Boolean
28 |
29 | /**
30 | * 初始化键对,如果键对已存在则无效
31 | *
32 | * @param defaultValue 默认值
33 | */
34 | fun initKey(key: String, defaultValue: T, isVisual: Boolean = true)
35 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/TextUtil.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util
2 |
3 | import java.lang.StringBuilder
4 | import java.net.URLDecoder
5 | import java.net.URLEncoder
6 | import java.util.regex.Matcher
7 | import java.util.regex.Pattern
8 |
9 | object TextUtil {
10 |
11 | fun String.urlDecode() = URLDecoder.decode(this, "UTF-8")
12 |
13 | fun String.urlEncode() = URLEncoder.encode(this, "UTF-8")
14 |
15 | fun buildRouteActionUrl(action: String, vararg params: String): String {
16 | return StringBuilder(action.removeSuffix("/")).run {
17 | params.forEach {
18 | append("/")
19 | append(it.urlEncode())
20 | }
21 | toString()
22 | }
23 | }
24 |
25 | fun String.getSubString(s: String, e: String): List {
26 | val regex = "$s(.*?)$e"
27 | val p: Pattern = Pattern.compile(regex)
28 | val m: Matcher = p.matcher(this)
29 | val list: MutableList = ArrayList()
30 | while (m.find()) {
31 | list.add(m.group(1))
32 | }
33 | return list
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/UIUtil.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util
2 |
3 | import android.content.res.Resources
4 | import android.util.TypedValue
5 | import android.widget.Toast
6 |
7 | object UIUtil {
8 | fun CharSequence.toast(duration: Int = Toast.LENGTH_SHORT) {
9 | Toast.makeText(AppUtil.appContext, this, duration).show()
10 | }
11 |
12 | val Float.dp: Float
13 | get() = TypedValue.applyDimension(
14 | TypedValue.COMPLEX_UNIT_DIP,
15 | this,
16 | Resources.getSystem().displayMetrics
17 | )
18 |
19 | val Int.dp: Int
20 | get() = TypedValue.applyDimension(
21 | TypedValue.COMPLEX_UNIT_DIP,
22 | this.toFloat(),
23 | Resources.getSystem().displayMetrics
24 | ).toInt()
25 |
26 | val Float.sp: Float // [xxhdpi](360 -> 1080)
27 | get() = TypedValue.applyDimension(
28 | TypedValue.COMPLEX_UNIT_SP,
29 | this,
30 | Resources.getSystem().displayMetrics
31 | )
32 |
33 | val Int.sp: Int
34 | get() = TypedValue.applyDimension(
35 | TypedValue.COMPLEX_UNIT_SP,
36 | this.toFloat(),
37 | Resources.getSystem().displayMetrics
38 | ).toInt()
39 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/WebUtil.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Web工具,由宿主初始化,插件直接调用即可,不需要自己实现
7 | *
8 | * 注意:该工具不能在单元测试中使用
9 | */
10 | lateinit var WebUtilIns: WebUtil
11 |
12 | interface WebUtil {
13 |
14 | /**
15 | * 加载政策
16 | */
17 | interface LoadPolicy : Serializable {
18 | /**
19 | * 自定义UA
20 | */
21 | val userAgentString: String?
22 |
23 | /**
24 | * 自定义Headers
25 | */
26 | val headers: Map?
27 |
28 | /**
29 | * 加载超时。当超过超时时间后还没返回数据则会直接返回
30 | */
31 | val timeOut: Long
32 |
33 | /**
34 | * 在页面加载完成后执行的js代码,可用于主动加载资源,如让视频加载出来以拦截
35 | */
36 | val actionJs: String?
37 |
38 | val encoding: String
39 |
40 | /**
41 | * 每次加载是否清空环境
42 | */
43 | val isClearEnv: Boolean
44 |
45 | /**
46 | * 每次加载是否拦截加载无用资源,可加快加载速度
47 | */
48 | val isBlockRes: Boolean
49 | }
50 |
51 | /**
52 | * 默认加载政策,需要单独修改某项可通过by代理实现
53 | */
54 | object DefaultLoadPolicy : LoadPolicy {
55 | override val userAgentString: String? = null
56 | override val headers: Map? = null
57 | override val timeOut: Long = 8000L
58 | override val actionJs: String? = null
59 | override val encoding: String = "utf-8"
60 | override val isClearEnv: Boolean = true
61 | override val isBlockRes: Boolean = true
62 | }
63 |
64 | /**
65 | * 获取已渲染网页源码
66 | *
67 | * @param callBackRegex 回调正则。在检测到特定请求时返回结果。默认为空则在页面加载完成后自动回调(因为ajax等因素可能得到的源码不完整,另外注意超时)
68 | * @param actionJs 在页面加载完成后执行的js代码,可用于主动加载资源,如让视频加载出来以拦截
69 | * @param timeOut 加载超时。当超过超时时间后还没返回数据则会直接返回当前源码
70 | */
71 | @Deprecated("弃用,请使用带LoadPolicy的API")
72 | suspend fun getRenderedHtmlCode(
73 | url: String,
74 | callBackRegex: String = "",
75 | encoding: String = "utf-8",
76 | userAgentString: String? = null,
77 | actionJs: String? = null,
78 | timeOut: Long = 8000L
79 | ): String
80 |
81 | /**
82 | * 获取已渲染网页源码
83 | *
84 | * @param callBackRegex 回调正则。在检测到特定请求时返回结果。默认为空则在页面加载完成后自动回调(因为ajax等因素可能得到的源码不完整,另外注意超时)
85 | * @param actionJs 在页面加载完成后执行的js代码,可用于主动加载资源,如让视频加载出来以拦截
86 | * @param timeOut 加载超时。当超过超时时间后还没返回数据则会直接返回当前源码
87 | */
88 | suspend fun getRenderedHtmlCode(
89 | url: String,
90 | callBackRegex: String = "",
91 | loadPolicy: LoadPolicy = DefaultLoadPolicy
92 | ): String
93 |
94 | /**
95 | * 拦截资源
96 | *
97 | * @param regex 回调正则,在检测到特定请求时返回结果
98 | * @param actionJs 在页面加载完成后执行的js代码,可用于主动加载资源,如让视频加载出来以拦截
99 | * @param timeOut 加载超时。当超过超时时间后还没返回数据则会直接返回当前源码
100 | */
101 | @Deprecated("弃用,请使用带LoadPolicy的API")
102 | suspend fun interceptResource(
103 | url: String,
104 | regex: String,
105 | userAgentString: String? = null,
106 | actionJs: String? = null,
107 | timeOut: Long = 8000L
108 | ): String
109 |
110 | /**
111 | * 拦截资源
112 | *
113 | * @param regex 回调正则,在检测到特定请求时返回结果
114 | */
115 | suspend fun interceptResource(
116 | url: String,
117 | regex: String,
118 | loadPolicy: LoadPolicy = DefaultLoadPolicy
119 | ): String
120 |
121 | /**
122 | * 拦截Blob数据
123 | *
124 | * @param regex 回调正则,在检测到特定Blob数据符合时返回结果
125 | * @param actionJs 在页面加载完成后执行的js代码,可用于主动加载资源,如让视频加载出来以拦截
126 | * @param timeOut 加载超时。当超过超时时间后还没返回数据则会直接返回当前源码
127 | */
128 | @Deprecated("弃用,请使用带LoadPolicy的API")
129 | suspend fun interceptBlob(
130 | url: String,
131 | regex: String,
132 | userAgentString: String? = null,
133 | actionJs: String? = null,
134 | timeOut: Long = 8000L
135 | ): String
136 |
137 | /**
138 | * 拦截Blob数据
139 | *
140 | * @param regex 回调正则,在检测到特定Blob数据符合时返回结果
141 | */
142 | suspend fun interceptBlob(
143 | url: String,
144 | regex: String,
145 | loadPolicy: LoadPolicy = DefaultLoadPolicy
146 | ): String
147 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/danmaku/AnimeDanmakuParser.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util.danmaku
2 |
3 | import android.graphics.Color
4 | import com.kuaishou.akdanmaku.data.DanmakuItemData
5 | import org.json.JSONArray
6 | import org.json.JSONException
7 | import org.json.JSONObject
8 | import java.util.*
9 | import kotlin.collections.ArrayList
10 |
11 | /**
12 | * 辅助解析弹幕
13 | *
14 | * 可能需要重新设计
15 | */
16 | class AnimeDanmakuParser(private var data: String) {
17 |
18 | fun parse(): List {
19 | if (data.isBlank()) return ArrayList()
20 | val jsonArray: JSONArray
21 | JSONObject(data).apply {
22 | jsonArray = getJSONArray("danmuku")
23 | }
24 | val dataList: MutableList = ArrayList(jsonArray.length())
25 | for (i in 0 until jsonArray.length()) {
26 | try {
27 | val array = jsonArray.getJSONArray(i)
28 | val content = array.getString(4)
29 | var textSize = 27
30 | if (array.length() >= 8) {
31 | textSize = array.getString(7).replace("px", "").toInt()
32 | }
33 | dataList.add(
34 | DanmakuItemData(
35 | content = content,
36 | danmakuId = i.toLong(),
37 | textSize = textSize,
38 | textColor = getColor(array.getString(2)),
39 | position = (array.getDouble(0) * 1000).toLong(),
40 | mode = getType(array.getString(1))
41 | )
42 | )
43 | } catch (e: JSONException) {
44 | e.printStackTrace()
45 | } catch (e: NumberFormatException) {
46 | e.printStackTrace()
47 | }
48 | }
49 | return dataList
50 | }
51 |
52 | companion object {
53 | fun getColor(s: String): Int {
54 | val strColor = s.toLowerCase(Locale.ROOT)
55 | try {
56 | if (strColor.startsWith("#")) {
57 | Color.parseColor(s)
58 | } else if (strColor.startsWith("rgb")) {
59 | val rgbArray = strColor.replace("rgb(", "")
60 | .replace(")", "").split(",")
61 | if (rgbArray.size == 3) Color.rgb(
62 | rgbArray[0].trim().toInt(),
63 | rgbArray[1].trim().toInt(),
64 | rgbArray[2].trim().toInt()
65 | )
66 | }
67 | } catch (e: IllegalArgumentException) {
68 | e.printStackTrace()
69 | }
70 | return Color.WHITE
71 | }
72 | }
73 |
74 | private fun getType(s: String): Int {
75 | return when (s) {
76 | "top" -> DanmakuItemData.DANMAKU_MODE_CENTER_TOP
77 | else -> DanmakuItemData.DANMAKU_MODE_ROLLING
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/pluginApi/src/main/java/com/su/mediabox/pluginapi/util/danmaku/BiliBiliDanmakuParser.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi.util.danmaku
2 |
3 | import com.kuaishou.akdanmaku.data.DanmakuItemData
4 | import org.xml.sax.Attributes
5 | import org.xml.sax.InputSource
6 | import org.xml.sax.SAXException
7 | import org.xml.sax.helpers.DefaultHandler
8 | import org.xml.sax.helpers.XMLReaderFactory
9 | import java.io.IOException
10 | import java.lang.NumberFormatException
11 | import java.util.*
12 | import kotlin.collections.ArrayList
13 |
14 | /**
15 | * 辅助解析弹幕
16 | *
17 | * 可能需要重新设计
18 | */
19 | class BiliBiliDanmakuParser(private var data: String) {
20 |
21 | init {
22 | System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver")
23 | }
24 |
25 | fun parse(): List {
26 | if (data.isBlank()) return ArrayList()
27 | try {
28 | val xmlReader = XMLReaderFactory.createXMLReader()
29 | val contentHandler = XmlContentHandler()
30 | xmlReader.contentHandler = contentHandler
31 | xmlReader.parse(InputSource(data.byteInputStream()))
32 | return contentHandler.result
33 | } catch (e: SAXException) {
34 | e.printStackTrace()
35 | } catch (e: IOException) {
36 | e.printStackTrace()
37 | }
38 | return ArrayList()
39 | }
40 |
41 | class XmlContentHandler : DefaultHandler() {
42 | lateinit var result: MutableList
43 | var item: DanmakuItemData? = null
44 | var completed = false
45 |
46 | override fun startDocument() {
47 | result = ArrayList()
48 | }
49 |
50 | override fun endDocument() {
51 | completed = true
52 | }
53 |
54 | override fun startElement(
55 | uri: String,
56 | localName: String,
57 | qName: String,
58 | attributes: Attributes
59 | ) {
60 | var tagName = if (localName.isNotEmpty()) localName else qName
61 | tagName = tagName.toLowerCase(Locale.getDefault()).trim { it <= ' ' }
62 | if (tagName == "d") {
63 | // 我从未见过如此厚颜无耻之猴
64 | // 0:时间(弹幕出现时间)
65 | // 1:类型(1从右至左滚动弹幕|6从左至右滚动弹幕|5顶端固定弹幕|4底端固定弹幕|7高级弹幕|8脚本弹幕)
66 | // 2:字号
67 | // 3:颜色
68 | // 4:时间戳 ?
69 | // 5:弹幕池id
70 | // 6:用户hash
71 | // 7:弹幕id
72 | val pValue = attributes.getValue("p")
73 | // parse p value to danmaku
74 | val values = pValue.split(",").toTypedArray()
75 |
76 | if (values.isNotEmpty()) {
77 | try {
78 | item = DanmakuItemData(
79 | content = "",
80 | danmakuId = values[7].toLong(),
81 | textSize = getTextSize(values[2].toInt()).toInt(),
82 | textColor = values[3].toInt(),
83 | position = (values[0].toFloat() * 1000).toLong(),
84 | mode = getType(values[1].toInt())
85 | )
86 | } catch (e: NumberFormatException) {
87 | e.printStackTrace()
88 | }
89 | }
90 | }
91 | }
92 |
93 | override fun endElement(uri: String, localName: String, qName: String) {
94 | item?.let {
95 | val tagName = if (localName.isNotEmpty()) localName else qName
96 | if (tagName.equals("d", ignoreCase = true)) {
97 | result.add(it)
98 | }
99 | item = null
100 | }
101 | }
102 |
103 | override fun characters(ch: CharArray, start: Int, length: Int) {
104 | item?.let {
105 | item = DanmakuItemData(
106 | content = decodeXmlString(String(ch, start, length)),
107 | danmakuId = it.danmakuId,
108 | textSize = it.textSize,
109 | textColor = it.textColor,
110 | position = it.position,
111 | mode = it.mode
112 | )
113 | }
114 | }
115 |
116 | private fun decodeXmlString(s: String): String {
117 | var result = s
118 | if (result.contains("&")) {
119 | result = result.replace("&", "&")
120 | }
121 | if (result.contains(""")) {
122 | result = result.replace(""", "\"")
123 | }
124 | if (result.contains(">")) {
125 | result = result.replace(">", ">")
126 | }
127 | if (result.contains("<")) {
128 | result = result.replace("<", "<")
129 | }
130 | return result
131 | }
132 |
133 | companion object {
134 | /**
135 | * 获取真实的字体大小px
136 | * 弹幕库限制字体最小12f最大25f
137 | * @param n 12非常小,16特小,18小,25中,36大,45很大,64特别大
138 | * @return 以px为单位的字体大小
139 | */
140 | private fun getTextSize(n: Int): Float {
141 | return when (n) {
142 | 12 -> 12f
143 | 16 -> 14f
144 | 18 -> 17f
145 | 25 -> 19f
146 | 36 -> 21f
147 | 45 -> 23f
148 | 64 -> 25f
149 | else -> 19f
150 | }
151 | }
152 |
153 | private fun getType(s: Int): Int {
154 | // 类型(1从右至左滚动弹幕|6从左至右滚动弹幕|5顶端固定弹幕|4底端固定弹幕|7高级弹幕|8脚本弹幕)
155 | return when (s) {
156 | 1 -> DanmakuItemData.DANMAKU_MODE_ROLLING
157 | 4 -> DanmakuItemData.DANMAKU_MODE_CENTER_BOTTOM
158 | 5 -> DanmakuItemData.DANMAKU_MODE_CENTER_TOP
159 | else -> DanmakuItemData.DANMAKU_MODE_ROLLING
160 | }
161 | }
162 | }
163 | }
164 | }
--------------------------------------------------------------------------------
/pluginApi/src/test/java/com/su/mediabox/pluginapi/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.su.mediabox.pluginapi
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "MediaBoxPlugin"
16 | include(":pluginApi")
17 |
--------------------------------------------------------------------------------