Compare commits
110 Commits
Author | SHA1 | Date |
---|---|---|
Ivan Agosto | 3141500c53 | |
Ivan Agosto | f86d66fdab | |
Ivan Agosto | de2f130826 | |
Ivan Agosto | 7d865cd181 | |
Ivan Agosto | c4c5737344 | |
Ivan Agosto | ff995e383d | |
Ivan Agosto | d3466f9cce | |
Ivan Agosto | f0fbd02cf4 | |
Ivan Agosto | 3364f60d32 | |
Ivan Agosto | 0f8c3a7126 | |
Ivan Agosto | d6aeadc489 | |
Ivan Agosto | 826bb79431 | |
Ivan Agosto | 2484406cc7 | |
Ivan Agosto | 0705d6dd80 | |
Ivan Agosto | dd54d214ff | |
Ivan Agosto | 48738f100a | |
Ivan Agosto | b6e1a979ca | |
Ivan Agosto | 96d8ae19c6 | |
Ivan Agosto | 8856984dc3 | |
Ivan Agosto | 2ffb7daede | |
Ivan Agosto | f0b5ba10e8 | |
Ivan Agosto | 4d2644674e | |
Ivan Agosto | 6a8d3baccb | |
Ivan Agosto | ac191c04d3 | |
Ivan Agosto | 15aaae2fa1 | |
Ivan Agosto | 42be7c4f77 | |
Ivan Agosto | e022fe5e96 | |
Ivan Agosto | 1f90e21f68 | |
Ivan Agosto | c104bf32da | |
Ivan Agosto | a3cd0b92ed | |
Ivan Agosto | 2de1bde4cd | |
Ivan Agosto | 6f0b97dbc4 | |
Ivan Agosto | 2fcd3b21f8 | |
Ivan Agosto | eeb20f1f9d | |
Ivan Agosto | 0d9bd5410a | |
Ivan Agosto | 40b193a816 | |
Ivan Agosto | c500ba9aa4 | |
Ivan Agosto | 35aa0fcea1 | |
Ivan Agosto | ba0a298ea9 | |
Ivan Agosto | 815bafaee1 | |
Ivan Agosto | ef5c97dce1 | |
Ivan Agosto | b6ef9b8aca | |
Ivan Agosto | bf35a75877 | |
Ivan Agosto | 65e061fd25 | |
Ivan Agosto | ffbc491f4c | |
Ivan Agosto | da1d3e301e | |
Ivan Agosto | 6784b5ebbe | |
Ivan Agosto | e70108a7ae | |
Ivan Agosto | 2b7d92ac37 | |
Ivan Agosto | 4d337074fb | |
Ivan Agosto | cd27342c74 | |
john j | ab1bb48dcc | |
Ivan Agosto | 0a648ef4bb | |
Igor Calì | 3e41ddd367 | |
Ivan Agosto | 9c90983ff4 | |
Poussinou | dad366eebf | |
Ivan Agosto | 14640a825f | |
Ivan Agosto | 8fbfd57f78 | |
Ivan Agosto | a66acfbcea | |
Ivan Agosto | d410be7d4e | |
Ivan Agosto | a26efeba63 | |
Ivan Agosto | 49b7841a97 | |
Ivan Agosto | 7d6f364223 | |
Ivan Agosto | 390b1a7add | |
Ivan Agosto | 904319674d | |
Ivan Agosto | c26ab0b8a2 | |
Ivan Agosto | 9167977c7c | |
Ivan Agosto | 8394484eb0 | |
Ivan Agosto | 4946a55215 | |
Ivan Agosto | 9638468191 | |
ivan agosto | b763ed2088 | |
ivan agosto | 5c966fe81c | |
Ivan Agosto | 23dfb98a67 | |
ivan agosto | 22a2772a3c | |
ivan agosto | abcf2f0e6e | |
ivan agosto | 398265c6ed | |
ivan agosto | 743c3147c1 | |
ivan agosto | d360a1849e | |
ivan agosto | 90f2ab6e7d | |
ivan agosto | d680eb77b8 | |
ivan agosto | 90aac608be | |
ivan agosto | 2abdcb8375 | |
ivan agosto | a6f3a4b6b4 | |
Ivan Agosto | d15ad1006e | |
ivan agosto | fb98d96f66 | |
ivan agosto | c1b746da80 | |
ivan agosto | 130ece5982 | |
ivan agosto | 999bd4ad9d | |
ivan agosto | 4347831907 | |
ivan agosto | d783b4887d | |
ivan agosto | 329813d1b3 | |
ivan agosto | 700559e28f | |
ivan agosto | c07c15c766 | |
ivan agosto | 305acc87e7 | |
Ivan Agosto | a626bc85bb | |
ivan agosto | 66428e0c34 | |
ivan agosto | 76a1d2f4b3 | |
ivan agosto | e2d1ffdb15 | |
ivan agosto | 97c85c7bba | |
ivan agosto | 7930ffa582 | |
ivan agosto | abec98d172 | |
ivan agosto | e74e39fe28 | |
ivan agosto | 176e580f1f | |
ivan agosto | ab69d59f9a | |
ivan agosto | 5cf806577a | |
ivan agosto | 9bf8ea0483 | |
ivan agosto | 6413bb078d | |
ivan agosto | d918824d74 | |
ivan agosto | 7d60dc8c0f | |
ivan agosto | 4655d9ed86 |
|
@ -0,0 +1,2 @@
|
||||||
|
[*.{kt,kts}]
|
||||||
|
ktlint_code_style = intellij_idea
|
|
@ -32,3 +32,9 @@ proguard/
|
||||||
captures/
|
captures/
|
||||||
|
|
||||||
\.idea/
|
\.idea/
|
||||||
|
|
||||||
|
# iml Files
|
||||||
|
*.iml
|
||||||
|
app/app.iml
|
||||||
|
|
||||||
|
app/release/
|
||||||
|
|
64
README.md
64
README.md
|
@ -1,52 +1,76 @@
|
||||||
# P2Play
|
# P2Play
|
||||||
P2Play is an Android Application for Peertube.
|
P2Play is an unoficial Peertube android application.
|
||||||
|
|
||||||
[What is Peertube?](https://github.com/Chocobozzz/PeerTube/)
|
[What is Peertube?](https://github.com/Chocobozzz/PeerTube/)
|
||||||
|
|
||||||
## Documentation
|
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
Comming soon!
|
alt="Get it on F-Droid"
|
||||||
|
height="80">](https://f-droid.org/packages/org.libre.agosto.p2play/)
|
||||||
|
|
||||||
## Realeases
|
## Screenshots
|
||||||
|
|
||||||
|
<img src="metadata/en-US/images/phoneScreenshots/1.jpg" alt="Screenshot" width="14%"/>
|
||||||
|
<img src="metadata/en-US/images/phoneScreenshots/2.jpg" alt="Screenshot" width="14%"/>
|
||||||
|
<img src="metadata/en-US/images/phoneScreenshots/3.jpg" alt="Screenshot" width="14%"/>
|
||||||
|
<img src="metadata/en-US/images/phoneScreenshots/4.jpg" alt="Screenshot" width="14%"/>
|
||||||
|
<img src="metadata/en-US/images/phoneScreenshots/5.jpg" alt="Screenshot" width="14%">/
|
||||||
|
<img src="metadata/en-US/images/phoneScreenshots/6.jpg" alt="Screenshot" width="14%"/>
|
||||||
|
|
||||||
|
## Realeases (apk's)
|
||||||
|
|
||||||
[All realeases are here](https://gitlab.com/agosto182/p2play/tags)
|
[All realeases are here](https://gitlab.com/agosto182/p2play/tags)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Show recent, popular and local list of videos.
|
- Show recent, popular and local list of videos.
|
||||||
- Reproduce videos (very simple)
|
- Reproduce videos
|
||||||
- Login and register in your instance
|
- Login and register in your instance
|
||||||
- Pull to refresh
|
|
||||||
- Show uploaded videos
|
- Show uploaded videos
|
||||||
- Subscribe to accounts
|
- Subscribe to accounts
|
||||||
- Show your subscripcion videos
|
- Show your subscripcion videos
|
||||||
|
- Show your history
|
||||||
- Rate videos
|
- Rate videos
|
||||||
|
|
||||||
## What to do? (in next version)
|
|
||||||
|
|
||||||
- Search videos
|
|
||||||
- Show and make commentaries
|
- Show and make commentaries
|
||||||
- Share videos
|
|
||||||
- View Peertube profiles
|
|
||||||
- Splash screen
|
- Splash screen
|
||||||
|
- Search videos
|
||||||
|
- Infinite scroll
|
||||||
|
- Share videos
|
||||||
|
- Report videos
|
||||||
|
- Peertube profiles
|
||||||
|
- Day/Night theme
|
||||||
|
|
||||||
|
## What to do? (on incomming updates)
|
||||||
|
|
||||||
|
- Playlists
|
||||||
|
- Manage subscriptions
|
||||||
|
- Better commentaries
|
||||||
|
- Account channels view
|
||||||
|
- Notifications
|
||||||
|
|
||||||
## Demostrations
|
## Demostrations
|
||||||
Demostration P2Play Beta 0.1: [https://peertube.video/videos/watch/2eb7b953-0b1b-4019-9300-817539f5f4e8](https://peertube.video/videos/watch/2eb7b953-0b1b-4019-9300-817539f5f4e8)
|
|
||||||
|
|
||||||
[Spanish] Demostracion P2Play Beta 0.1: [https://peertube.video/videos/watch/d6a7da26-d3dd-43aa-ad5c-7d032603c848](https://peertube.video/videos/watch/d6a7da26-d3dd-43aa-ad5c-7d032603c848)
|
P2play beta 0.6.0: https://fediverse.tv/w/suFPkm9zJstSrQU7WmVARv
|
||||||
|
|
||||||
|
**Dead links**
|
||||||
|
|
||||||
|
~~Demostration P2play Beta 0.2: https://peertube.video/videos/watch/730fa68e-32c4-4cdb-a7bb-1a819c9d3a46~~
|
||||||
|
|
||||||
|
~~Demostration P2Play Beta 0.1: https://peertube.video/videos/watch/2eb7b953-0b1b-4019-9300-817539f5f4e8~~
|
||||||
|
|
||||||
|
~~[Spanish] Demostracion P2Play Beta 0.1: https://peertube.video/videos/watch/d6a7da26-d3dd-43aa-ad5c-7d032603c848~~
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
You can follow our accounts for get news and contact with the developers.
|
You can follow our accounts to get news and contact with the developer(s).
|
||||||
|
|
||||||
- GNU Social: [https://gnusocial.ml/p2play](https://gnusocial.ml/p2play)
|
- WriteFreely (ActivityPub): https://personaljournal.ca/p2play/
|
||||||
- Peertube Channel: [https://peertube.video/video-channels/90df4e5f-c834-4720-a5d7-c9faa0af0af5/videos](https://peertube.video/video-channels/90df4e5f-c834-4720-a5d7-c9faa0af0af5/videos)
|
|
||||||
|
|
||||||
## About
|
## About
|
||||||
P2Play is made in Android Studio with Kotlin code.
|
P2Play is made in Android Studio with Kotlin languaje.
|
||||||
|
|
||||||
<img src="https://weblizar.com/blog/wp-content/uploads/2017/11/Kotlin-A-New-Programming-Platform-For-Android-Developers.png" width="200px">
|
![kotlin](https://weblizar.com/blog/wp-content/uploads/2017/11/Kotlin-A-New-Programming-Platform-For-Android-Developers.png)
|
||||||
|
|
||||||
### Developers
|
### Developers
|
||||||
- Ivan Agosto: [https://gnusocial.ml/agosto182](https://gnusocial.ml/agosto182)
|
- Ivan Agosto: [https://mast.lat/@agosto182](https://mast.lat/@agosto182)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
|
199
app/app.iml
199
app/app.iml
|
@ -1,199 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
|
||||||
<component name="FacetManager">
|
|
||||||
<facet type="android-gradle" name="Android-Gradle">
|
|
||||||
<configuration>
|
|
||||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
<facet type="android" name="Android">
|
|
||||||
<configuration>
|
|
||||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
|
||||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
|
||||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
|
||||||
<afterSyncTasks>
|
|
||||||
<task>generateDebugSources</task>
|
|
||||||
</afterSyncTasks>
|
|
||||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
|
||||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
|
||||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
|
||||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
|
||||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
<facet type="kotlin-language" name="Kotlin">
|
|
||||||
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
|
|
||||||
<compilerSettings />
|
|
||||||
<compilerArguments>
|
|
||||||
<option name="destination" value="$MODULE_DIR$/build/tmp/kotlin-classes/debug" />
|
|
||||||
<option name="noStdlib" value="true" />
|
|
||||||
<option name="noReflect" value="true" />
|
|
||||||
<option name="moduleName" value="app_debug" />
|
|
||||||
<option name="jvmTarget" value="1.8" />
|
|
||||||
<option name="addCompilerBuiltIns" value="true" />
|
|
||||||
<option name="loadBuiltInsFromDependencies" value="true" />
|
|
||||||
<option name="languageVersion" value="1.2" />
|
|
||||||
<option name="apiVersion" value="1.2" />
|
|
||||||
<option name="pluginOptions">
|
|
||||||
<array>
|
|
||||||
<option value="plugin:org.jetbrains.kotlin.android:experimental=false" />
|
|
||||||
<option value="plugin:org.jetbrains.kotlin.android:enabled=true" />
|
|
||||||
<option value="plugin:org.jetbrains.kotlin.android:defaultCacheImplementation=hashMap" />
|
|
||||||
</array>
|
|
||||||
</option>
|
|
||||||
<option name="pluginClasspaths">
|
|
||||||
<array>
|
|
||||||
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-android-extensions/1.2.51/1755c607e5fabf4ba949ef626c73fc7421d35123/kotlin-android-extensions-1.2.51.jar" />
|
|
||||||
</array>
|
|
||||||
</option>
|
|
||||||
</compilerArguments>
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
</component>
|
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6">
|
|
||||||
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes" />
|
|
||||||
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" />
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/not_namespaced_r_class_sources/debugAndroidTest/processDebugAndroidTestResources/r" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/apk_list" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/build-info" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-libraries" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-manifest" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/checkDebugClasspath" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/compatible_screen_manifest" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-apk" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-resources" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_run_merged_manifests" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_run_split_apk_resources" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javac" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint_jar" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged_assets" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged_manifests" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/prebuild" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/processed_res" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/resources" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shader_assets" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/split-apk" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/split_list" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/kotlin" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="jdk" jdkName="Android API 27 Platform" jdkType="Android SDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:transition-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.android.support.test:runner-1.0.2" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: android.arch.lifecycle:common:1.1.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.51@jar" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.android.support:support-annotations:27.1.1@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:animated-vector-drawable-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.2.51@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: android.arch.lifecycle:viewmodel-1.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-v4-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-compat-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:recyclerview-v7-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.squareup:javawriter:2.1.1@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-media-compat-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-vector-drawable-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-annotations:27.1.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support.constraint:constraint-layout-1.1.2" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-core-utils-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-core-ui-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.google.code.findbugs:jsr305:2.0.1@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.14.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.android.support.test.espresso:espresso-core-3.0.2" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: javax.inject:javax.inject:1@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:support-fragment-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.12@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.2.51@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:design-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: android.arch.core:runtime-1.1.0" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.3@jar" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.android.support.test:monitor-1.0.2" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:appcompat-v7-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: com.android.support.test.espresso:espresso-idling-resource-3.0.2" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:3.10.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support.constraint:constraint-layout-solver:1.1.2@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.android.support:exifinterface-27.1.0" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: android.arch.lifecycle:livedata-core-1.1.0" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-library:1.3@jar" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-integration:1.3@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.squareup.picasso:picasso-2.71828" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: android.arch.core:common:1.1.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" scope="TEST" name="Gradle: net.sf.kxml:kxml2:2.3.0@jar" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: android.arch.lifecycle:runtime-1.1.0" level="project" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
|
@ -1,18 +1,19 @@
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
|
|
||||||
apply plugin: 'kotlin-android'
|
plugins {
|
||||||
|
id "com.android.application"
|
||||||
apply plugin: 'kotlin-android-extensions'
|
id "kotlin-android"
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.libre.agosto.p2play"
|
applicationId "org.libre.agosto.p2play"
|
||||||
minSdkVersion 21
|
compileSdk 34
|
||||||
targetSdkVersion 27
|
minSdkVersion 26
|
||||||
versionCode 2
|
targetSdkVersion 32
|
||||||
versionName "0.1.5"
|
versionCode 10
|
||||||
|
versionName "0.7.0"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
vectorDrawables.useSupportLibrary = true
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
@ -20,22 +21,38 @@ android {
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildToolsVersion '28.0.3'
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_6
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
targetCompatibility JavaVersion.VERSION_1_6
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
namespace 'org.libre.agosto.p2play'
|
||||||
|
lint {
|
||||||
|
abortOnError false
|
||||||
|
checkReleaseBuilds false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation 'com.android.support:appcompat-v7:27.1.0'
|
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
|
||||||
implementation 'com.android.support:support-v4:27.1.0'
|
|
||||||
implementation 'com.android.support:design:27.1.0'
|
|
||||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
testImplementation 'junit:junit:4.12'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
|
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
|
implementation 'com.google.android.material:material:1.12.0'
|
||||||
|
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||||
|
implementation 'androidx.activity:activity:1.8.0'
|
||||||
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
implementation 'androidx.media3:media3-exoplayer:1.3.1'
|
||||||
|
implementation 'androidx.media3:media3-exoplayer-dash:1.3.1'
|
||||||
|
implementation 'androidx.media3:media3-ui:1.3.1'
|
||||||
|
implementation 'androidx.media3:media3-exoplayer-hls:1.3.1'
|
||||||
|
implementation "androidx.media3:media3-session:1.3.1"
|
||||||
|
implementation 'com.google.code.gson:gson:2.8.8'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package org.libre.agosto.p2play
|
|
||||||
|
|
||||||
import android.support.test.InstrumentationRegistry
|
|
||||||
import android.support.test.runner.AndroidJUnit4
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
fun useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
val appContext = InstrumentationRegistry.getTargetContext()
|
|
||||||
assertEquals("org.libre.agosto.p2play", appContext.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +1,40 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="org.libre.agosto.p2play">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_p2play"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_p2play"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/P2playTheme"
|
android:theme="@style/Theme.P2play">
|
||||||
android:hardwareAccelerated="true">
|
|
||||||
<activity android:name=".HostActivity">
|
<activity
|
||||||
|
android:name=".AccountActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@style/Theme.P2play.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".SettingsActivity2"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="@string/title_activity_settings"
|
||||||
|
android:theme="@style/Theme.P2play">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".MainActivity" />
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ChannelActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@style/Theme.P2play.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".SplashActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@style/Theme.P2play.NoActionBar">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
@ -21,15 +42,37 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".HostActivity"
|
||||||
android:theme="@style/P2playTheme.NoActionBar" />
|
android:exported="false"
|
||||||
<activity android:name=".ReproductorActivity" />
|
android:theme="@style/Theme.P2play.NoActionBar" />
|
||||||
<activity android:name=".LoginActivity" />
|
|
||||||
<activity android:name=".RegisterActivity" />
|
|
||||||
<activity android:name=".AboutActivity" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".SettingsActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/title_activity_settings"></activity>
|
android:exported="false"
|
||||||
|
android:theme="@style/Theme.P2play.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".ReproductorActivity"
|
||||||
|
android:configChanges="orientation|screenSize"
|
||||||
|
android:exported="false"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
|
android:theme="@style/Theme.P2play.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".LoginActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".RegisterActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".AboutActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".services.PlaybackService"
|
||||||
|
android:exported="true"
|
||||||
|
android:foregroundServiceType="mediaPlayback">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="androidx.media3.session.MediaSessionService" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -1,16 +1,19 @@
|
||||||
package org.libre.agosto.p2play
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.method.LinkMovementMethod
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import kotlinx.android.synthetic.main.activity_about.*
|
import org.libre.agosto.p2play.databinding.ActivityAboutBinding
|
||||||
|
|
||||||
class AboutActivity : AppCompatActivity() {
|
class AboutActivity : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_about)
|
val binding = ActivityAboutBinding.inflate(layoutInflater)
|
||||||
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
|
|
||||||
aboutUrl.text = "https://"+ManagerSingleton.url+"/about/instance"
|
binding.aboutUrl.text = "https://" + ManagerSingleton.url + "/about/instance"
|
||||||
|
|
||||||
|
binding.aboutLabel.text = binding.aboutLabel.text.toString() + " " + this.packageManager.getPackageInfo(this.packageName, 0).versionName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.libre.agosto.p2play.ajax.Accounts
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityAccountBinding
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityMainBinding
|
||||||
|
import org.libre.agosto.p2play.fragmentAdapters.AccountAdapter
|
||||||
|
import org.libre.agosto.p2play.models.AccountModel
|
||||||
|
|
||||||
|
class AccountActivity : AppCompatActivity() {
|
||||||
|
private lateinit var binding: ActivityAccountBinding
|
||||||
|
private val client = Accounts()
|
||||||
|
private lateinit var accountId: String
|
||||||
|
private lateinit var adapter: AccountAdapter
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivityAccountBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
|
accountId = this.intent.extras?.getString("accountId")!!
|
||||||
|
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
binding.toolbar.setNavigationOnClickListener {
|
||||||
|
onBackPressedDispatcher.onBackPressed()
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter = AccountAdapter(supportFragmentManager, lifecycle)
|
||||||
|
binding.viewpager.adapter = adapter
|
||||||
|
|
||||||
|
adapter.accountId = accountId
|
||||||
|
|
||||||
|
TabLayoutMediator(binding.tabs, binding.viewpager, false, false) { tab, position ->
|
||||||
|
tab.text = adapter.get(position)
|
||||||
|
}.attach()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
getChannelInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getChannelInfo() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
val account = client.get(accountId)
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
binding.collapsingToolbar.title = account.displayName
|
||||||
|
adapter.account = account
|
||||||
|
if (account.avatars.size > 0) {
|
||||||
|
Picasso.get().load("https://${ManagerSingleton.url}${account.avatars.last().path}").into(binding.profileImage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,90 +0,0 @@
|
||||||
package org.libre.agosto.p2play
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.preference.PreferenceActivity
|
|
||||||
import android.support.annotation.LayoutRes
|
|
||||||
import android.support.v7.app.ActionBar
|
|
||||||
import android.support.v7.app.AppCompatDelegate
|
|
||||||
import android.support.v7.widget.Toolbar
|
|
||||||
import android.view.MenuInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A [android.preference.PreferenceActivity] which implements and proxies the necessary calls
|
|
||||||
* to be used with AppCompat.
|
|
||||||
*/
|
|
||||||
abstract class AppCompatPreferenceActivity : PreferenceActivity() {
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
delegate.installViewFactory()
|
|
||||||
delegate.onCreate(savedInstanceState)
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onPostCreate(savedInstanceState)
|
|
||||||
delegate.onPostCreate(savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
val supportActionBar: ActionBar?
|
|
||||||
get() = delegate.supportActionBar
|
|
||||||
|
|
||||||
fun setSupportActionBar(toolbar: Toolbar?) {
|
|
||||||
delegate.setSupportActionBar(toolbar)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getMenuInflater(): MenuInflater {
|
|
||||||
return delegate.menuInflater
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setContentView(@LayoutRes layoutResID: Int) {
|
|
||||||
delegate.setContentView(layoutResID)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setContentView(view: View) {
|
|
||||||
delegate.setContentView(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setContentView(view: View, params: ViewGroup.LayoutParams) {
|
|
||||||
delegate.setContentView(view, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun addContentView(view: View, params: ViewGroup.LayoutParams) {
|
|
||||||
delegate.addContentView(view, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPostResume() {
|
|
||||||
super.onPostResume()
|
|
||||||
delegate.onPostResume()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTitleChanged(title: CharSequence, color: Int) {
|
|
||||||
super.onTitleChanged(title, color)
|
|
||||||
delegate.setTitle(title)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
||||||
super.onConfigurationChanged(newConfig)
|
|
||||||
delegate.onConfigurationChanged(newConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
delegate.onStop()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
delegate.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun invalidateOptionsMenu() {
|
|
||||||
delegate.invalidateOptionsMenu()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val delegate: AppCompatDelegate by lazy {
|
|
||||||
AppCompatDelegate.create(this, null)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
import org.libre.agosto.p2play.adapters.VideosAdapter
|
||||||
|
import org.libre.agosto.p2play.ajax.Actions
|
||||||
|
import org.libre.agosto.p2play.ajax.Channels
|
||||||
|
import org.libre.agosto.p2play.ajax.Videos
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityChannelBinding
|
||||||
|
import org.libre.agosto.p2play.helpers.getViewManager
|
||||||
|
import org.libre.agosto.p2play.models.ChannelModel
|
||||||
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
class ChannelActivity : AppCompatActivity() {
|
||||||
|
private lateinit var channelId: String
|
||||||
|
private lateinit var channel: ChannelModel
|
||||||
|
private var isSubcribed: Boolean = false
|
||||||
|
private val channelService = Channels()
|
||||||
|
private val videosService = Videos()
|
||||||
|
private val actionsService = Actions()
|
||||||
|
|
||||||
|
private lateinit var recyclerView: RecyclerView
|
||||||
|
private lateinit var viewAdapter: RecyclerView.Adapter<VideosAdapter.ViewHolder>
|
||||||
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityChannelBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivityChannelBinding.inflate(layoutInflater)
|
||||||
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
|
|
||||||
|
channelId = this.intent.extras?.getString("channel")!!
|
||||||
|
|
||||||
|
viewManager = getViewManager(this, resources)
|
||||||
|
|
||||||
|
binding.subcriptionBtn.setOnClickListener {
|
||||||
|
subscribeAction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
getChannel()
|
||||||
|
getSubscription()
|
||||||
|
getVideos()
|
||||||
|
|
||||||
|
if (ManagerSingleton.user.status == 1) {
|
||||||
|
binding.subcriptionBtn.visibility = View.VISIBLE
|
||||||
|
getSubscription()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getChannel() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
channel = channelService.getChannelInfo(channelId)
|
||||||
|
runOnUiThread {
|
||||||
|
binding.usernameProfile.text = channel.name
|
||||||
|
binding.hostTxt.text = channel.host
|
||||||
|
binding.subcriptionsTxt.text = channel.followers.toString()
|
||||||
|
if (channel.channelImg != "") {
|
||||||
|
Picasso.get().load("https://${ManagerSingleton.url}${channel.channelImg}").into(binding.channelImg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribe() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = actionsService.subscribe(ManagerSingleton.token.token, channel.getAccount())
|
||||||
|
runOnUiThread {
|
||||||
|
if (res == 1) {
|
||||||
|
binding.subcriptionBtn.text = getString(R.string.unSubscribeBtn)
|
||||||
|
ManagerSingleton.toast(getString(R.string.subscribeMsg), this)
|
||||||
|
getSubscription()
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(getString(R.string.errorMsg), this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unSubscribe() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = actionsService.unSubscribe(ManagerSingleton.token.token, channel.getAccount())
|
||||||
|
runOnUiThread {
|
||||||
|
if (res == 1) {
|
||||||
|
binding.subcriptionBtn.text = getString(R.string.subscribeBtn)
|
||||||
|
ManagerSingleton.toast(getString(R.string.unSubscribeMsg), this)
|
||||||
|
getSubscription()
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(getString(R.string.errorMsg), this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribeAction() {
|
||||||
|
if (isSubcribed) {
|
||||||
|
unSubscribe()
|
||||||
|
} else {
|
||||||
|
subscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSubscription() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
isSubcribed = actionsService.getSubscription(ManagerSingleton.token.token, channel.getAccount())
|
||||||
|
runOnUiThread {
|
||||||
|
if (isSubcribed) {
|
||||||
|
binding.subcriptionBtn.text = getText(R.string.unSubscribeBtn)
|
||||||
|
} else {
|
||||||
|
binding.subcriptionBtn.text = getText(R.string.subscribeBtn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVideos() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val videos = videosService.channelVideos(channel.getAccount(), 0)
|
||||||
|
runOnUiThread {
|
||||||
|
initRecycler(videos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic function for set data to RecyclerView
|
||||||
|
private fun initRecycler(data: ArrayList<VideoModel>) {
|
||||||
|
// val data = arrayListOf<VideoModel>()
|
||||||
|
viewAdapter = VideosAdapter(data)
|
||||||
|
|
||||||
|
recyclerView = findViewById<RecyclerView>(R.id.listVideosChannel).apply {
|
||||||
|
// use this setting to improve performance if you know that changes
|
||||||
|
// in content do not change the layout size of the RecyclerView
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
// use a linear layout manager
|
||||||
|
layoutManager = viewManager
|
||||||
|
|
||||||
|
// specify an viewAdapter (see also next example)
|
||||||
|
adapter = viewAdapter
|
||||||
|
}
|
||||||
|
// swipeContainer.isRefreshing = false
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,11 +8,11 @@ import android.database.sqlite.SQLiteOpenHelper
|
||||||
import org.libre.agosto.p2play.models.TokenModel
|
import org.libre.agosto.p2play.models.TokenModel
|
||||||
import org.libre.agosto.p2play.models.UserModel
|
import org.libre.agosto.p2play.models.UserModel
|
||||||
|
|
||||||
class Database(context:Context): SQLiteOpenHelper(context,"p2play",null,1) {
|
class Database(context: Context) : SQLiteOpenHelper(context, "p2play", null, 1) {
|
||||||
val dbName = "p2play"
|
val dbName = "p2play"
|
||||||
|
|
||||||
private val dbUsers = "CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT, uuid INTEGER, username varchar(30), " +
|
private val dbUsers = "CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT, uuid INTEGER, username varchar(30), " +
|
||||||
"nsfw INTEGER, email string, followers INTEGER, avatar string, status integer)"
|
"nsfw INTEGER, email string, followers INTEGER, avatar string, status integer)"
|
||||||
private val dbTokens = "CREATE TABLE tokens(id INTEGER PRIMARY KEY AUTOINCREMENT, token STRING, refresh_token STRING, status INTEGER)"
|
private val dbTokens = "CREATE TABLE tokens(id INTEGER PRIMARY KEY AUTOINCREMENT, token STRING, refresh_token STRING, status INTEGER)"
|
||||||
override fun onCreate(db: SQLiteDatabase?) {
|
override fun onCreate(db: SQLiteDatabase?) {
|
||||||
db?.execSQL(dbUsers)
|
db?.execSQL(dbUsers)
|
||||||
|
@ -28,12 +28,12 @@ class Database(context:Context): SQLiteOpenHelper(context,"p2play",null,1) {
|
||||||
fun newToken(token: TokenModel): Boolean {
|
fun newToken(token: TokenModel): Boolean {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
this.closeTokens()
|
this.closeTokens()
|
||||||
val newToken=ContentValues()
|
val newToken = ContentValues()
|
||||||
newToken.put("token", token.token)
|
newToken.put("token", token.token)
|
||||||
newToken.put("refresh_token", token.refresh_token)
|
newToken.put("refresh_token", token.refresh_token)
|
||||||
newToken.put("status", token.status)
|
newToken.put("status", token.status)
|
||||||
|
|
||||||
db.insert("tokens",null,newToken)
|
db.insert("tokens", null, newToken)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class Database(context:Context): SQLiteOpenHelper(context,"p2play",null,1) {
|
||||||
fun newUser(user: UserModel): Boolean {
|
fun newUser(user: UserModel): Boolean {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
this.closeUsers()
|
this.closeUsers()
|
||||||
val newUser=ContentValues()
|
val newUser = ContentValues()
|
||||||
newUser.put("uuid", user.uuid)
|
newUser.put("uuid", user.uuid)
|
||||||
newUser.put("username", user.username)
|
newUser.put("username", user.username)
|
||||||
newUser.put("email", user.email)
|
newUser.put("email", user.email)
|
||||||
|
@ -50,76 +50,78 @@ class Database(context:Context): SQLiteOpenHelper(context,"p2play",null,1) {
|
||||||
newUser.put("avatar", user.avatar)
|
newUser.put("avatar", user.avatar)
|
||||||
newUser.put("status", user.status)
|
newUser.put("status", user.status)
|
||||||
|
|
||||||
db.insert("users",null, newUser)
|
db.insert("users", null, newUser)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getToken(): TokenModel{
|
fun getToken(): TokenModel {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
var token = TokenModel()
|
var token = TokenModel()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var cursor= db.rawQuery("SELECT * FROM tokens WHERE status=1 ORDER BY id DESC LIMIT 1",null)
|
var cursor = db.rawQuery("SELECT * FROM tokens WHERE status=1 ORDER BY id DESC LIMIT 1", null)
|
||||||
cursor.moveToFirst()
|
|
||||||
|
|
||||||
token.token = cursor.getString(cursor.getColumnIndex("token")).toString()
|
if (cursor.count != 0) {
|
||||||
token.refresh_token = cursor.getString(cursor.getColumnIndex("refresh_token")).toString()
|
cursor.moveToFirst()
|
||||||
token.status = cursor.getString(cursor.getColumnIndex("status")).toInt()
|
|
||||||
|
|
||||||
|
token.token = cursor.getString(cursor.getColumnIndex("token")).toString()
|
||||||
|
token.refresh_token = cursor.getString(cursor.getColumnIndex("refresh_token")).toString()
|
||||||
|
token.status = cursor.getString(cursor.getColumnIndex("status")).toInt()
|
||||||
|
}
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
} catch (e: SQLiteException) {
|
||||||
}catch (e:SQLiteException){
|
|
||||||
db?.execSQL(dbTokens)
|
db?.execSQL(dbTokens)
|
||||||
}catch (e:Exception){
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUser(): UserModel{
|
fun getUser(): UserModel {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
var user = UserModel()
|
var user = UserModel()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var cursor= db.rawQuery("SELECT * FROM users WHERE status=1 ORDER BY id DESC LIMIT 1",null)
|
var cursor = db.rawQuery("SELECT * FROM users WHERE status=1 ORDER BY id DESC LIMIT 1", null)
|
||||||
cursor.moveToFirst()
|
|
||||||
|
|
||||||
user.uuid = cursor.getString(cursor.getColumnIndex("uuid")).toInt()
|
if (cursor.count != 0) {
|
||||||
user.username = cursor.getString(cursor.getColumnIndex("username")).toString()
|
cursor.moveToFirst()
|
||||||
user.email = cursor.getString(cursor.getColumnIndex("email")).toString()
|
|
||||||
user.nsfw = cursor.getString(cursor.getColumnIndex("nsfw")).toBoolean()
|
user.uuid = cursor.getString(cursor.getColumnIndex("uuid")).toInt()
|
||||||
user.followers = cursor.getString(cursor.getColumnIndex("followers")).toInt()
|
user.username = cursor.getString(cursor.getColumnIndex("username")).toString()
|
||||||
user.avatar = cursor.getString(cursor.getColumnIndex("avatar")).toString()
|
user.email = cursor.getString(cursor.getColumnIndex("email")).toString()
|
||||||
user.status = cursor.getString(cursor.getColumnIndex("status")).toInt()
|
user.nsfw = cursor.getString(cursor.getColumnIndex("nsfw")).toBoolean()
|
||||||
|
user.followers = cursor.getString(cursor.getColumnIndex("followers")).toInt()
|
||||||
|
user.avatar = cursor.getString(cursor.getColumnIndex("avatar")).toString()
|
||||||
|
user.status = cursor.getString(cursor.getColumnIndex("status")).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
} catch (e: SQLiteException) {
|
||||||
}catch (e:SQLiteException){
|
|
||||||
db?.execSQL(dbTokens)
|
db?.execSQL(dbTokens)
|
||||||
}catch (e:Exception){
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun closeTokens(){
|
private fun closeTokens() {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
db.execSQL("UPDATE tokens SET status=-1 WHERE 1")
|
db.execSQL("UPDATE tokens SET status=-1 WHERE 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun closeUsers(){
|
private fun closeUsers() {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
db.execSQL("UPDATE users SET status=-1 WHERE 1")
|
db.execSQL("UPDATE users SET status=-1 WHERE 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logout(){
|
fun logout() {
|
||||||
closeUsers()
|
closeUsers()
|
||||||
closeTokens()
|
closeTokens()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -3,115 +3,89 @@ package org.libre.agosto.p2play
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.preference.PreferenceManager
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.util.Log
|
import androidx.preference.PreferenceManager
|
||||||
import kotlinx.android.synthetic.main.activity_host.*
|
|
||||||
import org.libre.agosto.p2play.ajax.Auth
|
import org.libre.agosto.p2play.ajax.Auth
|
||||||
import org.libre.agosto.p2play.ajax.Client
|
import org.libre.agosto.p2play.databinding.ActivityHostBinding
|
||||||
|
|
||||||
class HostActivity : AppCompatActivity() {
|
class HostActivity : AppCompatActivity() {
|
||||||
lateinit var settings: SharedPreferences
|
lateinit var settings: SharedPreferences
|
||||||
lateinit var editor: SharedPreferences.Editor
|
lateinit var editor: SharedPreferences.Editor
|
||||||
val client:Auth = Auth()
|
val client: Auth = Auth()
|
||||||
val _db = Database(this)
|
private val db = Database(this)
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityHostBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_host)
|
binding = ActivityHostBinding.inflate(layoutInflater)
|
||||||
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
editor = settings.edit()
|
editor = settings.edit()
|
||||||
ManagerSingleton.context = this
|
|
||||||
button.setOnClickListener {
|
binding.button.setOnClickListener {
|
||||||
getKeys(hostText.text.toString())
|
getKeys(binding.hostText.text.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
val host = settings.getString("hostP2play","")
|
val host = settings.getString("hostP2play", "")
|
||||||
val lastHost = settings.getString("last_host","")
|
val lastHost = settings.getString("last_host", "")
|
||||||
if(host!=""){
|
if (host != "") {
|
||||||
if(lastHost!=host){
|
if (lastHost != host) {
|
||||||
_db.logout()
|
db.logout()
|
||||||
getKeys(host)
|
ManagerSingleton.logout()
|
||||||
}else{
|
getKeys(host!!)
|
||||||
ManagerSingleton.url=host
|
} else {
|
||||||
checkUser()
|
ManagerSingleton.url = host
|
||||||
|
startApp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkUser(){
|
fun saveHost(host: String) {
|
||||||
val token = _db.getToken()
|
editor.putString("last_host", host)
|
||||||
val user = _db.getUser()
|
editor.putString("hostP2play", host)
|
||||||
|
editor.apply()
|
||||||
|
ManagerSingleton.toast(getString(R.string.finallyMsg), this)
|
||||||
|
ManagerSingleton.url = host
|
||||||
|
startApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getKeys(hostText: String) {
|
||||||
|
binding.button.isEnabled = false
|
||||||
|
var host = hostText.toString()
|
||||||
|
host = host.replace("http://", "")
|
||||||
|
host = host.replace("https://", "")
|
||||||
|
host = host.replace("/", "")
|
||||||
|
ManagerSingleton.url = host
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper() == null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
|
|
||||||
startApp()
|
|
||||||
if (token.status == 1 && user.status == 1) {
|
|
||||||
val client_id = settings.getString("client_id", "")
|
|
||||||
val client_secret = settings.getString("client_secret", "")
|
|
||||||
|
|
||||||
val newToken = client.refreshToken(token, client_id, client_secret)
|
|
||||||
|
|
||||||
when (token.status.toString()) {
|
|
||||||
"1" -> {
|
|
||||||
_db.newToken(newToken)
|
|
||||||
ManagerSingleton.token = newToken
|
|
||||||
ManagerSingleton.user = user
|
|
||||||
}
|
|
||||||
else -> _db.logout()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_db.logout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val keys = client.getKeys()
|
||||||
|
if (keys.client_id != "") {
|
||||||
|
editor.putString("client_id", keys.client_id)
|
||||||
|
editor.putString("client_secret", keys.client_secret)
|
||||||
|
editor.apply()
|
||||||
|
saveHost(host)
|
||||||
|
} else {
|
||||||
|
runOnUiThread {
|
||||||
|
ManagerSingleton.toast(getString(R.string.errorMsg), this)
|
||||||
|
binding.button.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startApp() {
|
||||||
|
runOnUiThread {
|
||||||
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
this.finish()
|
this.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveHost(host: String){
|
|
||||||
editor.putString("last_host",host)
|
|
||||||
editor.putString("hostP2play",host)
|
|
||||||
editor.apply()
|
|
||||||
ManagerSingleton.Toast(getString(R.string.finallyMsg))
|
|
||||||
ManagerSingleton.url=host
|
|
||||||
checkUser()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getKeys(hostText: String){
|
|
||||||
button.isEnabled = false
|
|
||||||
var host = hostText.toString()
|
|
||||||
host = host.replace("http://","")
|
|
||||||
host = host.replace("https://","")
|
|
||||||
host = host.replace("/","")
|
|
||||||
ManagerSingleton.url = host
|
|
||||||
AsyncTask.execute {
|
|
||||||
if (Looper.myLooper()==null)
|
|
||||||
Looper.prepare()
|
|
||||||
|
|
||||||
val keys = client.getKeys()
|
|
||||||
if(keys.client_id!=""){
|
|
||||||
editor.putString("client_id",keys.client_id)
|
|
||||||
editor.putString("client_secret",keys.client_secret)
|
|
||||||
editor.apply()
|
|
||||||
saveHost(host)
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
runOnUiThread {
|
|
||||||
ManagerSingleton.Toast(getString(R.string.errorMsg))
|
|
||||||
button.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startApp(){
|
|
||||||
runOnUiThread {
|
|
||||||
val intent = Intent(ManagerSingleton.context,MainActivity::class.java)
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,86 +3,113 @@ package org.libre.agosto.p2play
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.preference.PreferenceManager
|
import android.widget.EditText
|
||||||
import android.util.Log
|
import androidx.appcompat.app.AlertDialog
|
||||||
import kotlinx.android.synthetic.main.activity_login.*
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import org.libre.agosto.p2play.ajax.Auth
|
import org.libre.agosto.p2play.ajax.Auth
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityLoginBinding
|
||||||
|
|
||||||
class LoginActivity : AppCompatActivity() {
|
class LoginActivity : AppCompatActivity() {
|
||||||
private val _auth = Auth()
|
private val auth = Auth()
|
||||||
lateinit var settings: SharedPreferences
|
lateinit var settings: SharedPreferences
|
||||||
lateinit var client_id: String
|
lateinit var clientId: String
|
||||||
lateinit var client_secret: String
|
lateinit var clientSecret: String
|
||||||
private lateinit var _db: Database
|
private lateinit var db: Database
|
||||||
|
private var optCode: String? = null
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityLoginBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_login)
|
binding = ActivityLoginBinding.inflate(layoutInflater)
|
||||||
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
setTitle(R.string.action_login)
|
setTitle(R.string.action_login)
|
||||||
ManagerSingleton.context = this
|
db = Database(this)
|
||||||
_db = Database(this)
|
|
||||||
|
|
||||||
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
client_id = settings.getString("client_id", "")
|
clientId = settings.getString("client_id", "")!!
|
||||||
client_secret = settings.getString("client_secret", "")
|
clientSecret = settings.getString("client_secret", "")!!
|
||||||
|
|
||||||
registerActionBtn.setOnClickListener { startActivity(Intent(this, RegisterActivity::class.java)) }
|
binding.registerActionBtn.setOnClickListener { startActivity(Intent(this, RegisterActivity::class.java)) }
|
||||||
loginBtn.setOnClickListener { tryLogin() }
|
binding.loginBtn.setOnClickListener { tryLogin() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryLogin(){
|
fun tryLogin() {
|
||||||
loginBtn.isEnabled = false;
|
binding.loginBtn.isEnabled = false
|
||||||
val username = userText.text.toString()
|
val username = binding.userText.text.toString()
|
||||||
val password = passwordText.text.toString()
|
val password = binding.passwordText.text.toString()
|
||||||
|
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper()==null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
|
}
|
||||||
|
|
||||||
val token = _auth.login(username, password, client_id, client_secret)
|
val token = auth.login(username, password, clientId, clientSecret, optCode)
|
||||||
|
|
||||||
// Log.d("token", token.token )
|
// Log.d("token", token.token )
|
||||||
// Log.d("status", token.status.toString() )
|
// Log.d("status", token.status.toString() )
|
||||||
|
|
||||||
|
when (token.status.toString()) {
|
||||||
when(token.status.toString()){
|
|
||||||
"1" -> {
|
"1" -> {
|
||||||
_db.newToken(token)
|
db.newToken(token)
|
||||||
ManagerSingleton.token = token
|
ManagerSingleton.token = token
|
||||||
getUser()
|
getUser()
|
||||||
}
|
}
|
||||||
"0" -> {
|
"0" -> {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
ManagerSingleton.Toast(getString(R.string.loginError_msg))
|
ManagerSingleton.toast(getString(R.string.loginError_msg), this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"-1" -> {
|
"-1" -> {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
loginBtn.isEnabled = true
|
binding.loginBtn.isEnabled = true
|
||||||
ManagerSingleton.Toast(getString(R.string.loginFailed_msg))
|
ManagerSingleton.toast(getString(R.string.loginFailed_msg), this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"-2" -> {
|
||||||
|
// TODO: Start 2FA modal
|
||||||
|
runOnUiThread {
|
||||||
|
val builder = AlertDialog.Builder(this, R.style.Widget_Material3_MaterialCalendar_Fullscreen)
|
||||||
|
val dialog = layoutInflater.inflate(R.layout.two_factor_dialog, null)
|
||||||
|
|
||||||
|
val inputTwoFactor = dialog.findViewById<EditText>(R.id.twoFactorText)
|
||||||
|
|
||||||
|
builder.setView(dialog)
|
||||||
|
.setTitle(R.string.twoFactorLabel)
|
||||||
|
// Add action buttons
|
||||||
|
.setPositiveButton(R.string.loginBtn) { d, _ ->
|
||||||
|
this.optCode = inputTwoFactor.text.toString()
|
||||||
|
this.tryLogin()
|
||||||
|
d.dismiss()
|
||||||
|
}
|
||||||
|
.setNegativeButton("Cancel") { d, _ ->
|
||||||
|
dialog.run { d.cancel() }
|
||||||
|
binding.loginBtn.isEnabled = true
|
||||||
|
}
|
||||||
|
val alertDialog = builder.create()
|
||||||
|
alertDialog.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUser(){
|
fun getUser() {
|
||||||
val user = _auth.me(ManagerSingleton.token.token)
|
val user = auth.me(ManagerSingleton.token.token)
|
||||||
if(user.status == 1){
|
if (user.status == 1) {
|
||||||
_db.newUser(user)
|
db.newUser(user)
|
||||||
ManagerSingleton.user = user
|
ManagerSingleton.user = user
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
ManagerSingleton.Toast(getString(R.string.loginSuccess_msg))
|
ManagerSingleton.toast(getString(R.string.loginSuccess_msg), this)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
ManagerSingleton.Toast(getString(R.string.loginError_msg))
|
ManagerSingleton.toast(getString(R.string.loginError_msg), this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,71 +3,79 @@ package org.libre.agosto.p2play
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.design.widget.Snackbar
|
import android.os.Handler
|
||||||
import android.support.design.widget.NavigationView
|
|
||||||
import android.support.v4.view.GravityCompat
|
|
||||||
import android.support.v7.app.ActionBarDrawerToggle
|
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.widget.SearchView
|
||||||
|
import androidx.core.view.GravityCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.navigation.NavigationView
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
|
||||||
import kotlinx.android.synthetic.main.app_bar_main.*
|
|
||||||
import kotlinx.android.synthetic.main.content_main.*
|
|
||||||
import kotlinx.android.synthetic.main.nav_header_main.*
|
|
||||||
import org.libre.agosto.p2play.adapters.VideosAdapter
|
import org.libre.agosto.p2play.adapters.VideosAdapter
|
||||||
import org.libre.agosto.p2play.ajax.Videos
|
import org.libre.agosto.p2play.ajax.Videos
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityMainBinding
|
||||||
|
import org.libre.agosto.p2play.helpers.getViewManager
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
import org.libre.agosto.p2play.singletons.PlaybackSingleton
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
|
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
|
||||||
private lateinit var recyclerView: RecyclerView
|
private lateinit var recyclerView: RecyclerView
|
||||||
private lateinit var viewAdapter: RecyclerView.Adapter<*>
|
private lateinit var viewAdapter: RecyclerView.Adapter<VideosAdapter.ViewHolder>
|
||||||
private lateinit var viewManager: RecyclerView.LayoutManager
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
val client: Videos = Videos()
|
private val client: Videos = Videos()
|
||||||
private lateinit var lastItem: MenuItem
|
private lateinit var lastItem: MenuItem
|
||||||
private lateinit var subItem: MenuItem
|
|
||||||
lateinit var myMenu: Menu
|
lateinit var myMenu: Menu
|
||||||
val _db = Database(this)
|
private val db = Database(this)
|
||||||
var section: String = ""
|
var section: String = ""
|
||||||
|
var searchVal: String = ""
|
||||||
|
var pagination = 0
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityMainBinding
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setSupportActionBar(toolbar)
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
/* fab.setOnClickListener { view ->
|
val toggle = ActionBarDrawerToggle(this, binding.drawerLayout, binding.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
|
||||||
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
binding.drawerLayout.addDrawerListener(toggle)
|
||||||
.setAction("Action", null).show()
|
|
||||||
} */
|
|
||||||
|
|
||||||
val toggle = ActionBarDrawerToggle(
|
|
||||||
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
|
|
||||||
drawer_layout.addDrawerListener(toggle)
|
|
||||||
toggle.syncState()
|
toggle.syncState()
|
||||||
|
|
||||||
// Context for ManagerSingleton
|
binding.navView.setNavigationItemSelectedListener(this)
|
||||||
ManagerSingleton.context = this
|
|
||||||
|
|
||||||
nav_view.setNavigationItemSelectedListener(this)
|
viewManager = getViewManager(this, resources)
|
||||||
viewManager = LinearLayoutManager(this)
|
|
||||||
|
|
||||||
// Set data for RecyclerView
|
// Init RecyclerView
|
||||||
this.setData(arrayListOf())
|
this.initRecycler()
|
||||||
|
|
||||||
this.getLastVideos()
|
this.getTrengindVideos()
|
||||||
|
|
||||||
swipeContainer.setOnRefreshListener {
|
binding.content.swipeContainer.setOnRefreshListener {
|
||||||
this.refresh()
|
this.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.content.mini.miniPlayerImage.setOnClickListener { this.resumeVideo() }
|
||||||
|
binding.content.mini.miniPlayerTitle.setOnClickListener { this.resumeVideo() }
|
||||||
|
binding.content.mini.miniPlayerAuthor.setOnClickListener { this.resumeVideo() }
|
||||||
|
// binding.content.mini.setOnClickListener { this.resumeVideo() }
|
||||||
|
binding.content.mini.miniPlayPause.setOnClickListener { this.playPausePlayer() }
|
||||||
|
|
||||||
|
Handler().postDelayed({
|
||||||
|
// Title for nav_bar
|
||||||
|
binding.navView.getHeaderView(0).findViewById<TextView>(R.id.side_emailTxt).text = getString(R.string.nav_header_subtitle) + " " + this.packageManager.getPackageInfo(this.packageName, 0).versionName
|
||||||
|
}, 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic function for set data to RecyclerView
|
// Generic function for set data to RecyclerView
|
||||||
fun setData(data:ArrayList<VideoModel>){
|
private fun initRecycler() {
|
||||||
|
val data = arrayListOf<VideoModel>()
|
||||||
viewAdapter = VideosAdapter(data)
|
viewAdapter = VideosAdapter(data)
|
||||||
|
|
||||||
recyclerView = findViewById<RecyclerView>(R.id.list).apply {
|
recyclerView = findViewById<RecyclerView>(R.id.list).apply {
|
||||||
|
@ -80,96 +88,176 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||||
|
|
||||||
// specify an viewAdapter (see also next example)
|
// specify an viewAdapter (see also next example)
|
||||||
adapter = viewAdapter
|
adapter = viewAdapter
|
||||||
|
|
||||||
|
this.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
// super.onScrolled(recyclerView!!, dx, dy)
|
||||||
|
|
||||||
|
if (!binding.content.swipeContainer.isRefreshing) {
|
||||||
|
if (!canScrollVertically(1)) {
|
||||||
|
loadMore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
swipeContainer.isRefreshing = false
|
binding.content.swipeContainer.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refresh(){
|
private fun addVideos(videos: ArrayList<VideoModel>) {
|
||||||
swipeContainer.isRefreshing = true
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
when(section){
|
|
||||||
|
try {
|
||||||
|
if (this.pagination == 0) {
|
||||||
|
(viewAdapter as VideosAdapter).clearData()
|
||||||
|
recyclerView.scrollToPosition(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
(viewAdapter as VideosAdapter).addData(videos)
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
ManagerSingleton.toast(getString(R.string.errorMsg), this)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.content.swipeContainer.isRefreshing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refresh() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
|
this.pagination = 0
|
||||||
|
when (section) {
|
||||||
"local" -> this.getLocalVideos()
|
"local" -> this.getLocalVideos()
|
||||||
"popular" -> this.getPopularVideos()
|
"popular" -> this.getPopularVideos()
|
||||||
|
"trending" -> this.getTrengindVideos()
|
||||||
"last" -> this.getLastVideos()
|
"last" -> this.getLastVideos()
|
||||||
"sub" -> this.getSubscriptionVideos()
|
"sub" -> this.getSubscriptionVideos()
|
||||||
|
"search" -> this.searchVideos()
|
||||||
"my_videos" -> {
|
"my_videos" -> {
|
||||||
if(ManagerSingleton.token.token != "")
|
if (ManagerSingleton.token.token != "") {
|
||||||
this.getMyVideos()
|
this.getMyVideos()
|
||||||
else
|
} else {
|
||||||
this.getLastVideos()
|
this.getLastVideos()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSubscriptionVideos(){
|
private fun getSubscriptionVideos() {
|
||||||
if(ManagerSingleton.user.status != 1){
|
if (ManagerSingleton.user.status != 1) {
|
||||||
ManagerSingleton.Toast("Inicia session primero")
|
ManagerSingleton.toast("Inicia session primero", this)
|
||||||
startActivity(Intent(this, LoginActivity::class.java))
|
startActivity(Intent(this, LoginActivity::class.java))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
swipeContainer.isRefreshing = true
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
section = "sub"
|
section = "sub"
|
||||||
setTitle(R.string.title_subscriptions)
|
setTitle(R.string.title_subscriptions)
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
val videos = client.videoSubscriptions(ManagerSingleton.token.token)
|
val videos = client.videoSubscriptions(ManagerSingleton.token.token, this.pagination)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
this.setData(videos)
|
this.addVideos(videos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last videos
|
// Last videos
|
||||||
fun getLastVideos(){
|
private fun getLastVideos() {
|
||||||
swipeContainer.isRefreshing = true
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
section = "last"
|
section = "last"
|
||||||
setTitle(R.string.title_recent)
|
setTitle(R.string.title_recent)
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
val videos = client.getLastVideos()
|
val videos = client.getLastVideos(this.pagination)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
this.setData(videos)
|
this.addVideos(videos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Popular videos
|
||||||
fun getPopularVideos(){
|
private fun getPopularVideos() {
|
||||||
swipeContainer.isRefreshing = true
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
section = "popular"
|
section = "popular"
|
||||||
setTitle(R.string.title_popular)
|
setTitle(R.string.title_popular)
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
val videos = client.getPopularVideos()
|
val videos = client.getPopularVideos(this.pagination)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
this.setData(videos)
|
this.addVideos(videos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLocalVideos(){
|
// Trending videos
|
||||||
swipeContainer.isRefreshing = true
|
private fun getTrengindVideos() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
|
section = "trending"
|
||||||
|
setTitle(R.string.title_trending)
|
||||||
|
AsyncTask.execute {
|
||||||
|
val videos = client.getTrendingVideos(this.pagination)
|
||||||
|
runOnUiThread {
|
||||||
|
this.addVideos(videos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local videos
|
||||||
|
private fun getLocalVideos() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
section = "local"
|
section = "local"
|
||||||
setTitle(R.string.title_local)
|
setTitle(R.string.title_local)
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
val videos = client.getLocalVideos()
|
val videos = client.getLocalVideos(this.pagination)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
this.setData(videos)
|
this.addVideos(videos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMyVideos(){
|
// Videos of user
|
||||||
swipeContainer.isRefreshing = true
|
private fun getMyVideos() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
section = "my_videos"
|
section = "my_videos"
|
||||||
setTitle(R.string.title_myVideos)
|
setTitle(R.string.title_myVideos)
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
val videos = client.myVideos(ManagerSingleton.token.token)
|
val videos = client.myVideos(ManagerSingleton.token.token, this.pagination)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
this.setData(videos)
|
this.addVideos(videos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Videos history of user
|
||||||
|
private fun getHistory() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
|
section = "my_videos"
|
||||||
|
setTitle(R.string.nav_history)
|
||||||
|
AsyncTask.execute {
|
||||||
|
val videos = client.videoHistory(ManagerSingleton.token.token, this.pagination)
|
||||||
|
runOnUiThread {
|
||||||
|
this.addVideos(videos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most liked
|
||||||
|
private fun getMostLiked() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
|
section = "liked"
|
||||||
|
setTitle(R.string.nav_likes)
|
||||||
|
AsyncTask.execute {
|
||||||
|
val videos = client.getMostLikedVideos(this.pagination)
|
||||||
|
runOnUiThread {
|
||||||
|
this.addVideos(videos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
|
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||||
drawer_layout.closeDrawer(GravityCompat.START)
|
binding.drawerLayout.closeDrawer(GravityCompat.START)
|
||||||
|
} else if (!section.equals("trending")) {
|
||||||
|
// Hot fix
|
||||||
|
pagination = 0
|
||||||
|
this.getTrengindVideos()
|
||||||
} else {
|
} else {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
|
@ -178,6 +266,26 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
menuInflater.inflate(R.menu.main, menu)
|
menuInflater.inflate(R.menu.main, menu)
|
||||||
|
|
||||||
|
val searchItem = menu.findItem(R.id.app_bar_search)
|
||||||
|
val searchView = searchItem.actionView as SearchView
|
||||||
|
|
||||||
|
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||||
|
override fun onQueryTextChange(p0: String?): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextSubmit(p0: String?): Boolean {
|
||||||
|
if (!p0.isNullOrBlank()) {
|
||||||
|
searchVal = p0
|
||||||
|
pagination = 0
|
||||||
|
searchView.onActionViewCollapsed()
|
||||||
|
searchVideos()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
myMenu = menu
|
myMenu = menu
|
||||||
setSideData()
|
setSideData()
|
||||||
return true
|
return true
|
||||||
|
@ -195,7 +303,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||||
// as you specify a parent activity in AndroidManifest.xml.
|
// as you specify a parent activity in AndroidManifest.xml.
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_settings -> {
|
R.id.action_settings -> {
|
||||||
val intent = Intent(this, SettingsActivity::class.java)
|
val intent = Intent(this, SettingsActivity2::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -216,73 +324,147 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||||
// Handle navigation view item clicks here.
|
// Handle navigation view item clicks here.
|
||||||
|
|
||||||
// if(::lastItem.isInitialized){
|
// if(::lastItem.isInitialized){
|
||||||
// lastItem.isChecked = false
|
// lastItem.isChecked = false
|
||||||
// }
|
// }
|
||||||
lastItem = item
|
lastItem = item
|
||||||
|
pagination = 0
|
||||||
|
|
||||||
// item.isChecked = true
|
// item.isChecked = true
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.nav_subscriptions->{
|
R.id.nav_subscriptions -> getSubscriptionVideos()
|
||||||
getSubscriptionVideos()
|
R.id.nav_popular -> getPopularVideos()
|
||||||
}
|
R.id.nav_trending -> getTrengindVideos()
|
||||||
R.id.nav_popular-> {
|
R.id.nav_recent -> getLastVideos()
|
||||||
getPopularVideos()
|
R.id.nav_local -> getLocalVideos()
|
||||||
}
|
R.id.nav_about -> {
|
||||||
R.id.nav_recent-> {
|
|
||||||
getLastVideos()
|
|
||||||
}
|
|
||||||
R.id.nav_local-> {
|
|
||||||
getLocalVideos()
|
|
||||||
}
|
|
||||||
R.id.nav_about-> {
|
|
||||||
val intent = Intent(this, AboutActivity::class.java)
|
val intent = Intent(this, AboutActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
R.id.nav_history -> getHistory()
|
||||||
|
R.id.nav_myVideos -> getMyVideos()
|
||||||
|
R.id.nav_likes -> getMostLiked()
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer_layout.closeDrawer(GravityCompat.START)
|
binding.drawerLayout.closeDrawer(GravityCompat.START)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
ManagerSingleton.context = this
|
|
||||||
setSideData()
|
setSideData()
|
||||||
|
|
||||||
|
if (PlaybackSingleton.player != null && PlaybackSingleton.player!!.isPlaying) {
|
||||||
|
PlaybackSingleton.runMediaSession(this)
|
||||||
|
|
||||||
|
binding.content.mini.miniPlayerTitle.text = PlaybackSingleton.video!!.name
|
||||||
|
binding.content.mini.miniPlayerAuthor.text = PlaybackSingleton.video!!.username
|
||||||
|
Picasso.get().load("https://${ManagerSingleton.url}${PlaybackSingleton.video!!.thumbUrl}").into(binding.content.mini.miniPlayerImage)
|
||||||
|
binding.content.mini.miniPlayPause.setImageResource(R.drawable.ic_pause_24)
|
||||||
|
binding.content.mini.miniPlayer.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.content.mini.miniPlayer.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setSideData(){
|
override fun onDestroy() {
|
||||||
if(ManagerSingleton.user.status == 1){
|
if (PlaybackSingleton.player != null) {
|
||||||
side_usernameTxt?.text = ManagerSingleton.user.username
|
PlaybackSingleton.release()
|
||||||
side_emailTxt?.text = ManagerSingleton.user.email
|
}
|
||||||
if(ManagerSingleton.user.avatar!="" && side_imageView != null)
|
super.onDestroy()
|
||||||
Picasso.get().load("https://"+ManagerSingleton.url+ManagerSingleton.user.avatar).into(side_imageView)
|
}
|
||||||
side_imageView?.setOnClickListener {
|
|
||||||
getMyVideos()
|
private fun setSideData() {
|
||||||
drawer_layout.closeDrawer(GravityCompat.START)
|
if (ManagerSingleton.user.status == 1) {
|
||||||
|
binding.navView.menu.findItem(R.id.ml).isVisible = true
|
||||||
|
|
||||||
|
val headerView = binding.navView.getHeaderView(0)
|
||||||
|
headerView.findViewById<TextView>(R.id.side_usernameTxt).text = ManagerSingleton.user.username
|
||||||
|
headerView.findViewById<TextView>(R.id.side_emailTxt).text = ManagerSingleton.user.email
|
||||||
|
if (ManagerSingleton.user.avatar != "" && headerView.findViewById<ImageView>(R.id.side_imageView) != null) {
|
||||||
|
Picasso.get().load("https://" + ManagerSingleton.url + ManagerSingleton.user.avatar).into(headerView.findViewById<ImageView>(R.id.side_imageView))
|
||||||
}
|
}
|
||||||
if(::myMenu.isInitialized){
|
headerView.findViewById<ImageView>(R.id.side_imageView).setOnClickListener {
|
||||||
|
pagination = 0
|
||||||
|
getMyVideos()
|
||||||
|
binding.drawerLayout.closeDrawer(GravityCompat.START)
|
||||||
|
}
|
||||||
|
if (::myMenu.isInitialized) {
|
||||||
myMenu.findItem(R.id.action_login).isVisible = false
|
myMenu.findItem(R.id.action_login).isVisible = false
|
||||||
myMenu.findItem(R.id.action_logout).isVisible = true
|
myMenu.findItem(R.id.action_logout).isVisible = true
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
binding.navView.menu.findItem(R.id.ml).isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logout(){
|
private fun logout() {
|
||||||
if(::myMenu.isInitialized){
|
if (::myMenu.isInitialized) {
|
||||||
myMenu.findItem(R.id.action_login).isVisible = true
|
myMenu.findItem(R.id.action_login).isVisible = true
|
||||||
myMenu.findItem(R.id.action_logout).isVisible = false
|
myMenu.findItem(R.id.action_logout).isVisible = false
|
||||||
}
|
}
|
||||||
|
val headerView = binding.navView.getHeaderView(0)
|
||||||
side_usernameTxt?.text = getString(R.string.nav_header_title)
|
binding.navView.menu.findItem(R.id.ml).isVisible = false
|
||||||
side_emailTxt?.text = getString(R.string.nav_header_subtitle)
|
headerView.findViewById<TextView>(R.id.side_usernameTxt).text = getString(R.string.nav_header_title)
|
||||||
side_imageView?.setImageResource(R.mipmap.ic_launcher_round)
|
headerView.findViewById<TextView>(R.id.side_emailTxt).text = getString(R.string.nav_header_subtitle) + " " + this.packageManager.getPackageInfo(this.packageName, 0).versionName
|
||||||
side_imageView?.setOnClickListener { }
|
headerView.findViewById<ImageView>(R.id.side_imageView).setImageResource(R.drawable.default_avatar)
|
||||||
_db.logout()
|
headerView.findViewById<ImageView>(R.id.side_imageView).setOnClickListener { }
|
||||||
|
db.logout()
|
||||||
ManagerSingleton.logout()
|
ManagerSingleton.logout()
|
||||||
|
|
||||||
this.refresh()
|
this.refresh()
|
||||||
ManagerSingleton.Toast(getString(R.string.logout_msg))
|
ManagerSingleton.toast(getString(R.string.logout_msg), this)
|
||||||
|
setSideData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadMore() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
|
this.pagination += ManagerSingleton.videosCount
|
||||||
|
|
||||||
|
when (section) {
|
||||||
|
"local" -> this.getLocalVideos()
|
||||||
|
"popular" -> this.getPopularVideos()
|
||||||
|
"trending" -> this.getTrengindVideos()
|
||||||
|
"last" -> this.getLastVideos()
|
||||||
|
"sub" -> this.getSubscriptionVideos()
|
||||||
|
"search" -> this.searchVideos()
|
||||||
|
"my_videos" -> {
|
||||||
|
if (ManagerSingleton.token.token != "") {
|
||||||
|
this.getMyVideos()
|
||||||
|
} else {
|
||||||
|
this.getLastVideos()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"liked" -> this.getMostLiked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun searchVideos() {
|
||||||
|
binding.content.swipeContainer.isRefreshing = true
|
||||||
|
section = "search"
|
||||||
|
this.title = this.searchVal
|
||||||
|
AsyncTask.execute {
|
||||||
|
val videos = client.search(this.searchVal, this.pagination)
|
||||||
|
runOnUiThread {
|
||||||
|
this.addVideos(videos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resumeVideo() {
|
||||||
|
val intent = Intent(this, ReproductorActivity::class.java)
|
||||||
|
intent.putExtra("resume", true)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun playPausePlayer() {
|
||||||
|
PlaybackSingleton.player?.let {
|
||||||
|
if (it.isPlaying) {
|
||||||
|
it.pause()
|
||||||
|
binding.content.mini.miniPlayPause.setImageResource(R.drawable.ic_play_arrow_24)
|
||||||
|
} else {
|
||||||
|
it.play()
|
||||||
|
binding.content.mini.miniPlayPause.setImageResource(R.drawable.ic_pause_24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,39 @@
|
||||||
package org.libre.agosto.p2play
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import org.libre.agosto.p2play.models.TokenModel
|
import org.libre.agosto.p2play.models.TokenModel
|
||||||
import org.libre.agosto.p2play.models.UserModel
|
import org.libre.agosto.p2play.models.UserModel
|
||||||
|
|
||||||
object ManagerSingleton {
|
object ManagerSingleton {
|
||||||
var context: Context?= null
|
var url: String? = null
|
||||||
var url: String?= null
|
|
||||||
var user: UserModel = UserModel()
|
var user: UserModel = UserModel()
|
||||||
var token: TokenModel = TokenModel()
|
var token: TokenModel = TokenModel()
|
||||||
// var keys:
|
var nfsw: Boolean = false
|
||||||
|
var videosCount: Int = 0
|
||||||
fun Toast(text: String?) {
|
lateinit var settings: SharedPreferences
|
||||||
if(this.context == null) { return }
|
lateinit var db: Database
|
||||||
android.widget.Toast.makeText(this.context, text, android.widget.Toast.LENGTH_SHORT).show()
|
fun toast(text: String?, context: Context) {
|
||||||
|
android.widget.Toast.makeText(context, text, android.widget.Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logout(){
|
fun logout() {
|
||||||
|
db.logout()
|
||||||
user = UserModel()
|
user = UserModel()
|
||||||
token = TokenModel()
|
token = TokenModel()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fun reloadSettings() {
|
||||||
|
val host = settings.getString("hostP2play", "")
|
||||||
|
val lastHost = settings.getString("last_host", "")
|
||||||
|
if (host != "") {
|
||||||
|
if (lastHost != host) {
|
||||||
|
logout()
|
||||||
|
}
|
||||||
|
url = host
|
||||||
|
}
|
||||||
|
|
||||||
|
nfsw = settings.getBoolean("show_nsfw", false)
|
||||||
|
videosCount = settings.getString("videos_count", "15")!!.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,54 +2,58 @@ package org.libre.agosto.p2play
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.preference.PreferenceManager
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import kotlinx.android.synthetic.main.activity_register.*
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import org.libre.agosto.p2play.ajax.Auth
|
import org.libre.agosto.p2play.ajax.Auth
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityRegisterBinding
|
||||||
|
|
||||||
class RegisterActivity : AppCompatActivity() {
|
class RegisterActivity : AppCompatActivity() {
|
||||||
private val _auth = Auth()
|
private val auth = Auth()
|
||||||
lateinit var settings: SharedPreferences
|
lateinit var settings: SharedPreferences
|
||||||
lateinit var client_id: String
|
lateinit var clientId: String
|
||||||
lateinit var client_secret: String
|
lateinit var clientSecret: String
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityRegisterBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_register)
|
binding = ActivityRegisterBinding.inflate(layoutInflater)
|
||||||
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
setTitle(R.string.registerActionBtn)
|
setTitle(R.string.registerActionBtn)
|
||||||
ManagerSingleton.context = this
|
|
||||||
|
|
||||||
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
client_id = settings.getString("client_id", "")
|
clientId = settings.getString("client_id", "")!!
|
||||||
client_secret = settings.getString("client_secret", "")
|
clientSecret = settings.getString("client_secret", "")!!
|
||||||
|
|
||||||
registerBtn.setOnClickListener { registerUser() }
|
binding.registerBtn.setOnClickListener { registerUser() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerUser(){
|
private fun registerUser() {
|
||||||
registerBtn.isEnabled = false
|
binding.registerBtn.isEnabled = false
|
||||||
val username = userText2.text.toString()
|
val username = binding.userText2.text.toString()
|
||||||
val password = passwordText2.text.toString()
|
val password = binding.passwordText2.text.toString()
|
||||||
val email = emailText.text.toString()
|
val email = binding.emailText.text.toString()
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper()==null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
|
}
|
||||||
|
|
||||||
val res = _auth.register(username, password, email)
|
val res = auth.register(username, password, email)
|
||||||
Log.d("Res register", res.toString())
|
Log.d("Res register", res.toString())
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
when (res) {
|
when (res) {
|
||||||
1 -> {
|
1 -> {
|
||||||
ManagerSingleton.Toast(getString(R.string.registerSuccess_msg))
|
ManagerSingleton.toast(getString(R.string.registerSuccess_msg), this)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
0 -> ManagerSingleton.Toast(getString(R.string.registerFailed_msg))
|
0 -> ManagerSingleton.toast(getString(R.string.registerFailed_msg), this)
|
||||||
-1 -> ManagerSingleton.Toast(getString(R.string.registerError_msg))
|
-1 -> ManagerSingleton.toast(getString(R.string.registerError_msg), this)
|
||||||
}
|
}
|
||||||
registerBtn.isEnabled = true
|
binding.registerBtn.isEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,82 @@
|
||||||
package org.libre.agosto.p2play
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
import android.opengl.Visibility
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.DownloadManager
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.support.v4.content.ContextCompat
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.webkit.WebChromeClient
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.MediaMetadata
|
||||||
|
import androidx.media3.common.Player
|
||||||
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
|
import androidx.media3.session.MediaController
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import kotlinx.android.synthetic.main.activity_reproductor.*
|
import org.libre.agosto.p2play.adapters.CommentariesAdapter
|
||||||
import org.libre.agosto.p2play.ajax.Actions
|
import org.libre.agosto.p2play.ajax.Actions
|
||||||
|
import org.libre.agosto.p2play.ajax.Comments
|
||||||
|
import org.libre.agosto.p2play.ajax.Videos
|
||||||
|
import org.libre.agosto.p2play.databinding.ActivityReproductorBinding
|
||||||
|
import org.libre.agosto.p2play.helpers.setFullscreen
|
||||||
|
import org.libre.agosto.p2play.models.CommentaryModel
|
||||||
|
import org.libre.agosto.p2play.models.DownloadFiles
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
import org.libre.agosto.p2play.singletons.PlaybackSingleton
|
||||||
|
|
||||||
class ReproductorActivity : AppCompatActivity() {
|
class ReproductorActivity : AppCompatActivity() {
|
||||||
lateinit var video:VideoModel
|
private val clientVideo: Videos = Videos()
|
||||||
private val _actions: Actions = Actions()
|
lateinit var video: VideoModel
|
||||||
|
lateinit var videoPlayback: VideoModel
|
||||||
|
private val actions: Actions = Actions()
|
||||||
|
private val client: Comments = Comments()
|
||||||
|
private val videos: Videos = Videos()
|
||||||
|
|
||||||
|
// Commentaries adapter values
|
||||||
|
private lateinit var recyclerView: RecyclerView
|
||||||
|
private lateinit var viewAdapter: RecyclerView.Adapter<*>
|
||||||
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
|
|
||||||
|
// Exoplayer
|
||||||
|
private lateinit var player: ExoPlayer
|
||||||
|
|
||||||
|
private lateinit var mediaControl: MediaController
|
||||||
|
|
||||||
|
// Fullscreen info
|
||||||
|
private var isFullscreen = false
|
||||||
|
|
||||||
|
// Resume info
|
||||||
|
private var isResume = false
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityReproductorBinding
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled", "SetTextI18n")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_reproductor)
|
binding = ActivityReproductorBinding.inflate(layoutInflater)
|
||||||
ManagerSingleton.context = this
|
val view = binding.root
|
||||||
|
setContentView(view)
|
||||||
|
|
||||||
|
val fullscreenButton = binding.exoPlayer.findViewById<ImageView>(R.id.exo_fullscreen_custom)
|
||||||
|
val fullscreenButton2 = binding.fullscreenPlayer.findViewById<ImageView>(R.id.exo_fullscreen_custom)
|
||||||
|
|
||||||
|
val videoView = binding.videoView
|
||||||
|
videoView.webChromeClient = WebClient()
|
||||||
videoView.settings.javaScriptEnabled = true
|
videoView.settings.javaScriptEnabled = true
|
||||||
videoView.settings.allowContentAccess = true
|
videoView.settings.allowContentAccess = true
|
||||||
videoView.settings.javaScriptCanOpenWindowsAutomatically = true
|
videoView.settings.javaScriptCanOpenWindowsAutomatically = true
|
||||||
|
@ -31,133 +86,464 @@ class ReproductorActivity : AppCompatActivity() {
|
||||||
videoView.settings.domStorageEnabled = true
|
videoView.settings.domStorageEnabled = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.video = this.intent.extras.getSerializable("video") as VideoModel
|
val resume = this.intent.extras?.getSerializable("resume")
|
||||||
tittleVideoTxt.text = this.video.name
|
if (resume == null) {
|
||||||
viewsTxt.text = this.video.views.toString() + ' ' + getString(R.string.view_text)
|
video = this.intent.extras?.getSerializable("video") as VideoModel
|
||||||
userTxt.text = this.video.username
|
isResume = false
|
||||||
descriptionVideoTxt.text = this.video.description
|
} else {
|
||||||
|
video = PlaybackSingleton.video!!
|
||||||
|
isResume = true
|
||||||
|
}
|
||||||
|
|
||||||
if(this.video.userImageUrl!="")
|
binding.tittleVideoTxt.text = this.video.name
|
||||||
Picasso.get().load("https://"+ManagerSingleton.url+this.video.userImageUrl).into(userImg)
|
binding.viewsTxt.text = "${this.video.views} ${getString(R.string.view_text)}"
|
||||||
videoView.loadUrl("https://"+ManagerSingleton.url+this.video.embedUrl)
|
binding.userTxt.text = this.video.username
|
||||||
Log.d("url", videoView.url)
|
binding.descriptionVideoTxt.text = this.video.description
|
||||||
}
|
val haveDescription = this.video.description.endsWith("...")
|
||||||
catch (err:Exception){
|
if (haveDescription) {
|
||||||
|
binding.showMoreBtn.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
binding.hostTxt.text = this.video.userHost
|
||||||
|
|
||||||
|
// Check if user had profile image
|
||||||
|
if (this.video.userImageUrl != "") {
|
||||||
|
Picasso.get().load("https://" + ManagerSingleton.url + this.video.userImageUrl).into(binding.userImg)
|
||||||
|
}
|
||||||
|
// Load the video
|
||||||
|
videoView.loadUrl("https://" + ManagerSingleton.url + this.video.embedUrl)
|
||||||
|
} catch (err: Exception) {
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
Log.d("Error", err?.message)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// subscribeBtn.setOnClickListener { ManagerSingleton.Toast(getString(R.string.comming)) }
|
viewManager = LinearLayoutManager(this)
|
||||||
subscribeBtn.setOnClickListener { subscribe() }
|
this.setDataComments(arrayListOf())
|
||||||
likeLayout.setOnClickListener { rate("like") }
|
|
||||||
dislikeLayout.setOnClickListener { rate("dislike") }
|
this.getComments()
|
||||||
|
|
||||||
|
binding.subscribeBtn.setOnClickListener { subscribe() }
|
||||||
|
binding.likeLayout.setOnClickListener { rate("like") }
|
||||||
|
binding.dislikeLayout.setOnClickListener { rate("dislike") }
|
||||||
|
binding.commentBox.commentaryBtn.setOnClickListener { makeComment() }
|
||||||
|
binding.showMoreBtn.setOnClickListener { getDescription() }
|
||||||
|
binding.shareLayout.setOnClickListener { shareIntent() }
|
||||||
|
binding.reportLayout.setOnClickListener { reportIntent() }
|
||||||
|
fullscreenButton.setOnClickListener { toggleFullscreen() }
|
||||||
|
fullscreenButton2.setOnClickListener { toggleFullscreen() }
|
||||||
|
binding.downloadLayout!!.setOnClickListener { downloadVideo() }
|
||||||
|
|
||||||
|
|
||||||
|
binding.userImg.setOnClickListener {
|
||||||
|
val intent = Intent(this, ChannelActivity::class.java)
|
||||||
|
intent.putExtra("channel", video.getChannel())
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncTask.execute {
|
||||||
|
videoPlayback = this.clientVideo.getVideo(this.video.uuid)
|
||||||
|
// TODO: Make this configurable
|
||||||
|
// val bufferSize = 1024 * 1024 // 1mb
|
||||||
|
// val allocator = DefaultAllocator(true, bufferSize)
|
||||||
|
// val loadControl = DefaultLoadControl.Builder()
|
||||||
|
// .setAllocator(allocator)
|
||||||
|
// .build()
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
try {
|
||||||
|
if (PlaybackSingleton.player == null || !PlaybackSingleton.player!!.playWhenReady) {
|
||||||
|
PlaybackSingleton.player = ExoPlayer.Builder(this)
|
||||||
|
//.setSeekBackIncrementMs(10000)
|
||||||
|
//.setSeekForwardIncrementMs(10000)
|
||||||
|
//.setLoadControl(loadControl)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
player = PlaybackSingleton.player!!
|
||||||
|
binding.exoPlayer.player = player
|
||||||
|
|
||||||
|
binding.exoPlayer
|
||||||
|
player.addListener(
|
||||||
|
object : Player.Listener {
|
||||||
|
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||||
|
super.onPlaybackStateChanged(playbackState)
|
||||||
|
val controls = binding.exoPlayer.findViewById<LinearLayout>(R.id.exo_center_controls)
|
||||||
|
if (playbackState == Player.STATE_BUFFERING || playbackState == Player.STATE_IDLE) {
|
||||||
|
controls.visibility = View.INVISIBLE
|
||||||
|
} else if (playbackState == Player.STATE_READY) {
|
||||||
|
controls.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
println("----- video --------")
|
||||||
|
println(videoPlayback.streamingData?.playlistUrl)
|
||||||
|
|
||||||
|
if (!isResume) {
|
||||||
|
val mediaItem = MediaItem.Builder()
|
||||||
|
.setUri(videoPlayback.streamingData?.playlistUrl!!)
|
||||||
|
.setMediaMetadata(
|
||||||
|
MediaMetadata.Builder()
|
||||||
|
.setArtist(videoPlayback.username)
|
||||||
|
.setTitle(videoPlayback.name)
|
||||||
|
.setArtworkUri(Uri.parse("https://${ManagerSingleton.url}${videoPlayback.thumbUrl}"))
|
||||||
|
.build(),
|
||||||
|
).build()
|
||||||
|
PlaybackSingleton.setData(mediaItem, video)
|
||||||
|
}
|
||||||
|
// Start the playback.
|
||||||
|
// TODO: Setting for autoplay
|
||||||
|
// player.play()
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun subscribe(){
|
private fun subscribe() {
|
||||||
val account = this.video.userUuid+"@"+this.video.userHost
|
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper() == null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
val res = this._actions.subscribe(ManagerSingleton.token.token, account)
|
}
|
||||||
|
val res = this.actions.subscribe(ManagerSingleton.token.token, video.getChannel())
|
||||||
if (res == 1) {
|
if (res == 1) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
ManagerSingleton.Toast(getString(R.string.subscribeMsg))
|
ManagerSingleton.toast(getString(R.string.subscribeMsg), this)
|
||||||
this.changeSubscribeBtn(true)
|
this.changeSubscribeBtn(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unSubscribe(){
|
private fun unSubscribe() {
|
||||||
val account = this.video.userUuid+"@"+this.video.userHost
|
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper() == null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
val res = this._actions.unSubscribe(ManagerSingleton.token.token, account)
|
}
|
||||||
|
val res = this.actions.unSubscribe(ManagerSingleton.token.token, video.getChannel())
|
||||||
if (res == 1) {
|
if (res == 1) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
ManagerSingleton.Toast(getString(R.string.unSubscribeMsg))
|
ManagerSingleton.toast(getString(R.string.unSubscribeMsg), this)
|
||||||
this.changeSubscribeBtn(false)
|
this.changeSubscribeBtn(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rate(rate: String){
|
private fun rate(rate: String) {
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper() == null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
val res = this._actions.rate(ManagerSingleton.token.token, this.video.id, rate)
|
}
|
||||||
|
val res = this.actions.rate(ManagerSingleton.token.token, this.video.id, rate)
|
||||||
if (res == 1) {
|
if (res == 1) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
ManagerSingleton.Toast(getString(R.string.rateMsg))
|
ManagerSingleton.toast(getString(R.string.rateMsg), this)
|
||||||
if(rate=="like"){
|
if (rate == "like") {
|
||||||
likeLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorLike))
|
binding.textViewLike.setTextColor(ContextCompat.getColor(this, R.color.colorLike))
|
||||||
dislikeLayout.background = null
|
binding.textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light))
|
||||||
}
|
} else if (rate == "dislike") {
|
||||||
else if(rate=="dislike"){
|
binding.textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.colorDislike))
|
||||||
dislikeLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorDislike))
|
binding.textViewLike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light))
|
||||||
likeLayout.background = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRate(){
|
private fun getRate() {
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper() == null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
val rate = this._actions.getRate(ManagerSingleton.token.token, this.video.id)
|
}
|
||||||
|
val rate = this.actions.getRate(ManagerSingleton.token.token, this.video.id)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
when (rate){
|
when (rate) {
|
||||||
"like" -> {
|
"like" -> {
|
||||||
likeLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorLike))
|
binding.textViewLike.setTextColor(ContextCompat.getColor(this, R.color.colorLike))
|
||||||
dislikeLayout.background = null
|
binding.textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light))
|
||||||
}
|
}
|
||||||
"dislike" -> {
|
"dislike" -> {
|
||||||
dislikeLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorDislike))
|
binding.textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.colorDislike))
|
||||||
likeLayout.background = null
|
binding.textViewLike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
likeLayout.background = null
|
binding.textViewLike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light))
|
||||||
dislikeLayout.background = null
|
binding.textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSubscription(){
|
private fun getSubscription() {
|
||||||
val account = this.video.userUuid+"@"+this.video.userHost
|
val account = this.video.nameChannel + "@" + this.video.userHost
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
if (Looper.myLooper() == null)
|
if (Looper.myLooper() == null) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
val isSubscribed = this._actions.getSubscription(ManagerSingleton.token.token, account)
|
}
|
||||||
|
val isSubscribed = this.actions.getSubscription(ManagerSingleton.token.token, account)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
this.changeSubscribeBtn(isSubscribed)
|
this.changeSubscribeBtn(isSubscribed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeSubscribeBtn(subscribed: Boolean){
|
private fun changeSubscribeBtn(subscribed: Boolean) {
|
||||||
if(subscribed){
|
if (subscribed) {
|
||||||
subscribeBtn.text = getText(R.string.unSubscribeBtn)
|
binding.subscribeBtn.text = getText(R.string.unSubscribeBtn)
|
||||||
subscribeBtn.setOnClickListener { this.unSubscribe() }
|
binding.subscribeBtn.setOnClickListener { this.unSubscribe() }
|
||||||
|
} else {
|
||||||
|
binding.subscribeBtn.text = getText(R.string.subscribeBtn)
|
||||||
|
binding.subscribeBtn.setOnClickListener { this.subscribe() }
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
subscribeBtn.text = getText(R.string.subscribeBtn)
|
|
||||||
subscribeBtn.setOnClickListener { this.subscribe() }
|
private fun setDataComments(data: ArrayList<CommentaryModel>) {
|
||||||
|
// Set data for RecyclerView
|
||||||
|
viewAdapter = CommentariesAdapter(data).setFragmentManager(supportFragmentManager)
|
||||||
|
|
||||||
|
recyclerView = findViewById<RecyclerView>(R.id.listCommentaries).apply {
|
||||||
|
// use this setting to improve performance if you know that changes
|
||||||
|
// in content do not change the layout size of the RecyclerView
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
// use a linear layout manager
|
||||||
|
layoutManager = viewManager
|
||||||
|
|
||||||
|
// specify an viewAdapter (see also next example)
|
||||||
|
adapter = viewAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getComments() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val data = this.client.getCommentaries(this.video.id)
|
||||||
|
runOnUiThread {
|
||||||
|
this.setDataComments(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeComment() {
|
||||||
|
if (binding.commentBox.commentaryText.text.toString() == "") {
|
||||||
|
ManagerSingleton.toast(getString(R.string.emptyCommentaryMsg), this)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val text = binding.commentBox.commentaryText.text.toString()
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = this.client.makeCommentary(ManagerSingleton.token.token, this.video.id, text)
|
||||||
|
runOnUiThread {
|
||||||
|
if (res) {
|
||||||
|
ManagerSingleton.toast(getString(R.string.makedCommentaryMsg), this)
|
||||||
|
binding.commentBox.commentaryText.text?.clear()
|
||||||
|
this.getComments()
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(getString(R.string.errorCommentaryMsg), this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if(ManagerSingleton.user.status == 1) {
|
if (ManagerSingleton.user.status == 1) {
|
||||||
this.getRate()
|
this.getRate()
|
||||||
this.getSubscription()
|
this.getSubscription()
|
||||||
actionsLayout.visibility = View.VISIBLE
|
binding.actionsLayout.visibility = View.VISIBLE
|
||||||
subscribeBtn.visibility = View.VISIBLE
|
binding.subscribeBtn.visibility = View.VISIBLE
|
||||||
|
binding.commentBox.commentaryLayout.visibility = View.VISIBLE
|
||||||
|
if (ManagerSingleton.user.avatar != "") {
|
||||||
|
Picasso.get().load("https://" + ManagerSingleton.url + ManagerSingleton.user.avatar).into(binding.commentBox.userImgCom)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.commentBox.commentaryLayout.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDescription() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val fullDescription = this.videos.fullDescription(this.video.id)
|
||||||
|
runOnUiThread {
|
||||||
|
binding.descriptionVideoTxt.text = fullDescription
|
||||||
|
binding.showMoreBtn.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shareIntent() {
|
||||||
|
val sendIntent: Intent = Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_TEXT, "${video.name} ${video.getVideoUrl()}")
|
||||||
|
type = "text/plain"
|
||||||
|
}
|
||||||
|
startActivity(Intent.createChooser(sendIntent, resources.getText(R.string.shareBtn)))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reportIntent() {
|
||||||
|
val builder = AlertDialog.Builder(this)
|
||||||
|
// Get the layout inflater
|
||||||
|
val dialog = layoutInflater.inflate(R.layout.report_dialog, null)
|
||||||
|
|
||||||
|
val inputReason = dialog.findViewById<EditText>(R.id.reportText)
|
||||||
|
|
||||||
|
// Inflate and set the layout for the dialog
|
||||||
|
// Pass null as the parent view because its going in the dialog layout
|
||||||
|
builder.setView(dialog)
|
||||||
|
.setTitle(R.string.reportDialog)
|
||||||
|
// Add action buttons
|
||||||
|
.setPositiveButton(R.string.reportBtn) { _, _ ->
|
||||||
|
val reason = inputReason.text.toString()
|
||||||
|
reportVideo(reason)
|
||||||
|
}
|
||||||
|
.setNegativeButton("Cancel") { dialog, _ ->
|
||||||
|
dialog.run { cancel() }
|
||||||
|
}
|
||||||
|
val alertDialog = builder.create()
|
||||||
|
alertDialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reportVideo(reason: String) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = actions.reportVideo(video.id, reason, ManagerSingleton.token.token)
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
if (res) {
|
||||||
|
ManagerSingleton.toast(getText(R.string.reportDialogMsg).toString(), this)
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(getText(R.string.errorMsg).toString(), this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleFullscreen() {
|
||||||
|
if (isFullscreen) {
|
||||||
|
binding.nonFullScreen.visibility = View.VISIBLE
|
||||||
|
binding.fullScreenExo.visibility = View.GONE
|
||||||
|
binding.exoPlayer.player = player
|
||||||
|
binding.fullscreenPlayer.player = null
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||||
|
|
||||||
|
val attrs = window.attributes
|
||||||
|
attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
|
||||||
|
attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON.inv()
|
||||||
|
window.attributes = attrs
|
||||||
|
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
|
||||||
|
|
||||||
|
isFullscreen = false
|
||||||
|
} else {
|
||||||
|
val matchParent = WindowManager.LayoutParams.MATCH_PARENT
|
||||||
|
|
||||||
|
binding.nonFullScreen.visibility = View.GONE
|
||||||
|
binding.fullScreenExo.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
binding.exoPlayer.player = null
|
||||||
|
binding.fullscreenPlayer.player = player
|
||||||
|
|
||||||
|
setFullscreen(window)
|
||||||
|
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||||
|
isFullscreen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadVideo() {
|
||||||
|
val downloadFile = videoPlayback.streamingData?.downloadFiles?.first()
|
||||||
|
if (downloadFile != null) {
|
||||||
|
val manager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||||
|
val request = DownloadManager.Request(Uri.parse(downloadFile.url))
|
||||||
|
val fileName = "${videoPlayback.name}-${downloadFile.resolution}.${downloadFile.url.split('.').last()}"
|
||||||
|
try {
|
||||||
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||||
|
.setTitle(fileName)
|
||||||
|
.setDescription(getString(R.string.downloadText))
|
||||||
|
.setDestinationInExternalPublicDir(
|
||||||
|
android.os.Environment.DIRECTORY_DOWNLOADS,
|
||||||
|
fileName
|
||||||
|
)
|
||||||
|
manager.enqueue(request)
|
||||||
|
ManagerSingleton.toast(getString(R.string.downloadStarted), this)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
ManagerSingleton.toast(getString(R.string.downloadFailed), this)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(getString(R.string.downloadFailed), this)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
if (!player.isPlaying) {
|
||||||
|
PlaybackSingleton.release()
|
||||||
|
}
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inner class WebClient : WebChromeClient() {
|
||||||
|
private var mCustomView: View? = null
|
||||||
|
private var mCustomViewCallback: WebChromeClient.CustomViewCallback? = null
|
||||||
|
private var mOriginalOrientation: Int = 0
|
||||||
|
private var mOriginalSystemUiVisibility: Int = 0
|
||||||
|
|
||||||
|
override fun getDefaultVideoPoster(): Bitmap? {
|
||||||
|
AsyncTask.execute {
|
||||||
|
this@ReproductorActivity.actions.watchVideo(this@ReproductorActivity.video.id, ManagerSingleton.token.token)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (mCustomView == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
BitmapFactory.decodeResource(this@ReproductorActivity.resources, 2130837573)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onHideCustomView() {
|
||||||
|
try {
|
||||||
|
this@ReproductorActivity.binding.nonFullScreen.visibility = View.VISIBLE
|
||||||
|
this@ReproductorActivity.binding.fullScreen.visibility = View.GONE
|
||||||
|
this@ReproductorActivity.binding.fullScreen.removeView(this.mCustomView)
|
||||||
|
this.mCustomView = null
|
||||||
|
|
||||||
|
this.mCustomViewCallback!!.onCustomViewHidden()
|
||||||
|
this.mCustomViewCallback = null
|
||||||
|
|
||||||
|
this@ReproductorActivity.requestedOrientation = this.mOriginalOrientation
|
||||||
|
// this@ReproductorActivity.window.decorView.systemUiVisibility = this.mOriginalSystemUiVisibility
|
||||||
|
|
||||||
|
val attrs = this@ReproductorActivity.window.attributes
|
||||||
|
attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
|
||||||
|
attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON.inv()
|
||||||
|
window.attributes = attrs
|
||||||
|
this@ReproductorActivity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShowCustomView(paramView: View, paramCustomViewCallback: WebChromeClient.CustomViewCallback) {
|
||||||
|
if (this.mCustomView != null) {
|
||||||
|
this.onHideCustomView()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.mCustomView = paramView
|
||||||
|
this.mOriginalSystemUiVisibility = this@ReproductorActivity.window.decorView.systemUiVisibility
|
||||||
|
this.mOriginalOrientation = this@ReproductorActivity.requestedOrientation
|
||||||
|
this.mCustomViewCallback = paramCustomViewCallback
|
||||||
|
val matchParent = WindowManager.LayoutParams.MATCH_PARENT
|
||||||
|
|
||||||
|
this@ReproductorActivity.binding.nonFullScreen.visibility = View.GONE
|
||||||
|
this@ReproductorActivity.binding.fullScreen.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
this@ReproductorActivity.binding.fullScreen.addView(paramView, FrameLayout.LayoutParams(matchParent, matchParent))
|
||||||
|
|
||||||
|
setFullscreen(this@ReproductorActivity.window)
|
||||||
|
|
||||||
|
this@ReproductorActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
package org.libre.agosto.p2play
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.media.RingtoneManager
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.preference.ListPreference
|
|
||||||
import android.preference.Preference
|
|
||||||
import android.preference.PreferenceActivity
|
|
||||||
import android.preference.PreferenceFragment
|
|
||||||
import android.preference.PreferenceManager
|
|
||||||
import android.preference.RingtonePreference
|
|
||||||
import android.text.TextUtils
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.MenuItem
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A [PreferenceActivity] that presents a set of application settings. On
|
|
||||||
* handset devices, settings are presented as a single list. On tablets,
|
|
||||||
* settings are split by category, with category headers shown to the left of
|
|
||||||
* the list of settings.
|
|
||||||
*
|
|
||||||
* See [Android Design: Settings](http://developer.android.com/design/patterns/settings.html)
|
|
||||||
* for design guidelines and the [Settings API Guide](http://developer.android.com/guide/topics/ui/settings.html)
|
|
||||||
* for more information on developing a Settings UI.
|
|
||||||
*/
|
|
||||||
class SettingsActivity : AppCompatPreferenceActivity() {
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
ManagerSingleton.context = this
|
|
||||||
setupActionBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
super.onBackPressed()
|
|
||||||
ManagerSingleton.Toast(getString(R.string.pref_message_exit))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the [android.app.ActionBar], if the API is available.
|
|
||||||
*/
|
|
||||||
private fun setupActionBar() {
|
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
override fun onIsMultiPane(): Boolean {
|
|
||||||
return isXLargeTablet(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
|
||||||
override fun onBuildHeaders(target: List<PreferenceActivity.Header>) {
|
|
||||||
loadHeadersFromResource(R.xml.pref_headers, target)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method stops fragment injection in malicious applications.
|
|
||||||
* Make sure to deny any unknown fragments here.
|
|
||||||
*/
|
|
||||||
override fun isValidFragment(fragmentName: String): Boolean {
|
|
||||||
return PreferenceFragment::class.java.name == fragmentName
|
|
||||||
|| GeneralPreferenceFragment::class.java.name == fragmentName
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This fragment shows general preferences only. It is used when the
|
|
||||||
* activity is showing a two-pane settings UI.
|
|
||||||
*/
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
|
||||||
class GeneralPreferenceFragment : PreferenceFragment() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
addPreferencesFromResource(R.xml.pref_general)
|
|
||||||
setHasOptionsMenu(true)
|
|
||||||
|
|
||||||
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
|
|
||||||
// to their values. When their values change, their summaries are
|
|
||||||
// updated to reflect the new value, per the Android Design
|
|
||||||
// guidelines.
|
|
||||||
bindPreferenceSummaryToValue(findPreference("hostP2play"))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
val id = item.itemId
|
|
||||||
if (id == android.R.id.home) {
|
|
||||||
startActivity(Intent(activity, SettingsActivity::class.java))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A preference value change listener that updates the preference's summary
|
|
||||||
* to reflect its new value.
|
|
||||||
*/
|
|
||||||
private val sBindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, value ->
|
|
||||||
val stringValue = value.toString()
|
|
||||||
|
|
||||||
if (preference is ListPreference) {
|
|
||||||
// For list preferences, look up the correct display value in
|
|
||||||
// the preference's 'entries' list.
|
|
||||||
val listPreference = preference
|
|
||||||
val index = listPreference.findIndexOfValue(stringValue)
|
|
||||||
|
|
||||||
// Set the summary to reflect the new value.
|
|
||||||
preference.setSummary(
|
|
||||||
if (index >= 0)
|
|
||||||
listPreference.entries[index]
|
|
||||||
else
|
|
||||||
null)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// For all other preferences, set the summary to the value's
|
|
||||||
// simple string representation.
|
|
||||||
preference.summary = stringValue
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to determine if the device has an extra-large screen. For
|
|
||||||
* example, 10" tablets are extra-large.
|
|
||||||
*/
|
|
||||||
private fun isXLargeTablet(context: Context): Boolean {
|
|
||||||
return context.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_XLARGE
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a preference's summary to its value. More specifically, when the
|
|
||||||
* preference's value is changed, its summary (line of text below the
|
|
||||||
* preference title) is updated to reflect the value. The summary is also
|
|
||||||
* immediately updated upon calling this method. The exact display format is
|
|
||||||
* dependent on the type of preference.
|
|
||||||
|
|
||||||
* @see .sBindPreferenceSummaryToValueListener
|
|
||||||
*/
|
|
||||||
private fun bindPreferenceSummaryToValue(preference: Preference) {
|
|
||||||
// Set the listener to watch for value changes.
|
|
||||||
preference.onPreferenceChangeListener = sBindPreferenceSummaryToValueListener
|
|
||||||
|
|
||||||
// Trigger the listener immediately with the preference's
|
|
||||||
// current value.
|
|
||||||
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
|
|
||||||
PreferenceManager
|
|
||||||
.getDefaultSharedPreferences(preference.context)
|
|
||||||
.getString(preference.key, ""))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
|
||||||
|
class SettingsActivity2 : AppCompatActivity() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.settings_activity)
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
supportFragmentManager
|
||||||
|
.beginTransaction()
|
||||||
|
.replace(R.id.settings, SettingsFragment())
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
ManagerSingleton.reloadSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package org.libre.agosto.p2play
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
import org.libre.agosto.p2play.ajax.Auth
|
||||||
|
import java.lang.Exception
|
||||||
|
|
||||||
|
class SplashActivity : AppCompatActivity() {
|
||||||
|
lateinit var settings: SharedPreferences
|
||||||
|
val client: Auth = Auth()
|
||||||
|
val db = Database(this)
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_splash)
|
||||||
|
|
||||||
|
settings = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
ManagerSingleton.settings = settings
|
||||||
|
ManagerSingleton.db = db
|
||||||
|
|
||||||
|
ManagerSingleton.reloadSettings()
|
||||||
|
|
||||||
|
val host = settings.getString("hostP2play", "")
|
||||||
|
val lastHost = settings.getString("last_host", "")
|
||||||
|
if (host != "") {
|
||||||
|
if (lastHost != host) {
|
||||||
|
Handler().postDelayed({
|
||||||
|
startHostActivity()
|
||||||
|
}, 2000)
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.url = host
|
||||||
|
checkUser()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Handler().postDelayed({
|
||||||
|
startHostActivity()
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkUser() {
|
||||||
|
Log.d("was", "Checked")
|
||||||
|
try {
|
||||||
|
val token = db.getToken()
|
||||||
|
val user = db.getUser()
|
||||||
|
AsyncTask.execute {
|
||||||
|
if (Looper.myLooper() == null) {
|
||||||
|
Looper.prepare()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.status == 1 && user.status == 1) {
|
||||||
|
val clientId = settings.getString("client_id", "")!!
|
||||||
|
val clientSecret = settings.getString("client_secret", "")!!
|
||||||
|
|
||||||
|
val newToken = client.refreshToken(token, clientId, clientSecret)
|
||||||
|
|
||||||
|
when (token.status.toString()) {
|
||||||
|
"1" -> {
|
||||||
|
db.newToken(newToken)
|
||||||
|
ManagerSingleton.token = newToken
|
||||||
|
ManagerSingleton.user = user
|
||||||
|
}
|
||||||
|
else -> ManagerSingleton.logout()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.logout()
|
||||||
|
}
|
||||||
|
|
||||||
|
startApp()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
Handler().postDelayed({
|
||||||
|
startApp()
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startApp() {
|
||||||
|
runOnUiThread {
|
||||||
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
this.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startHostActivity() {
|
||||||
|
runOnUiThread {
|
||||||
|
val intent = Intent(this, HostActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
this.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package org.libre.agosto.p2play.adapters
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
import org.libre.agosto.p2play.AccountActivity
|
||||||
|
import org.libre.agosto.p2play.ChannelActivity
|
||||||
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
|
import org.libre.agosto.p2play.R
|
||||||
|
import org.libre.agosto.p2play.ajax.Actions
|
||||||
|
import org.libre.agosto.p2play.models.ChannelModel
|
||||||
|
|
||||||
|
class ChannelAdapter(private val myDataset: ArrayList<ChannelModel>): RecyclerView.Adapter<ChannelAdapter.ViewHolder>() {
|
||||||
|
private val actionsService = Actions()
|
||||||
|
lateinit var parent: FragmentActivity
|
||||||
|
|
||||||
|
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
// Define click listener for the ViewHolder's View
|
||||||
|
val channelImage: ImageView = view.findViewById(R.id.channelImage)
|
||||||
|
val channelName: TextView = view.findViewById(R.id.channelName)
|
||||||
|
val channelDescription: TextView = view.findViewById(R.id.channelDescription)
|
||||||
|
val subscribeButton: Button = view.findViewById(R.id.subscribeBtn)
|
||||||
|
val context: Context = view.context
|
||||||
|
var isSubscribed: Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelAdapter.ViewHolder {
|
||||||
|
val view = LayoutInflater.from(parent.context)
|
||||||
|
.inflate(R.layout.view_channel, parent, false) as View
|
||||||
|
|
||||||
|
return ViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = myDataset.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
holder.channelName.text = myDataset[position].name
|
||||||
|
holder.channelDescription.text = myDataset[position].description
|
||||||
|
|
||||||
|
if (myDataset[position].channelImg != "") {
|
||||||
|
Picasso.get().load("https://${ManagerSingleton.url}${myDataset[position].channelImg}").into(holder.channelImage)
|
||||||
|
} else {
|
||||||
|
holder.channelImage.setImageResource(R.drawable.default_avatar)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ManagerSingleton.user.status == 1) {
|
||||||
|
getSubscription(myDataset[position], holder)
|
||||||
|
} else {
|
||||||
|
holder.subscribeButton.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.subscribeButton.setOnClickListener {
|
||||||
|
this.subscribeAction(myDataset[position], holder)
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.channelImage.setOnClickListener {
|
||||||
|
this.launchChannelActivity(myDataset[position].getAccount())
|
||||||
|
}
|
||||||
|
holder.channelName.setOnClickListener {
|
||||||
|
this.launchChannelActivity(myDataset[position].getAccount())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSubscription(channel: ChannelModel, holder: ViewHolder) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
holder.isSubscribed = actionsService.getSubscription(ManagerSingleton.token.token, channel.getAccount())
|
||||||
|
parent.runOnUiThread {
|
||||||
|
if (holder.isSubscribed) {
|
||||||
|
holder.subscribeButton.text = parent.getText(R.string.unSubscribeBtn)
|
||||||
|
} else {
|
||||||
|
holder.subscribeButton.text = parent.getText(R.string.subscribeBtn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribe(channel: ChannelModel, holder: ViewHolder) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = actionsService.subscribe(ManagerSingleton.token.token, channel.getAccount())
|
||||||
|
parent.runOnUiThread {
|
||||||
|
if (res == 1) {
|
||||||
|
holder.subscribeButton.text = parent.getString(R.string.unSubscribeBtn)
|
||||||
|
ManagerSingleton.toast(parent.getString(R.string.subscribeMsg), parent)
|
||||||
|
getSubscription(channel, holder)
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(parent.getString(R.string.errorMsg), parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unSubscribe(channel: ChannelModel, holder: ViewHolder) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = actionsService.unSubscribe(ManagerSingleton.token.token, channel.getAccount())
|
||||||
|
parent.runOnUiThread {
|
||||||
|
if (res == 1) {
|
||||||
|
holder.subscribeButton.text = parent.getString(R.string.subscribeBtn)
|
||||||
|
ManagerSingleton.toast(parent.getString(R.string.unSubscribeMsg), parent)
|
||||||
|
getSubscription(channel, holder)
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(parent.getString(R.string.errorMsg), parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribeAction(channel: ChannelModel, holder: ViewHolder) {
|
||||||
|
if (holder.isSubscribed) {
|
||||||
|
unSubscribe(channel, holder)
|
||||||
|
} else {
|
||||||
|
subscribe(channel, holder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchChannelActivity (channelId: String) {
|
||||||
|
val intent = Intent(parent, ChannelActivity::class.java)
|
||||||
|
intent.putExtra("channel", channelId)
|
||||||
|
parent.startActivity(intent)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
package org.libre.agosto.p2play.adapters
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Html
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.fragment.app.FragmentTransaction
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
import org.libre.agosto.p2play.AccountActivity
|
||||||
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
|
import org.libre.agosto.p2play.R
|
||||||
|
import org.libre.agosto.p2play.dialogs.ThreadDialog
|
||||||
|
import org.libre.agosto.p2play.models.CommentaryModel
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
class CommentariesAdapter(private val myDataset: ArrayList<CommentaryModel>) :
|
||||||
|
RecyclerView.Adapter<CommentariesAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private lateinit var fragmentManager: FragmentManager
|
||||||
|
|
||||||
|
fun setFragmentManager(manager: FragmentManager): CommentariesAdapter {
|
||||||
|
this.fragmentManager = manager
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide a reference to the views for each data item
|
||||||
|
// Complex data items may need more than one view per item, and
|
||||||
|
// you provide access to all the views for a data item in a view holder.
|
||||||
|
// Each data item is just a string in this case that is shown in a TextView.
|
||||||
|
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val userImg: ImageView
|
||||||
|
val username: TextView
|
||||||
|
val commentary: TextView
|
||||||
|
val replyBtn: TextView
|
||||||
|
val context: Context
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Define click listener for the ViewHolder's View
|
||||||
|
username = view.findViewById(R.id.userTxt)
|
||||||
|
commentary = view.findViewById(R.id.userCommentary)
|
||||||
|
userImg = view.findViewById(R.id.userCommentImg)
|
||||||
|
replyBtn = view.findViewById(R.id.replyBtn)
|
||||||
|
context = view.context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new views (invoked by the layout manager)
|
||||||
|
override fun onCreateViewHolder(
|
||||||
|
parent: ViewGroup,
|
||||||
|
viewType: Int,
|
||||||
|
): ViewHolder {
|
||||||
|
// create a new view
|
||||||
|
val view = LayoutInflater.from(parent.context)
|
||||||
|
.inflate(R.layout.view_commentary, parent, false) as View
|
||||||
|
|
||||||
|
// set the view's size, margins, paddings and layout parameters
|
||||||
|
return ViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the contents of a view (invoked by the layout manager)
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
// - get element from your dataset at this position
|
||||||
|
// - replace the contents of the view with that element
|
||||||
|
holder.username.text = myDataset[position].username
|
||||||
|
|
||||||
|
// holder.userImg.setOnClickListener {
|
||||||
|
// val intent = Intent(holder.context, ChannelActivity::class.java)
|
||||||
|
// intent.putExtra("channel", myDataset[position])
|
||||||
|
// holder.context.startActivity(intent)
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (myDataset[position].userImageUrl != "") {
|
||||||
|
Picasso.get().load("https://" + ManagerSingleton.url + myDataset[position].userImageUrl).into(holder.userImg)
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.commentary.text = Html.fromHtml(myDataset[position].commentary)
|
||||||
|
holder.replyBtn.setOnClickListener { this.initRepliesDialog(myDataset[position]) }
|
||||||
|
|
||||||
|
if (myDataset[position].replies > 0) {
|
||||||
|
holder.replyBtn.text = holder.itemView.context.getString(R.string.see_replies, myDataset[position].replies)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support for view and account (is different than a video channel)
|
||||||
|
holder.userImg.setOnClickListener {
|
||||||
|
val intent = Intent(holder.context, AccountActivity::class.java)
|
||||||
|
intent.putExtra("accountId", myDataset[position].getAccount())
|
||||||
|
holder.context.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the size of your dataset (invoked by the layout manager)
|
||||||
|
override fun getItemCount() = myDataset.size
|
||||||
|
|
||||||
|
private fun initRepliesDialog(commentData: CommentaryModel) {
|
||||||
|
val dialog = ThreadDialog()
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putSerializable("comment", commentData as Serializable)
|
||||||
|
|
||||||
|
dialog.arguments = bundle
|
||||||
|
dialog.fragmentManager2 = this.fragmentManager
|
||||||
|
val transaction = fragmentManager.beginTransaction()
|
||||||
|
// For a polished look, specify a transition animation.
|
||||||
|
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||||
|
// To make it fullscreen, use the 'content' root view as the container
|
||||||
|
// for the fragment, which is always the root view for the activity.
|
||||||
|
transaction
|
||||||
|
.add(android.R.id.content, dialog)
|
||||||
|
.addToBackStack("comments")
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,55 +1,45 @@
|
||||||
package org.libre.agosto.p2play.adapters
|
package org.libre.agosto.p2play.adapters
|
||||||
|
|
||||||
import android.app.Activity
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import org.libre.agosto.p2play.MainActivity
|
import org.libre.agosto.p2play.AccountActivity
|
||||||
|
import org.libre.agosto.p2play.ChannelActivity
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
import org.libre.agosto.p2play.R
|
import org.libre.agosto.p2play.R
|
||||||
import org.libre.agosto.p2play.ReproductorActivity
|
import org.libre.agosto.p2play.ReproductorActivity
|
||||||
|
import org.libre.agosto.p2play.helpers.mapSeconds
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
import java.io.InputStream
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.net.URL
|
|
||||||
|
|
||||||
class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
|
class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
|
||||||
RecyclerView.Adapter<VideosAdapter.ViewHolder>() {
|
RecyclerView.Adapter<VideosAdapter.ViewHolder>() {
|
||||||
|
|
||||||
// Provide a reference to the views for each data item
|
// Provide a reference to the views for each data item
|
||||||
// Complex data items may need more than one view per item, and
|
// Complex data items may need more than one view per item, and
|
||||||
// you provide access to all the views for a data item in a view holder.
|
// you provide access to all the views for a data item in a view holder.
|
||||||
// Each data item is just a string in this case that is shown in a TextView.
|
// Each data item is just a string in this case that is shown in a TextView.
|
||||||
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view){
|
class ViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
val thumb: ImageView
|
val thumb: ImageView = view.findViewById(R.id.thumb)
|
||||||
val userImg: ImageView
|
val userImg: ImageView = view.findViewById(R.id.userImg)
|
||||||
val tittle: TextView
|
val title: TextView = view.findViewById(R.id.tittleTxt)
|
||||||
val description: TextView
|
val description: TextView = view.findViewById(R.id.descriptionTxt)
|
||||||
|
val context: Context = view.context
|
||||||
init {
|
val duration: TextView = view.findViewById(R.id.duration)
|
||||||
// Define click listener for the ViewHolder's View
|
val isLive: TextView = view.findViewById(R.id.isLive)
|
||||||
tittle = view.findViewById(R.id.tittleTxt)
|
|
||||||
description = view.findViewById(R.id.descriptionTxt)
|
|
||||||
thumb = view.findViewById(R.id.thumb)
|
|
||||||
userImg = view.findViewById(R.id.userImg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create new views (invoked by the layout manager)
|
// Create new views (invoked by the layout manager)
|
||||||
override fun onCreateViewHolder(parent: ViewGroup,
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
viewType: Int): VideosAdapter.ViewHolder {
|
|
||||||
// create a new view
|
// create a new view
|
||||||
val view = LayoutInflater.from(parent.context)
|
val view = LayoutInflater.from(parent.context)
|
||||||
.inflate(R.layout.view_video, parent, false) as View
|
.inflate(R.layout.view_video, parent, false) as View
|
||||||
// set the view's size, margins, paddings and layout parameters
|
// set the view's size, margins, paddings and layout parameters
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
@ -58,22 +48,57 @@ class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
// - get element from your dataset at this position
|
// - get element from your dataset at this position
|
||||||
// - replace the contents of the view with that element
|
// - replace the contents of the view with that element
|
||||||
holder.tittle.text = myDataset[position].name
|
holder.title.text = myDataset[position].name
|
||||||
Picasso.get().load("https://"+ManagerSingleton.url+myDataset[position].thumbUrl).into(holder.thumb)
|
holder.title.setOnClickListener {
|
||||||
holder.thumb.setOnClickListener {
|
this.launchChannelActivity(myDataset[position] as Serializable, holder.context)
|
||||||
val intent = Intent(ManagerSingleton.context, ReproductorActivity::class.java)
|
}
|
||||||
intent.putExtra("video", myDataset[position] as Serializable)
|
Picasso.get().load("https://" + ManagerSingleton.url + myDataset[position].thumbUrl).into(holder.thumb)
|
||||||
ManagerSingleton.context!!.startActivity(intent)
|
holder.thumb.setOnClickListener {
|
||||||
|
this.launchChannelActivity(myDataset[position] as Serializable, holder.context)
|
||||||
}
|
}
|
||||||
if(myDataset[position].userImageUrl!="")
|
|
||||||
Picasso.get().load("https://"+ManagerSingleton.url+myDataset[position].userImageUrl).into(holder.userImg);
|
|
||||||
|
|
||||||
val viewsText = ManagerSingleton.context!!.getString(R.string.view_text)
|
holder.userImg.setOnClickListener {
|
||||||
val timeText = ManagerSingleton.context!!.getString(R.string.time_text)
|
val intent = Intent(holder.context, ChannelActivity::class.java)
|
||||||
holder.description.text = myDataset[position].username+" - "+myDataset[position].views+" "+viewsText+" - "+myDataset[position].duration+" "+timeText
|
intent.putExtra("channel", myDataset[position].getChannel())
|
||||||
|
holder.context.startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myDataset[position].userImageUrl != "") {
|
||||||
|
Picasso.get().load("https://" + ManagerSingleton.url + myDataset[position].userImageUrl).into(holder.userImg)
|
||||||
|
} else {
|
||||||
|
Picasso.get().load(R.drawable.default_avatar).into(holder.userImg)
|
||||||
|
}
|
||||||
|
|
||||||
|
val viewsText = holder.context.getString(R.string.view_text)
|
||||||
|
val seconds = myDataset[position].duration.toInt()
|
||||||
|
val timeString = mapSeconds(seconds)
|
||||||
|
|
||||||
|
holder.duration.text = timeString
|
||||||
|
|
||||||
|
holder.description.text = myDataset[position].username + " - " + myDataset[position].views + " " + viewsText
|
||||||
|
|
||||||
|
if (myDataset[position].isLive) {
|
||||||
|
holder.isLive.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the size of your dataset (invoked by the layout manager)
|
// Return the size of your dataset (invoked by the layout manager)
|
||||||
override fun getItemCount() = myDataset.size
|
override fun getItemCount() = myDataset.size
|
||||||
}
|
|
||||||
|
fun clearData() {
|
||||||
|
myDataset.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addData(newItems: ArrayList<VideoModel>) {
|
||||||
|
val lastPos = myDataset.size
|
||||||
|
myDataset.addAll(newItems)
|
||||||
|
notifyItemRangeInserted(lastPos, newItems.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchChannelActivity(data: Serializable, context: Context) {
|
||||||
|
val intent = Intent(context, ReproductorActivity::class.java)
|
||||||
|
intent.putExtra("video", data)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.libre.agosto.p2play.ajax
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import org.libre.agosto.p2play.models.AccountModel
|
||||||
|
import org.libre.agosto.p2play.models.ChannelModel
|
||||||
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
class Accounts : Client() {
|
||||||
|
|
||||||
|
fun get(accountId: String): AccountModel {
|
||||||
|
val con = this.newCon("accounts/$accountId", "GET")
|
||||||
|
lateinit var account: AccountModel
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
account = Gson().fromJson(response, AccountModel::class.java)
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return account
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getChannels(accountId: String): ArrayList<ChannelModel> {
|
||||||
|
val con = this.newCon("accounts/$accountId/video-channels", "GET")
|
||||||
|
val channels = arrayListOf<ChannelModel>()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
when (data.nextName()) {
|
||||||
|
"data" -> {
|
||||||
|
data.beginArray()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val channel = ChannelModel()
|
||||||
|
channel.parseChannel(data)
|
||||||
|
channels.add(channel)
|
||||||
|
}
|
||||||
|
data.endArray()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,11 +3,11 @@ package org.libre.agosto.p2play.ajax
|
||||||
import android.util.JsonReader
|
import android.util.JsonReader
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
class Actions: Client() {
|
class Actions : Client() {
|
||||||
|
|
||||||
fun subscribe(token: String, account: String):Int{
|
fun subscribe(token: String, account: String): Int {
|
||||||
var con=this._newCon("users/me/subscriptions","POST", token)
|
val con = this.newCon("users/me/subscriptions", "POST", token)
|
||||||
val params:String= "uri=$account"
|
val params: String = "uri=$account"
|
||||||
con.outputStream.write(params.toByteArray())
|
con.outputStream.write(params.toByteArray())
|
||||||
var response = 0
|
var response = 0
|
||||||
|
|
||||||
|
@ -15,65 +15,66 @@ class Actions: Client() {
|
||||||
if (con.responseCode == 204) {
|
if (con.responseCode == 204) {
|
||||||
response = 1
|
response = 1
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
response = -1
|
response = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unSubscribe(token: String, account: String):Int{
|
fun unSubscribe(token: String, account: String): Int {
|
||||||
var con=this._newCon("users/me/subscriptions/$account","DELETE", token)
|
val con = this.newCon("users/me/subscriptions/$account", "DELETE", token)
|
||||||
var response = 0
|
var response = 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 204) {
|
if (con.responseCode == 204) {
|
||||||
response = 1
|
response = 1
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
response = -1
|
response = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSubscription(token: String, account: String): Boolean{
|
fun getSubscription(token: String, account: String): Boolean {
|
||||||
var con=this._newCon("users/me/subscriptions/exist?uris=$account","GET", token)
|
val con = this.newCon("users/me/subscriptions/exist?uris=$account", "GET", token)
|
||||||
var isSubscribed = false
|
var isSubscribed = false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 200) {
|
if (con.responseCode == 200) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val response = InputStreamReader(con.inputStream)
|
||||||
var data = JsonReader(response)
|
val data = JsonReader(response)
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
while (data.hasNext()){
|
while (data.hasNext()) {
|
||||||
val key = data.nextName()
|
val key = data.nextName()
|
||||||
when (key.toString()) {
|
when (key.toString()) {
|
||||||
account->{
|
account -> {
|
||||||
isSubscribed = data.nextBoolean()
|
isSubscribed = data.nextBoolean()
|
||||||
}
|
}
|
||||||
else->{
|
else -> {
|
||||||
data.skipValue()
|
data.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
data.close()
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
isSubscribed = false
|
isSubscribed = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return isSubscribed
|
return isSubscribed
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rate(token: String, id_video: Int, rate: String):Int{
|
fun rate(token: String, id_video: Int, rate: String): Int {
|
||||||
var con=this._newCon("videos/$id_video/rate","PUT", token)
|
val con = this.newCon("videos/$id_video/rate", "PUT", token)
|
||||||
val params:String= "rating=$rate"
|
val params = "rating=$rate"
|
||||||
con.outputStream.write(params.toByteArray())
|
con.outputStream.write(params.toByteArray())
|
||||||
var response = 0
|
var response = 0
|
||||||
|
|
||||||
|
@ -81,43 +82,79 @@ class Actions: Client() {
|
||||||
if (con.responseCode == 204) {
|
if (con.responseCode == 204) {
|
||||||
response = 1
|
response = 1
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
response = -1
|
response = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRate(token: String, id_video: Int): String {
|
||||||
|
val con = this.newCon("users/me/videos/$id_video/rating", "GET", token)
|
||||||
|
var rating = "none"
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val key = data.nextName()
|
||||||
|
when (key.toString()) {
|
||||||
|
"rating" -> {
|
||||||
|
rating = data.nextString()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
con.disconnect()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
rating = "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return rating
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reportVideo(videoId: Int, reason: String, token: String): Boolean {
|
||||||
|
val con = this.newCon("videos/$videoId/abuse", "POST", token)
|
||||||
|
val params = "reason=$reason"
|
||||||
|
con.outputStream.write(params.toByteArray())
|
||||||
|
|
||||||
|
var response = false
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
response = true
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
response = false
|
||||||
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRate(token: String, id_video: Int):String{
|
fun watchVideo(videoId: Int, token: String): Boolean {
|
||||||
var con=this._newCon("users/me/videos/$id_video/rating","GET", token)
|
val con = this.newCon("videos/$videoId/watching", "PUT", token)
|
||||||
var rating = "none"
|
val params = "currentTime=1"
|
||||||
|
con.outputStream.write(params.toByteArray())
|
||||||
|
|
||||||
|
var response = false
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 200) {
|
if (con.responseCode == 204) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
response = true
|
||||||
var data = JsonReader(response)
|
|
||||||
data.beginObject()
|
|
||||||
while (data.hasNext()){
|
|
||||||
val key = data.nextName()
|
|
||||||
when (key.toString()) {
|
|
||||||
"rating"->{
|
|
||||||
rating = data.nextString()
|
|
||||||
}
|
|
||||||
else->{
|
|
||||||
data.skipValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
rating = "none"
|
response = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return rating
|
return response
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -4,55 +4,64 @@ package org.libre.agosto.p2play.ajax
|
||||||
import android.util.JsonReader
|
import android.util.JsonReader
|
||||||
import android.util.JsonToken
|
import android.util.JsonToken
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
|
||||||
import org.libre.agosto.p2play.models.TokenModel
|
import org.libre.agosto.p2play.models.TokenModel
|
||||||
import org.libre.agosto.p2play.models.UserModel
|
import org.libre.agosto.p2play.models.UserModel
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
class Auth: Client() {
|
class Auth : Client() {
|
||||||
val stockParams = "grant_type=password"
|
private val stockParams = "grant_type=password"
|
||||||
|
|
||||||
|
fun login(username: String, password: String, client_id: String, client_secret: String, twoFactorCode: String? = null): TokenModel {
|
||||||
|
val con = this.newCon("users/token", "POST")
|
||||||
|
val params = "$stockParams&username=$username&password=$password&client_id=$client_id&client_secret=$client_secret"
|
||||||
|
|
||||||
|
if (twoFactorCode !== null) {
|
||||||
|
con.setRequestProperty("x-peertube-otp", twoFactorCode)
|
||||||
|
}
|
||||||
|
|
||||||
fun login(username: String, password: String, client_id: String, client_secret: String): TokenModel{
|
|
||||||
var con = this._newCon("users/token","POST")
|
|
||||||
val params:String= "$stockParams&username=$username&password=$password&client_id=$client_id&client_secret=$client_secret"
|
|
||||||
con.outputStream.write(params.toByteArray())
|
con.outputStream.write(params.toByteArray())
|
||||||
var token = TokenModel()
|
val token = TokenModel()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
when (con.responseCode) {
|
||||||
|
200 -> {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
data.beginObject()
|
||||||
|
|
||||||
if(con.responseCode==200){
|
while (data.hasNext()) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val k = data.nextName()
|
||||||
var data = JsonReader(response)
|
when (k.toString()) {
|
||||||
data.beginObject()
|
"access_token" -> token.token = data.nextString()
|
||||||
|
"refresh_token" -> token.refresh_token = data.nextString()
|
||||||
while(data.hasNext()){
|
else -> data.skipValue()
|
||||||
val k = data.nextName()
|
}
|
||||||
when(k.toString()){
|
|
||||||
"access_token" -> token.token = data.nextString()
|
|
||||||
"refresh_token" -> token.refresh_token = data.nextString()
|
|
||||||
else -> data.skipValue()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.endObject()
|
||||||
|
data.close()
|
||||||
|
token.status = 1
|
||||||
|
}
|
||||||
|
401 -> {
|
||||||
|
// User require 2FA code
|
||||||
|
token.status = -2
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Log.d("Status", con.responseMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.endObject()
|
|
||||||
token.status = 1
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
} catch (err: Exception) {
|
||||||
Log.d("Status", con.responseMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
token.status = 0
|
token.status = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
fun register(username: String, password: String, email: String): Int{
|
fun register(username: String, password: String, email: String): Int {
|
||||||
var con = this._newCon("users/register","POST")
|
val con = this.newCon("users/register", "POST")
|
||||||
val params:String= "username=$username&password=$password&email=$email"
|
val params = "username=$username&password=$password&email=$email"
|
||||||
con.outputStream.write(params.toByteArray())
|
con.outputStream.write(params.toByteArray())
|
||||||
|
|
||||||
var response = 0
|
var response = 0
|
||||||
|
@ -61,31 +70,30 @@ class Auth: Client() {
|
||||||
if (con.responseCode == 204) {
|
if (con.responseCode == 204) {
|
||||||
response = 1
|
response = 1
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
response = -1
|
response = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshToken(token: TokenModel, client_id: String, client_secret: String): TokenModel{
|
fun refreshToken(token: TokenModel, client_id: String, client_secret: String): TokenModel {
|
||||||
var con = this._newCon("users/token", "POST", token.token)
|
val con = this.newCon("users/token", "POST", token.token)
|
||||||
val params:String = "refresh_token=${token.refresh_token}&response_type=code&grant_type=refresh_token&client_id=$client_id&client_secret=$client_secret"
|
val params = "refresh_token=${token.refresh_token}&response_type=code&grant_type=refresh_token&client_id=$client_id&client_secret=$client_secret"
|
||||||
con.outputStream.write(params.toByteArray())
|
con.outputStream.write(params.toByteArray())
|
||||||
var token = TokenModel()
|
// val token = TokenModel()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(con.responseCode==200){
|
if (con.responseCode == 200) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val response = InputStreamReader(con.inputStream)
|
||||||
var data = JsonReader(response)
|
val data = JsonReader(response)
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
|
|
||||||
while(data.hasNext()){
|
while (data.hasNext()) {
|
||||||
val k = data.nextName()
|
val k = data.nextName()
|
||||||
when(k.toString()){
|
when (k.toString()) {
|
||||||
"access_token" -> token.token = data.nextString()
|
"access_token" -> token.token = data.nextString()
|
||||||
"refresh_token" -> token.refresh_token = data.nextString()
|
"refresh_token" -> token.refresh_token = data.nextString()
|
||||||
else -> data.skipValue()
|
else -> data.skipValue()
|
||||||
|
@ -93,48 +101,45 @@ class Auth: Client() {
|
||||||
}
|
}
|
||||||
|
|
||||||
data.endObject()
|
data.endObject()
|
||||||
|
data.close()
|
||||||
token.status = 1
|
token.status = 1
|
||||||
|
} else {
|
||||||
}
|
|
||||||
else{
|
|
||||||
Log.d("Status", con.responseMessage)
|
Log.d("Status", con.responseMessage)
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
token.status = 0
|
token.status = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
fun me(token: String): UserModel{
|
fun me(token: String): UserModel {
|
||||||
var con = this._newCon("users/me","GET", token)
|
val con = this.newCon("users/me", "GET", token)
|
||||||
|
val user = UserModel()
|
||||||
var user = UserModel()
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
if(con.responseCode==200){
|
val response = InputStreamReader(con.inputStream)
|
||||||
var response = InputStreamReader(con.inputStream)
|
val data = JsonReader(response)
|
||||||
var data = JsonReader(response)
|
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
|
|
||||||
while(data.hasNext()){
|
while (data.hasNext()) {
|
||||||
val k = data.nextName()
|
val k = data.nextName()
|
||||||
when(k.toString()){
|
when (k.toString()) {
|
||||||
"id" -> user.uuid = data.nextInt()
|
"id" -> user.uuid = data.nextInt()
|
||||||
"username" -> user.username = data.nextString()
|
"username" -> user.username = data.nextString()
|
||||||
"email" -> user.email = data.nextString()
|
"email" -> user.email = data.nextString()
|
||||||
"displayNSFW" -> user.nsfw = data.nextBoolean()
|
"displayNSFW" -> user.nsfw = data.nextBoolean()
|
||||||
"account" -> {
|
"account" -> {
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
while (data.hasNext()){
|
while (data.hasNext()) {
|
||||||
val l = data.nextName()
|
val l = data.nextName()
|
||||||
when(l.toString()){
|
when (l.toString()) {
|
||||||
"followersCount" -> user.followers = data.nextInt()
|
"followersCount" -> user.followers = data.nextInt()
|
||||||
"avatar" -> {
|
"avatar" -> {
|
||||||
if(data.peek() == JsonToken.BEGIN_OBJECT) {
|
if (data.peek() == JsonToken.BEGIN_OBJECT) {
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
while (data.hasNext()) {
|
while (data.hasNext()) {
|
||||||
val m = data.nextName()
|
val m = data.nextName()
|
||||||
|
@ -144,8 +149,7 @@ class Auth: Client() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.endObject()
|
data.endObject()
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
data.skipValue()
|
data.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,19 +163,17 @@ class Auth: Client() {
|
||||||
}
|
}
|
||||||
|
|
||||||
data.endObject()
|
data.endObject()
|
||||||
|
data.close()
|
||||||
user.status = 1
|
user.status = 1
|
||||||
|
} else {
|
||||||
}
|
|
||||||
else{
|
|
||||||
Log.d("Status", con.responseMessage)
|
Log.d("Status", con.responseMessage)
|
||||||
}
|
}
|
||||||
}
|
} catch (err: Exception) {
|
||||||
catch (err: Exception){
|
|
||||||
err.printStackTrace()
|
err.printStackTrace()
|
||||||
user.status = 0
|
user.status = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.libre.agosto.p2play.ajax
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
import org.libre.agosto.p2play.models.ChannelModel
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
class Channels : Client() {
|
||||||
|
|
||||||
|
fun getChannelInfo(account: String): ChannelModel {
|
||||||
|
val con = this.newCon("video-channels/$account", "GET")
|
||||||
|
var channel = ChannelModel()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
channel.parseChannel(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return channel
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package org.libre.agosto.p2play.ajax
|
package org.libre.agosto.p2play.ajax
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.util.JsonReader
|
import android.util.JsonReader
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
|
@ -10,61 +9,59 @@ import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
open class Client {
|
open class Client {
|
||||||
|
protected fun newCon(uri: String, method: String, token: String = ""): HttpURLConnection {
|
||||||
|
val url = URL("https://${ManagerSingleton.url}/api/v1/$uri")
|
||||||
|
val con = url.openConnection() as HttpURLConnection
|
||||||
|
|
||||||
|
con.setRequestProperty("User-Agent", "P2play/0.5.3")
|
||||||
protected fun _newCon(uri: String, method: String, token: String = ""): HttpURLConnection {
|
|
||||||
var url = URL("https://"+ManagerSingleton.url+"/api/v1/"+uri)
|
|
||||||
var con = url.openConnection() as HttpURLConnection
|
|
||||||
|
|
||||||
con.setRequestProperty("User-Agent", "P2play/0.1")
|
|
||||||
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
|
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
|
||||||
con.setRequestProperty("Accept", "*/*")
|
con.setRequestProperty("Accept", "*/*")
|
||||||
|
|
||||||
if(token != ""){
|
if (token != "") {
|
||||||
con.setRequestProperty("Authorization", "Bearer ${token}")
|
con.setRequestProperty("Authorization", "Bearer $token")
|
||||||
}
|
}
|
||||||
|
|
||||||
con.requestMethod=method
|
con.requestMethod = method
|
||||||
con.connectTimeout=10000
|
con.connectTimeout = 60000
|
||||||
con.readTimeout=10000
|
con.readTimeout = 60000
|
||||||
|
|
||||||
if(method.equals("POST"))
|
if (method == "POST") {
|
||||||
con.doOutput=true
|
con.doOutput = true
|
||||||
|
}
|
||||||
|
|
||||||
Log.d("Petition", url.toString())
|
Log.d("Petition", url.toString())
|
||||||
return con
|
return con
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getKeys():HostModel{
|
fun getKeys(): HostModel {
|
||||||
var con=this._newCon("oauth-clients/local","GET")
|
val con = this.newCon("oauth-clients/local", "GET")
|
||||||
var keys = HostModel("","")
|
val keys = HostModel("", "")
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 200) {
|
if (con.responseCode == 200) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val response = InputStreamReader(con.inputStream)
|
||||||
var data = JsonReader(response)
|
val data = JsonReader(response)
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
while (data.hasNext()) {
|
while (data.hasNext()) {
|
||||||
val key = data.nextName()
|
val key = data.nextName()
|
||||||
when (key.toString()) {
|
when (key.toString()) {
|
||||||
"client_id"->{
|
"client_id" -> {
|
||||||
keys.client_id = data.nextString()
|
keys.client_id = data.nextString()
|
||||||
}
|
}
|
||||||
"client_secret"->{
|
"client_secret" -> {
|
||||||
keys.client_secret = data.nextString()
|
keys.client_secret = data.nextString()
|
||||||
}
|
}
|
||||||
else->{
|
else -> {
|
||||||
data.skipValue()
|
data.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
data.close()
|
||||||
}
|
}
|
||||||
Log.d("Key",keys.client_id)
|
} catch (err: Exception) {
|
||||||
return keys
|
err.printStackTrace()
|
||||||
} catch(err:Exception){
|
|
||||||
Log.d("Error",err.message)
|
|
||||||
return keys
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return keys
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
package org.libre.agosto.p2play.ajax
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
import android.util.Log
|
||||||
|
import org.libre.agosto.p2play.models.CommentaryModel
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
class Comments : Client() {
|
||||||
|
private fun parseCommentaries(data: JsonReader): ArrayList<CommentaryModel> {
|
||||||
|
val commentaries = arrayListOf<CommentaryModel>()
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
when (data.nextName()) {
|
||||||
|
"data" -> {
|
||||||
|
data.beginArray()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val comment = CommentaryModel()
|
||||||
|
comment.parseCommentary(data)
|
||||||
|
commentaries.add(comment)
|
||||||
|
}
|
||||||
|
data.endArray()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
|
||||||
|
return commentaries
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCommentaries(videoId: Int): ArrayList<CommentaryModel> {
|
||||||
|
var commentaries = arrayListOf<CommentaryModel>()
|
||||||
|
val con = this.newCon("videos/$videoId/comment-threads", "GET")
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
commentaries = parseCommentaries(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
con.disconnect()
|
||||||
|
return commentaries
|
||||||
|
}
|
||||||
|
|
||||||
|
fun makeCommentary(token: String, videoId: Int, text: String): Boolean {
|
||||||
|
val con = this.newCon("videos/$videoId/comment-threads", "POST", token)
|
||||||
|
val params = "text=$text"
|
||||||
|
con.outputStream.write(params.toByteArray())
|
||||||
|
|
||||||
|
var response: Boolean
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
con.disconnect()
|
||||||
|
response = true
|
||||||
|
} else {
|
||||||
|
Log.d("Status", con.responseMessage)
|
||||||
|
response = false
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
response = false
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCommentariesThread(videoId: Int, threadId: Int): ArrayList<CommentaryModel> {
|
||||||
|
var commentaries = arrayListOf<CommentaryModel>()
|
||||||
|
val con = this.newCon("videos/$videoId/comment-threads/$threadId", "GET")
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
when (data.nextName()) {
|
||||||
|
"children" -> {
|
||||||
|
data.beginArray()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
when (data.nextName()) {
|
||||||
|
"comment" -> {
|
||||||
|
val comment = CommentaryModel()
|
||||||
|
comment.parseCommentary(data)
|
||||||
|
commentaries.add(comment)
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
data.endArray()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
con.disconnect()
|
||||||
|
return commentaries
|
||||||
|
}
|
||||||
|
|
||||||
|
fun replyThread(token: String, videoId: Int, threadId: Int, text: String): Boolean {
|
||||||
|
val con = this.newCon("videos/$videoId/comments/$threadId", "POST", token)
|
||||||
|
val params = "text=$text"
|
||||||
|
con.outputStream.write(params.toByteArray())
|
||||||
|
|
||||||
|
val response: Boolean = try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
con.disconnect()
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
Log.d("Status", con.responseMessage)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,88 +1,27 @@
|
||||||
package org.libre.agosto.p2play.ajax
|
package org.libre.agosto.p2play.ajax
|
||||||
|
|
||||||
import android.util.JsonReader
|
import android.util.JsonReader
|
||||||
import android.util.JsonToken
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
import android.util.Log
|
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
class Videos: Client() {
|
class Videos : Client() {
|
||||||
|
|
||||||
fun parseVideos(data: JsonReader): ArrayList<VideoModel>{
|
private fun parseVideos(data: JsonReader): ArrayList<VideoModel> {
|
||||||
var videos = arrayListOf<VideoModel>()
|
val videos = arrayListOf<VideoModel>()
|
||||||
data.beginObject()
|
data.beginObject()
|
||||||
while (data.hasNext()){
|
while (data.hasNext()) {
|
||||||
when(data.nextName()){
|
when (data.nextName()) {
|
||||||
"data"->{
|
"data" -> {
|
||||||
data.beginArray()
|
data.beginArray()
|
||||||
while (data.hasNext()) {
|
while (data.hasNext()) {
|
||||||
val video = VideoModel()
|
val video = VideoModel()
|
||||||
data.beginObject()
|
video.parseVideo(data)
|
||||||
while (data.hasNext()){
|
|
||||||
val key = data.nextName()
|
|
||||||
when (key.toString()) {
|
|
||||||
"id"-> video.id = data.nextInt()
|
|
||||||
"name"->{
|
|
||||||
video.name= data.nextString()
|
|
||||||
}
|
|
||||||
"description"->{
|
|
||||||
if(data.peek() == JsonToken.STRING)
|
|
||||||
video.description = data.nextString()
|
|
||||||
else
|
|
||||||
data.skipValue()
|
|
||||||
}
|
|
||||||
"duration"->{
|
|
||||||
video.duration = data.nextInt()
|
|
||||||
}
|
|
||||||
"thumbnailPath"->{
|
|
||||||
video.thumbUrl = data.nextString()
|
|
||||||
}
|
|
||||||
"embedPath"->{
|
|
||||||
video.embedUrl = data.nextString()
|
|
||||||
}
|
|
||||||
"views"->{
|
|
||||||
video.views = data.nextInt()
|
|
||||||
}
|
|
||||||
"channel"->{
|
|
||||||
data.beginObject()
|
|
||||||
while (data.hasNext()){
|
|
||||||
val acKey = data.nextName()
|
|
||||||
when(acKey.toString()){
|
|
||||||
"displayName"-> video.username=data.nextString()
|
|
||||||
"avatar"-> {
|
|
||||||
if(data.peek() == JsonToken.BEGIN_OBJECT){
|
|
||||||
data.beginObject()
|
|
||||||
while (data.hasNext()){
|
|
||||||
val avKey = data.nextName()
|
|
||||||
when(avKey){
|
|
||||||
"path"-> video.userImageUrl = data.nextString()
|
|
||||||
else-> data.skipValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.endObject()
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data.skipValue()
|
|
||||||
|
|
||||||
}
|
|
||||||
"uuid" -> video.userUuid = data.nextString()
|
|
||||||
"host" -> video.userHost = data.nextString()
|
|
||||||
else-> data.skipValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.endObject()
|
|
||||||
}
|
|
||||||
else->{
|
|
||||||
data.skipValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.endObject()
|
|
||||||
videos.add(video)
|
videos.add(video)
|
||||||
}
|
}
|
||||||
data.endArray()
|
data.endArray()
|
||||||
}
|
}
|
||||||
else-> data.skipValue()
|
else -> data.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.endObject()
|
data.endObject()
|
||||||
|
@ -90,69 +29,213 @@ class Videos: Client() {
|
||||||
return videos
|
return videos
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getVideos(start:Int, count:Int, sort:String = "-publishedAt", filter:String = ""):ArrayList<VideoModel>{
|
private fun getVideos(start: Int, sort: String = "-publishedAt", isLocal: Boolean = false): ArrayList<VideoModel> {
|
||||||
var params = "start=$start&count=$count&sort=$sort"
|
val nsfw = ManagerSingleton.nfsw
|
||||||
if(filter != "")
|
val count = ManagerSingleton.videosCount
|
||||||
params+="&filter=$filter"
|
var params = "start=$start&count=$count&sort=$sort&nsfw=$nsfw&isLocal=$isLocal"
|
||||||
var con=this._newCon("videos?$params","GET")
|
|
||||||
|
val con = this.newCon("videos?$params", "GET")
|
||||||
var videos = arrayListOf<VideoModel>()
|
var videos = arrayListOf<VideoModel>()
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 200) {
|
if (con.responseCode == 200) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val response = InputStreamReader(con.inputStream)
|
||||||
var data = JsonReader(response)
|
val data = JsonReader(response)
|
||||||
videos = parseVideos(data)
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
}
|
}
|
||||||
} catch(err:Exception){
|
} catch (err: Exception) {
|
||||||
err?.printStackTrace()
|
err.printStackTrace()
|
||||||
Log.d("TypeErr",err?.message ,err.cause)
|
|
||||||
Log.d("Error","fallo la coneccion")
|
|
||||||
}
|
}
|
||||||
|
con.disconnect()
|
||||||
return videos
|
return videos
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLastVideos(start:Int = 0, count:Int = 30): ArrayList<VideoModel>{
|
fun getLastVideos(start: Int = 0): ArrayList<VideoModel> {
|
||||||
return this.getVideos(start, count)
|
return this.getVideos(start)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPopularVideos(start:Int = 0, count:Int = 30): ArrayList<VideoModel>{
|
fun getPopularVideos(start: Int = 0): ArrayList<VideoModel> {
|
||||||
return this.getVideos(start, count,"-views")
|
return this.getVideos(start, "-views")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLocalVideos(start:Int = 0, count:Int = 30): ArrayList<VideoModel>{
|
fun getTrendingVideos(start: Int = 0): ArrayList<VideoModel> {
|
||||||
return this.getVideos(start, count,"-publishedAt", "local")
|
return this.getVideos(start, "-trending")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun myVideos(token: String): ArrayList<VideoModel>{
|
fun getLocalVideos(start: Int = 0): ArrayList<VideoModel> {
|
||||||
var con=this._newCon("users/me/videos","GET", token)
|
return this.getVideos(start, "-publishedAt", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun myVideos(token: String, start: Int = 0): ArrayList<VideoModel> {
|
||||||
|
val count = ManagerSingleton.videosCount
|
||||||
|
val params = "start=$start&count=$count"
|
||||||
|
val con = this.newCon("users/me/videos?$params", "GET", token)
|
||||||
var videos = arrayListOf<VideoModel>()
|
var videos = arrayListOf<VideoModel>()
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 200) {
|
if (con.responseCode == 200) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val response = InputStreamReader(con.inputStream)
|
||||||
var data = JsonReader(response)
|
val data = JsonReader(response)
|
||||||
videos = parseVideos(data)
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
}
|
}
|
||||||
} catch(err:Exception){
|
} catch (err: Exception) {
|
||||||
err?.printStackTrace()
|
err.printStackTrace()
|
||||||
Log.d("TypeErr",err?.message ,err.cause)
|
|
||||||
Log.d("Error","fallo la coneccion")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return videos
|
return videos
|
||||||
}
|
}
|
||||||
|
|
||||||
fun videoSubscriptions(token: String): ArrayList<VideoModel>{
|
fun videoSubscriptions(token: String, start: Int = 0): ArrayList<VideoModel> {
|
||||||
var con=this._newCon("users/me/subscriptions/videos","GET", token)
|
val count = ManagerSingleton.videosCount
|
||||||
|
val params = "start=$start&count=$count"
|
||||||
|
val con = this.newCon("users/me/subscriptions/videos?$params", "GET", token)
|
||||||
var videos = arrayListOf<VideoModel>()
|
var videos = arrayListOf<VideoModel>()
|
||||||
try {
|
try {
|
||||||
if (con.responseCode == 200) {
|
if (con.responseCode == 200) {
|
||||||
var response = InputStreamReader(con.inputStream)
|
val response = InputStreamReader(con.inputStream)
|
||||||
var data = JsonReader(response)
|
val data = JsonReader(response)
|
||||||
videos = parseVideos(data)
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
|
} else {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
print(data)
|
||||||
}
|
}
|
||||||
} catch(err:Exception){
|
} catch (err: Exception) {
|
||||||
err?.printStackTrace()
|
err.printStackTrace()
|
||||||
Log.d("TypeErr",err?.message ,err.cause)
|
|
||||||
Log.d("Error","fallo la coneccion")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
return videos
|
return videos
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fun videoHistory(token: String, start: Int = 0): ArrayList<VideoModel> {
|
||||||
|
val count = ManagerSingleton.videosCount
|
||||||
|
val params = "start=$start&count=$count"
|
||||||
|
val con = this.newCon("users/me/history/videos?$params", "GET", token)
|
||||||
|
var videos = arrayListOf<VideoModel>()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return videos
|
||||||
|
}
|
||||||
|
|
||||||
|
fun search(text: String, start: Int = 0): ArrayList<VideoModel> {
|
||||||
|
val count = ManagerSingleton.videosCount
|
||||||
|
val nsfw = ManagerSingleton.nfsw
|
||||||
|
val params = "search=$text&start=$start&count=$count&nsfw=$nsfw"
|
||||||
|
val con = this.newCon("search/videos?$params", "GET")
|
||||||
|
var videos = arrayListOf<VideoModel>()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
con.disconnect()
|
||||||
|
return videos
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fullDescription(videoId: Int): String {
|
||||||
|
val con = this.newCon("videos/$videoId/description", "GET")
|
||||||
|
var description = ""
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val name = data.nextName()
|
||||||
|
when (name) {
|
||||||
|
"description" -> description = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
description = "Error!"
|
||||||
|
}
|
||||||
|
con.disconnect()
|
||||||
|
return description
|
||||||
|
}
|
||||||
|
|
||||||
|
fun channelVideos(account: String, start: Int): ArrayList<VideoModel> {
|
||||||
|
val count = ManagerSingleton.videosCount
|
||||||
|
val params = "start=$start&count=$count"
|
||||||
|
val con = this.newCon("video-channels/$account/videos?$params", "GET")
|
||||||
|
var videos = arrayListOf<VideoModel>()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return videos
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMostLikedVideos(start: Int = 0): ArrayList<VideoModel> {
|
||||||
|
return this.getVideos(start, "-likes")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVideo(uuid: String): VideoModel {
|
||||||
|
val con = this.newCon("videos/$uuid", "GET")
|
||||||
|
val video = VideoModel()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
video.parseVideo(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return video
|
||||||
|
}
|
||||||
|
|
||||||
|
fun accountVideos(account: String, start: Int): ArrayList<VideoModel> {
|
||||||
|
val count = ManagerSingleton.videosCount
|
||||||
|
val params = "start=$start&count=$count"
|
||||||
|
val con = this.newCon("accounts/$account/videos?$params", "GET")
|
||||||
|
var videos = arrayListOf<VideoModel>()
|
||||||
|
try {
|
||||||
|
if (con.responseCode == 200) {
|
||||||
|
val response = InputStreamReader(con.inputStream)
|
||||||
|
val data = JsonReader(response)
|
||||||
|
videos = parseVideos(data)
|
||||||
|
data.close()
|
||||||
|
}
|
||||||
|
} catch (err: Exception) {
|
||||||
|
err.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
con.disconnect()
|
||||||
|
return videos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
package org.libre.agosto.p2play.dialogs
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.Window
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
|
import org.libre.agosto.p2play.R
|
||||||
|
import org.libre.agosto.p2play.adapters.CommentariesAdapter
|
||||||
|
import org.libre.agosto.p2play.ajax.Comments
|
||||||
|
import org.libre.agosto.p2play.databinding.DialogThreadBinding
|
||||||
|
import org.libre.agosto.p2play.models.CommentaryModel
|
||||||
|
|
||||||
|
class ThreadDialog : DialogFragment() {
|
||||||
|
private lateinit var comment: CommentaryModel
|
||||||
|
lateinit var fragmentManager2: FragmentManager
|
||||||
|
private val client: Comments = Comments()
|
||||||
|
|
||||||
|
private var _binding: DialogThreadBinding? = null
|
||||||
|
// This property is only valid between onCreateView and
|
||||||
|
// onDestroyView.
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
|
||||||
|
// The system calls this to get the DialogFragment's layout, regardless of
|
||||||
|
// whether it's being displayed as a dialog or an embedded fragment.
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?,
|
||||||
|
): View {
|
||||||
|
// Inflate the layout to use as a dialog or embedded fragment.
|
||||||
|
_binding = DialogThreadBinding.inflate(inflater, container, false)
|
||||||
|
val view = binding.root
|
||||||
|
comment = arguments?.getSerializable("comment") as CommentaryModel
|
||||||
|
|
||||||
|
binding.commentThread?.userTxt?.text = comment.username
|
||||||
|
binding.commentThread?.userCommentary?.text = comment.commentary
|
||||||
|
Picasso.get().load("https://${ManagerSingleton.url}${comment.userImageUrl}").into(binding.commentThread?.userCommentImg)
|
||||||
|
binding.commentThread?.replyBtn?.visibility = View.GONE
|
||||||
|
|
||||||
|
if (ManagerSingleton.user.status == 1) {
|
||||||
|
binding.commentBox?.commentaryText?.setText("${comment.nameChannel}@${comment.userHost} ")
|
||||||
|
if (ManagerSingleton.user.avatar != "") {
|
||||||
|
Picasso.get().load("https://${ManagerSingleton.url}${ManagerSingleton.user.avatar}").into(binding.commentBox?.userImgCom)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.commentBox?.commentaryText?.requestFocus()
|
||||||
|
binding.commentBox?.commentaryBtn?.setOnClickListener { this.replyThread() }
|
||||||
|
} else {
|
||||||
|
binding.commentBox?.commentaryLayout?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.materialToolbar.setTitle("Thread")
|
||||||
|
binding.materialToolbar.setNavigationIcon(R.drawable.baseline_arrow_back_24)
|
||||||
|
binding.materialToolbar.setNavigationOnClickListener {
|
||||||
|
dismiss()
|
||||||
|
this.fragmentManager2.popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getComments()
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
// The system calls this only when creating the layout in a dialog.
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val dialog = super.onCreateDialog(savedInstanceState)
|
||||||
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getComments() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val data =
|
||||||
|
this.client.getCommentariesThread(this.comment.videoId, this.comment.id)
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
this.setDataComments(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setDataComments(data: ArrayList<CommentaryModel>) {
|
||||||
|
// Set data for RecyclerView
|
||||||
|
val viewAdapter = CommentariesAdapter(data).setFragmentManager(this.fragmentManager2)
|
||||||
|
|
||||||
|
view?.findViewById<RecyclerView>(R.id.listCommentaries)?.let {
|
||||||
|
// use this setting to improve performance if you know that changes
|
||||||
|
// in content do not change the layout size of the RecyclerView
|
||||||
|
it.setHasFixedSize(true)
|
||||||
|
// use a linear layout manager
|
||||||
|
it.layoutManager = LinearLayoutManager(activity)
|
||||||
|
|
||||||
|
// specify an viewAdapter (see also next example)
|
||||||
|
it.adapter = viewAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun replyThread() {
|
||||||
|
val commentary = binding.commentBox?.commentaryText?.text.toString()
|
||||||
|
|
||||||
|
if (commentary == "") {
|
||||||
|
ManagerSingleton.toast(getString(R.string.emptyCommentaryMsg), requireActivity())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncTask.execute {
|
||||||
|
val res = this.client.replyThread(ManagerSingleton.token.token, this.comment.videoId, this.comment.id, commentary)
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
if (res) {
|
||||||
|
ManagerSingleton.toast(getString(R.string.makedCommentaryMsg), requireActivity())
|
||||||
|
binding.commentBox?.commentaryText?.text?.clear()
|
||||||
|
this.getComments()
|
||||||
|
} else {
|
||||||
|
ManagerSingleton.toast(getString(R.string.errorCommentaryMsg), requireActivity())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.libre.agosto.p2play.fragmentAdapters
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import org.libre.agosto.p2play.fragments.AccountVideosFragment
|
||||||
|
import org.libre.agosto.p2play.fragments.AccountChannelsFragment
|
||||||
|
import org.libre.agosto.p2play.fragments.AccountInfoFragment
|
||||||
|
import org.libre.agosto.p2play.models.AccountModel
|
||||||
|
|
||||||
|
val TAB_NAMES = arrayOf(
|
||||||
|
"Videos",
|
||||||
|
"Channels",
|
||||||
|
"Info"
|
||||||
|
)
|
||||||
|
|
||||||
|
class AccountAdapter(fm: FragmentManager, c: Lifecycle) : FragmentStateAdapter(fm, c) {
|
||||||
|
lateinit var accountId: String
|
||||||
|
lateinit var account: AccountModel
|
||||||
|
override fun getItemCount(): Int = 3
|
||||||
|
|
||||||
|
override fun createFragment(i: Int): Fragment {
|
||||||
|
val fragment = when (i) {
|
||||||
|
0 -> AccountVideosFragment.newInstance(accountId)
|
||||||
|
1 -> AccountChannelsFragment.newInstance(accountId)
|
||||||
|
2 -> AccountInfoFragment.newInstance(account)
|
||||||
|
else -> throw Error("Invalid tab")
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get(position: Int): CharSequence {
|
||||||
|
return TAB_NAMES[position]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package org.libre.agosto.p2play.fragments
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.libre.agosto.p2play.adapters.ChannelAdapter
|
||||||
|
import org.libre.agosto.p2play.ajax.Accounts
|
||||||
|
import org.libre.agosto.p2play.databinding.FragmentChannelsBinding
|
||||||
|
import org.libre.agosto.p2play.helpers.getViewManager
|
||||||
|
import org.libre.agosto.p2play.models.ChannelModel
|
||||||
|
|
||||||
|
private const val ARG_PARAM1 = "accountId"
|
||||||
|
|
||||||
|
class AccountChannelsFragment : Fragment() {
|
||||||
|
private var _binding: FragmentChannelsBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
private var accountId: String? = null
|
||||||
|
|
||||||
|
private val client = Accounts()
|
||||||
|
|
||||||
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
arguments?.let {
|
||||||
|
accountId = it.getString(ARG_PARAM1)
|
||||||
|
}
|
||||||
|
viewManager = getViewManager(this.requireContext(), resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentChannelsBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
getChannels()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getChannels() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val channels = client.getChannels(this.accountId!!)
|
||||||
|
requireActivity().runOnUiThread {
|
||||||
|
initRecycler(channels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initRecycler(data: ArrayList<ChannelModel>) {
|
||||||
|
val viewAdapter = ChannelAdapter(data)
|
||||||
|
|
||||||
|
binding.channelList.apply {
|
||||||
|
viewAdapter.parent = requireActivity()
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
// use a linear layout manager
|
||||||
|
layoutManager = viewManager
|
||||||
|
|
||||||
|
// specify an viewAdapter (see also next example)
|
||||||
|
adapter = viewAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(accountId: String) =
|
||||||
|
AccountChannelsFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putString(ARG_PARAM1, accountId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.libre.agosto.p2play.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import org.libre.agosto.p2play.databinding.FragmentChannelInfoBinding
|
||||||
|
import org.libre.agosto.p2play.models.AccountModel
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
private const val ARG_PARAM1 = "account"
|
||||||
|
|
||||||
|
class AccountInfoFragment : Fragment() {
|
||||||
|
private var _binding: FragmentChannelInfoBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
private var account: AccountModel? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
arguments?.let {
|
||||||
|
account = it.getSerializable(ARG_PARAM1) as AccountModel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentChannelInfoBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
binding.account.text = account?.name
|
||||||
|
binding.host.text = account?.host
|
||||||
|
binding.description.text = account?.description
|
||||||
|
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(account: AccountModel) =
|
||||||
|
AccountInfoFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
val param = account as Serializable
|
||||||
|
putSerializable(ARG_PARAM1, param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package org.libre.agosto.p2play.fragments
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.libre.agosto.p2play.adapters.VideosAdapter
|
||||||
|
import org.libre.agosto.p2play.ajax.Videos
|
||||||
|
import org.libre.agosto.p2play.databinding.FragmentChannelVideosBinding
|
||||||
|
import org.libre.agosto.p2play.helpers.getViewManager
|
||||||
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
|
||||||
|
private const val ARG_PARAM1 = "accountId"
|
||||||
|
|
||||||
|
class AccountVideosFragment : Fragment() {
|
||||||
|
private var _binding: FragmentChannelVideosBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
private var accountId: String? = "agosto182"
|
||||||
|
private val videosService = Videos()
|
||||||
|
|
||||||
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
arguments?.let {
|
||||||
|
accountId = it.getString(ARG_PARAM1, accountId)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewManager = getViewManager(this.requireContext(), resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentChannelVideosBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
getVideos()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVideos() {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val videos = videosService.accountVideos(this.accountId!!, 0)
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
initRecycler(videos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initRecycler(data: ArrayList<VideoModel>) {
|
||||||
|
// val data = arrayListOf<VideoModel>()
|
||||||
|
val viewAdapter = VideosAdapter(data)
|
||||||
|
|
||||||
|
binding.videosList.apply {
|
||||||
|
// use this setting to improve performance if you know that changes
|
||||||
|
// in content do not change the layout size of the RecyclerView
|
||||||
|
setHasFixedSize(true)
|
||||||
|
|
||||||
|
// use a linear layout manager
|
||||||
|
layoutManager = viewManager
|
||||||
|
|
||||||
|
// specify an viewAdapter (see also next example)
|
||||||
|
adapter = viewAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(param1: String) =
|
||||||
|
AccountVideosFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putString(ARG_PARAM1, param1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.libre.agosto.p2play.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.content.res.Resources
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.LayoutManager
|
||||||
|
|
||||||
|
fun getViewManager (context: Context, resources: Resources): LayoutManager {
|
||||||
|
val screenSize = resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK
|
||||||
|
val manager = if (screenSize > Configuration.SCREENLAYOUT_SIZE_LARGE) {
|
||||||
|
val orientation = resources.configuration.orientation
|
||||||
|
val gridItems = when (orientation) {
|
||||||
|
Configuration.ORIENTATION_LANDSCAPE -> 4
|
||||||
|
else -> 3
|
||||||
|
}
|
||||||
|
GridLayoutManager(context, gridItems)
|
||||||
|
} else {
|
||||||
|
LinearLayoutManager(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
return manager
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.libre.agosto.p2play.helpers
|
||||||
|
|
||||||
|
fun mapSeconds(inputSeconds: Int): String {
|
||||||
|
val seconds = (inputSeconds % 60)
|
||||||
|
var minutes = inputSeconds / 60
|
||||||
|
var hours = 0
|
||||||
|
|
||||||
|
if (minutes > 60) {
|
||||||
|
hours = minutes / 60
|
||||||
|
minutes %= 60
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = minutes.toString().padStart(2, '0') + ":" + seconds.toString().padStart(2, '0')
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
result = hours.toString().padStart(2, '0') + ":" + result
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.libre.agosto.p2play.helpers
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
|
|
||||||
|
fun setFullscreen(window: Window) {
|
||||||
|
val attrs = window.attributes
|
||||||
|
attrs.flags = attrs.flags or WindowManager.LayoutParams.FLAG_FULLSCREEN
|
||||||
|
attrs.flags = attrs.flags or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||||
|
window.attributes = attrs
|
||||||
|
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
data class AccountAvatar (
|
||||||
|
val path: String
|
||||||
|
)
|
||||||
|
|
||||||
|
class AccountModel (
|
||||||
|
val name: String,
|
||||||
|
val url: String,
|
||||||
|
val host: String,
|
||||||
|
val avatars: ArrayList<AccountAvatar>,
|
||||||
|
val displayName: String,
|
||||||
|
val description: String
|
||||||
|
): Serializable
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
import android.util.JsonToken
|
||||||
|
|
||||||
|
class ChannelModel(
|
||||||
|
var id: Int = 0,
|
||||||
|
var url: String = "",
|
||||||
|
var nameChannel: String = "",
|
||||||
|
var followers: Int = 0,
|
||||||
|
var host: String = "",
|
||||||
|
var name: String = "",
|
||||||
|
var description: String = "",
|
||||||
|
var support: String = "",
|
||||||
|
var channelImg: String = "",
|
||||||
|
) {
|
||||||
|
fun getAccount(): String {
|
||||||
|
return "$nameChannel@$host"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun parseChannel(data: JsonReader) {
|
||||||
|
data.beginObject()
|
||||||
|
|
||||||
|
while (data.hasNext()) {
|
||||||
|
when (data.nextName()) {
|
||||||
|
"id" -> this.id = data.nextInt()
|
||||||
|
"url" -> this.url = data.nextString()
|
||||||
|
"name" -> this.nameChannel = data.nextString()
|
||||||
|
"host" -> this.host = data.nextString()
|
||||||
|
"followersCount" -> this.followers = data.nextInt()
|
||||||
|
"displayName" -> this.name = data.nextString()
|
||||||
|
"description" -> {
|
||||||
|
if (data.peek() == JsonToken.STRING) {
|
||||||
|
this.description = data.nextString()
|
||||||
|
} else {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"support" -> {
|
||||||
|
if (data.peek() == JsonToken.STRING) {
|
||||||
|
this.support = data.nextString()
|
||||||
|
} else {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"avatar" -> {
|
||||||
|
if (data.peek() == JsonToken.BEGIN_OBJECT) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
when (data.nextName()) {
|
||||||
|
"path" -> this.channelImg = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
} else {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
import android.util.JsonToken
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
class CommentaryModel(
|
||||||
|
var id: Int = 0,
|
||||||
|
var threadId: Int = 0,
|
||||||
|
var userUuid: String = "",
|
||||||
|
var username: String = "",
|
||||||
|
var userImageUrl: String = "",
|
||||||
|
var commentary: String = "",
|
||||||
|
var userHost: String = "",
|
||||||
|
var replies: Int = 0,
|
||||||
|
var nameChannel: String = "",
|
||||||
|
var videoId: Int = 0,
|
||||||
|
) : Serializable {
|
||||||
|
fun parseCommentary(data: JsonReader) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val key = data.nextName()
|
||||||
|
when (key.toString()) {
|
||||||
|
"id" -> this.id = data.nextInt()
|
||||||
|
"threadId" -> this.threadId = data.nextInt()
|
||||||
|
"text" -> this.commentary = data.nextString()
|
||||||
|
"totalReplies" -> this.replies = data.nextInt()
|
||||||
|
"videoId" -> this.videoId = data.nextInt()
|
||||||
|
"account" -> {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val acKey = data.nextName()
|
||||||
|
when (acKey.toString()) {
|
||||||
|
"displayName" -> this.username = data.nextString()
|
||||||
|
"avatar" -> {
|
||||||
|
if (data.peek() == JsonToken.BEGIN_OBJECT) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val avKey = data.nextName()
|
||||||
|
when (avKey) {
|
||||||
|
"path" -> this.userImageUrl = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
} else {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"uuid" -> this.userUuid = data.nextString()
|
||||||
|
"host" -> this.userHost = data.nextString()
|
||||||
|
"name" -> this.nameChannel = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAccount(): String {
|
||||||
|
return "$nameChannel@$userHost"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
package org.libre.agosto.p2play.models
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
class HostModel (var client_id:String, var client_secret:String)
|
class HostModel(var client_id: String, var client_secret: String)
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
|
||||||
|
class DownloadFiles(
|
||||||
|
var resolution: String = "",
|
||||||
|
var url: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
class StreamingModel(
|
||||||
|
var playlistUrl: String = "",
|
||||||
|
var segmentsSha256Url: String = "",
|
||||||
|
var downloadFiles: ArrayList<DownloadFiles> = arrayListOf<DownloadFiles>()
|
||||||
|
) {
|
||||||
|
fun parse(data: JsonReader) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val key = data.nextName()
|
||||||
|
when (key.toString()) {
|
||||||
|
"playlistUrl" -> {
|
||||||
|
this.playlistUrl = data.nextString()
|
||||||
|
}
|
||||||
|
"segmentsSha256Url" -> {
|
||||||
|
this.segmentsSha256Url = data.nextString()
|
||||||
|
}
|
||||||
|
"files" -> {
|
||||||
|
data.beginArray()
|
||||||
|
if (data.hasNext()) {
|
||||||
|
data.beginObject()
|
||||||
|
val downloadFile = DownloadFiles()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val key2 = data.nextName()
|
||||||
|
when (key2.toString()) {
|
||||||
|
"fileDownloadUrl" -> downloadFile.url = data.nextString()
|
||||||
|
"resolution" -> {
|
||||||
|
data.beginObject()
|
||||||
|
while(data.hasNext()) {
|
||||||
|
val keyRes = data.nextName()
|
||||||
|
when (keyRes!!) {
|
||||||
|
"label" -> downloadFile.resolution = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.downloadFiles.add(downloadFile)
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
while (data.hasNext()) {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
data.endArray()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package org.libre.agosto.p2play.models
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
class TokenModel (
|
class TokenModel(
|
||||||
var token: String = "",
|
var token: String = "",
|
||||||
var refresh_token: String = "",
|
var refresh_token: String = "",
|
||||||
var status: Int = -1
|
var status: Int = -1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package org.libre.agosto.p2play.models
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
class UserModel (
|
class UserModel(
|
||||||
var id: Int = 0,
|
var id: Int = 0,
|
||||||
var uuid: Int = 0,
|
var uuid: Int = 0,
|
||||||
var username: String = "",
|
var username: String = "",
|
||||||
var email: String = "",
|
var email: String = "",
|
||||||
var nsfw: Boolean = true,
|
var nsfw: Boolean = true,
|
||||||
var followers: Int = 0,
|
var followers: Int = 0,
|
||||||
var avatar: String = "",
|
var avatar: String = "",
|
||||||
var status: Int = -1
|
var status: Int = -1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,17 +1,146 @@
|
||||||
package org.libre.agosto.p2play.models
|
package org.libre.agosto.p2play.models
|
||||||
|
|
||||||
|
import android.util.JsonReader
|
||||||
|
import android.util.JsonToken
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
class VideoModel(
|
class VideoModel(
|
||||||
var id: Int = 0,
|
var id: Int = 0,
|
||||||
var name: String = "",
|
var uuid: String = "",
|
||||||
var description: String = "",
|
var name: String = "",
|
||||||
var thumbUrl: String = "",
|
var description: String = "",
|
||||||
var userImageUrl: String = "",
|
var thumbUrl: String = "",
|
||||||
var embedUrl: String = "",
|
var userImageUrl: String = "",
|
||||||
var duration: Number = 0,
|
var embedUrl: String = "",
|
||||||
var username: String = "",
|
var duration: Number = 0,
|
||||||
var views: Number = 0,
|
var username: String = "",
|
||||||
var userUuid: String = "",
|
var views: Number = 0,
|
||||||
var userHost: String = ""
|
var userUuid: String = "",
|
||||||
):Serializable
|
var userHost: String = "",
|
||||||
|
var nameChannel: String = "",
|
||||||
|
var isLive: Boolean = false,
|
||||||
|
var streamingData: StreamingModel? = null,
|
||||||
|
) : Serializable {
|
||||||
|
fun getChannel(): String {
|
||||||
|
return "$nameChannel@$userHost"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVideoUrl(): String {
|
||||||
|
return "https://$userHost/videos/watch/$uuid"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun parseVideo(data: JsonReader) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val key = data.nextName()
|
||||||
|
when (key.toString()) {
|
||||||
|
"id" -> this.id = data.nextInt()
|
||||||
|
"uuid" -> this.uuid = data.nextString()
|
||||||
|
"name" -> {
|
||||||
|
this.name = data.nextString()
|
||||||
|
}
|
||||||
|
"description" -> {
|
||||||
|
if (data.peek() == JsonToken.STRING) {
|
||||||
|
this.description = data.nextString()
|
||||||
|
} else {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"duration" -> {
|
||||||
|
this.duration = data.nextInt()
|
||||||
|
}
|
||||||
|
"thumbnailPath" -> {
|
||||||
|
this.thumbUrl = data.nextString()
|
||||||
|
}
|
||||||
|
"embedPath" -> {
|
||||||
|
this.embedUrl = data.nextString()
|
||||||
|
}
|
||||||
|
"views" -> {
|
||||||
|
this.views = data.nextInt()
|
||||||
|
}
|
||||||
|
"isLive" -> {
|
||||||
|
this.isLive = data.nextBoolean()
|
||||||
|
}
|
||||||
|
"streamingPlaylists" -> {
|
||||||
|
data.beginArray()
|
||||||
|
if (data.hasNext()) {
|
||||||
|
val streamingData = StreamingModel()
|
||||||
|
streamingData.parse(data)
|
||||||
|
this.streamingData = streamingData
|
||||||
|
}
|
||||||
|
data.endArray()
|
||||||
|
}
|
||||||
|
"files" -> {
|
||||||
|
data.beginArray()
|
||||||
|
if (streamingData === null) {
|
||||||
|
if (data.hasNext()) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val key2 = data.nextName()
|
||||||
|
streamingData = StreamingModel()
|
||||||
|
val downloadFile = DownloadFiles()
|
||||||
|
when (key2.toString()) {
|
||||||
|
"fileUrl" -> {
|
||||||
|
streamingData!!.playlistUrl = data.nextString()
|
||||||
|
}
|
||||||
|
"fileDownloadUrl" -> downloadFile.url = data.nextString()
|
||||||
|
"resolution" -> {
|
||||||
|
data.beginObject()
|
||||||
|
while(data.hasNext()) {
|
||||||
|
val keyRes = data.nextName()
|
||||||
|
when (keyRes!!) {
|
||||||
|
"label" -> downloadFile.resolution = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
streamingData!!.downloadFiles.add(downloadFile)
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
while (data.hasNext()) {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endArray()
|
||||||
|
}
|
||||||
|
"channel" -> {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val acKey = data.nextName()
|
||||||
|
when (acKey.toString()) {
|
||||||
|
"displayName" -> this.username = data.nextString()
|
||||||
|
"avatar" -> {
|
||||||
|
if (data.peek() == JsonToken.BEGIN_OBJECT) {
|
||||||
|
data.beginObject()
|
||||||
|
while (data.hasNext()) {
|
||||||
|
val avKey = data.nextName()
|
||||||
|
when (avKey) {
|
||||||
|
"path" -> this.userImageUrl = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
} else {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"uuid" -> this.userUuid = data.nextString()
|
||||||
|
"host" -> this.userHost = data.nextString()
|
||||||
|
"name" -> this.nameChannel = data.nextString()
|
||||||
|
else -> data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
data.skipValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.endObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.libre.agosto.p2play.services
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.media3.session.MediaSession
|
||||||
|
import androidx.media3.session.MediaSessionService
|
||||||
|
import org.libre.agosto.p2play.ReproductorActivity
|
||||||
|
import org.libre.agosto.p2play.singletons.PlaybackSingleton
|
||||||
|
|
||||||
|
class PlaybackService : MediaSessionService() {
|
||||||
|
private var mediaSession: MediaSession? = null
|
||||||
|
|
||||||
|
// Create your Player and MediaSession in the onCreate lifecycle event
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
val player = PlaybackSingleton.player!!
|
||||||
|
mediaSession = MediaSession.Builder(this, player)
|
||||||
|
.build()
|
||||||
|
val contentIntent = Intent(this, ReproductorActivity::class.java)
|
||||||
|
contentIntent.putExtra("resume", true)
|
||||||
|
val pendingIntent = PendingIntent.getActivity(
|
||||||
|
this,
|
||||||
|
0,
|
||||||
|
contentIntent,
|
||||||
|
PendingIntent.FLAG_MUTABLE,
|
||||||
|
)
|
||||||
|
mediaSession!!.setSessionActivity(pendingIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember to release the player and media session in onDestroy
|
||||||
|
override fun onDestroy() {
|
||||||
|
mediaSession?.run {
|
||||||
|
release()
|
||||||
|
mediaSession = null
|
||||||
|
}
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||||
|
this.mediaSession!!.player.stop()
|
||||||
|
super.onTaskRemoved(rootIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
|
||||||
|
return mediaSession
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.libre.agosto.p2play.singletons
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
|
import androidx.media3.session.MediaController
|
||||||
|
import androidx.media3.session.SessionToken
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors
|
||||||
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
import org.libre.agosto.p2play.services.PlaybackService
|
||||||
|
|
||||||
|
object PlaybackSingleton {
|
||||||
|
var player: ExoPlayer? = null
|
||||||
|
var video: VideoModel? = null
|
||||||
|
private var withMediaSession = false
|
||||||
|
|
||||||
|
fun setData(mediaItem: MediaItem, video: VideoModel): ExoPlayer? {
|
||||||
|
player?.let {
|
||||||
|
if (it.isPlaying) {
|
||||||
|
it.pause()
|
||||||
|
}
|
||||||
|
it.setMediaItem(mediaItem)
|
||||||
|
it.prepare()
|
||||||
|
this.video = video
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun release() {
|
||||||
|
player?.release()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runMediaSession(context: Context) {
|
||||||
|
if (!this.withMediaSession) {
|
||||||
|
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
|
||||||
|
|
||||||
|
val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync()
|
||||||
|
|
||||||
|
controllerFuture.addListener(
|
||||||
|
{
|
||||||
|
val med = controllerFuture.get()
|
||||||
|
},
|
||||||
|
MoreExecutors.directExecutor(),
|
||||||
|
)
|
||||||
|
this.withMediaSession = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportHeight="108"
|
|
||||||
android:viewportWidth="108">
|
|
||||||
<path
|
|
||||||
android:fillType="evenOdd"
|
|
||||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:strokeWidth="1">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="78.5885"
|
|
||||||
android:endY="90.9159"
|
|
||||||
android:startX="48.7653"
|
|
||||||
android:startY="61.0927"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:strokeWidth="1" />
|
|
||||||
</vector>
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M12.8716,3.5097L12,1.9603L11.1284,3.5097L2.1284,19.5097L1.2902,21L3,21L21,21L22.7098,21L21.8716,19.5097L12.8716,3.5097Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#585858"
|
||||||
|
android:fillType="evenOdd"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M12,17.75C12.6904,17.75 13.25,17.1904 13.25,16.5C13.25,15.8096 12.6904,15.25 12,15.25C11.3096,15.25 10.75,15.8096 10.75,16.5C10.75,17.1904 11.3096,17.75 12,17.75Z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:fillColor="#585858"
|
||||||
|
android:strokeColor="#585858"
|
||||||
|
android:fillType="evenOdd" />
|
||||||
|
<path
|
||||||
|
android:pathData="M12,9L12,9A1,1 0,0 1,13 10L13,13A1,1 0,0 1,12 14L12,14A1,1 0,0 1,11 13L11,10A1,1 0,0 1,12 9z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:fillColor="#585858"
|
||||||
|
android:strokeColor="#585858"
|
||||||
|
android:fillType="evenOdd" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#88ffffff" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#fff" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M18,13c0,3.31 -2.69,6 -6,6s-6,-2.69 -6,-6s2.69,-6 6,-6v4l5,-5l-5,-5v4c-4.42,0 -8,3.58 -8,8c0,4.42 3.58,8 8,8s8,-3.58 8,-8H18z"/>
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M10.86,15.94l0,-4.27l-0.09,0l-1.77,0.63l0,0.69l1.01,-0.31l0,3.26z"/>
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12.25,13.44v0.74c0,1.9 1.31,1.82 1.44,1.82c0.14,0 1.44,0.09 1.44,-1.82v-0.74c0,-1.9 -1.31,-1.82 -1.44,-1.82C13.55,11.62 12.25,11.53 12.25,13.44zM14.29,13.32v0.97c0,0.77 -0.21,1.03 -0.59,1.03c-0.38,0 -0.6,-0.26 -0.6,-1.03v-0.97c0,-0.75 0.22,-1.01 0.59,-1.01C14.07,12.3 14.29,12.57 14.29,13.32z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="48dp" android:tint="#fff" android:viewportHeight="24" android:viewportWidth="24" android:width="48dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
|
||||||
|
</vector>
|
|
@ -1,170 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportHeight="108"
|
|
||||||
android:viewportWidth="108">
|
|
||||||
<path
|
|
||||||
android:fillColor="#26A69A"
|
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M9,0L9,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,0L19,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,0L29,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,0L39,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,0L49,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,0L59,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,0L69,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,0L79,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M89,0L89,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M99,0L99,108"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,9L108,9"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,19L108,19"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,29L108,29"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,39L108,39"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,49L108,49"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,59L108,59"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,69L108,69"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,79L108,79"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,89L108,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,99L108,99"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,29L89,29"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,39L89,39"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,49L89,49"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,59L89,59"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,69L89,69"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,79L89,79"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,19L29,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,19L39,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,19L49,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,19L59,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,19L69,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,19L79,89"
|
|
||||||
android:strokeColor="#33FFFFFF"
|
|
||||||
android:strokeWidth="0.8" />
|
|
||||||
</vector>
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M21,6h-7.59l3.29,-3.29L16,2l-4,4 -4,-4 -0.71,0.71L10.59,6L3,6c-1.1,0 -2,0.89 -2,2v12c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,8c0,-1.11 -0.9,-2 -2,-2zM21,20L3,20L3,8h18v12zM9,10v8l7,-4z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M260,800Q169,800 104.5,737Q40,674 40,583Q40,505 87,444Q134,383 210,366Q227,294 295,229Q363,164 440,164Q473,164 496.5,187.5Q520,211 520,244L520,486L584,424L640,480L480,640L320,480L376,424L440,486L440,244Q364,258 322,317.5Q280,377 280,440L260,440Q202,440 161,481Q120,522 120,580Q120,638 161,679Q202,720 260,720L740,720Q782,720 811,691Q840,662 840,620Q840,578 811,549Q782,520 740,520L680,520L680,440Q680,392 658,350.5Q636,309 600,280L600,187Q674,222 717,290.5Q760,359 760,440L760,440L760,440Q829,448 874.5,499.5Q920,551 920,620Q920,695 867.5,747.5Q815,800 740,800L260,800ZM480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442L480,442L480,442Q480,442 480,442Q480,442 480,442Z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#fff" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#fff" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#fff" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M11.99,5V1l-5,5l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6s-6,-2.69 -6,-6h-2c0,4.42 3.58,8 8,8s8,-3.58 8,-8S16.41,5 11.99,5z"/>
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M10.89,16h-0.85v-3.26l-1.01,0.31v-0.69l1.77,-0.63h0.09V16z"/>
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M15.17,14.24c0,0.32 -0.03,0.6 -0.1,0.82s-0.17,0.42 -0.29,0.57s-0.28,0.26 -0.45,0.33s-0.37,0.1 -0.59,0.1s-0.41,-0.03 -0.59,-0.1s-0.33,-0.18 -0.46,-0.33s-0.23,-0.34 -0.3,-0.57s-0.11,-0.5 -0.11,-0.82V13.5c0,-0.32 0.03,-0.6 0.1,-0.82s0.17,-0.42 0.29,-0.57s0.28,-0.26 0.45,-0.33s0.37,-0.1 0.59,-0.1s0.41,0.03 0.59,0.1c0.18,0.07 0.33,0.18 0.46,0.33s0.23,0.34 0.3,0.57s0.11,0.5 0.11,0.82V14.24zM14.32,13.38c0,-0.19 -0.01,-0.35 -0.04,-0.48s-0.07,-0.23 -0.12,-0.31s-0.11,-0.14 -0.19,-0.17s-0.16,-0.05 -0.25,-0.05s-0.18,0.02 -0.25,0.05s-0.14,0.09 -0.19,0.17s-0.09,0.18 -0.12,0.31s-0.04,0.29 -0.04,0.48v0.97c0,0.19 0.01,0.35 0.04,0.48s0.07,0.24 0.12,0.32s0.11,0.14 0.19,0.17s0.16,0.05 0.25,0.05s0.18,-0.02 0.25,-0.05s0.14,-0.09 0.19,-0.17s0.09,-0.19 0.11,-0.32s0.04,-0.29 0.04,-0.48V13.38z"/>
|
||||||
|
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M20,15L20,18.0026C20,19.1057 19.1074,20 18.0049,20L5.9951,20C4.8932,20 4,19.1074 4,18.0049L4,5.9951C4,4.8932 4.8959,4 5.9974,4L9,4"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#585858"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M13,4l7.0208,0l0,7.0191"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#585858"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M19,5L12,12"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#585858"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M1,21h4L5,9L1,9v12zM23,10c0,-1.1 -0.9,-2 -2,-2h-6.31l0.95,-4.57 0.03,-0.32c0,-0.41 -0.17,-0.79 -0.44,-1.06L14.17,1 7.59,7.59C7.22,7.95 7,8.45 7,9v10c0,1.1 0.9,2 2,2h9c0.83,0 1.54,-0.5 1.84,-1.22l3.02,-7.05c0.09,-0.23 0.14,-0.47 0.14,-0.73v-1.91l-0.01,-0.01L23,10z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
|
||||||
|
<!-- This is the border color -->
|
||||||
|
|
||||||
|
<!--- This is the background color -->
|
||||||
|
<solid android:color="@color/colorDislike" />
|
||||||
|
|
||||||
|
</shape>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
|
||||||
|
<!-- This is the border color -->
|
||||||
|
|
||||||
|
<!--- This is the background color -->
|
||||||
|
<solid android:color="?attr/colorSecondary" />
|
||||||
|
|
||||||
|
</shape>
|
|
@ -0,0 +1,360 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ReproductorActivity">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/fullScreen"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/fullScreenExo"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" >
|
||||||
|
<androidx.media3.ui.PlayerView
|
||||||
|
android:id="@+id/fullscreenPlayer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#000"
|
||||||
|
app:use_controller="true"
|
||||||
|
app:show_buffering="always"
|
||||||
|
app:controller_layout_id="@layout/custom_player_controls"
|
||||||
|
app:player_layout_id="@layout/exo_player_view"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/nonFullScreen"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
android:id="@+id/videoView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="205dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<androidx.media3.ui.PlayerView
|
||||||
|
android:id="@+id/exoPlayer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="500dp"
|
||||||
|
app:show_buffering="always"
|
||||||
|
app:use_controller="true"
|
||||||
|
app:controller_layout_id="@layout/custom_player_controls"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tittleVideoTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Display1"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/viewsTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:id="@+id/actionsLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:gravity="top"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:id="@+id/likeLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/likeBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_like" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewLike"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/likeBtn"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/dislikeLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/dislikeBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_dislike" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewDislike"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/dislikeBtn"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/reportLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageViewAlert"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/dislikeBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_alert" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewAlert"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/reportBtn"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/shareLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageViewShare"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/shareBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_share" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewShare"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/shareBtn"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:gravity="center|center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/userImg"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="3"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/userTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxWidth="300dp"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Large"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hostTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textStyle="italic" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/subscribeBtn"
|
||||||
|
style="@style/Widget.MaterialComponents.Button"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/subscribeBtn"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:visibility="invisible" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/descriptionTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLength="1000"
|
||||||
|
android:maxLines="100"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:text="@string/descriptionTxt"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/descriptionVideoTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:autoLink="web"
|
||||||
|
android:linksClickable="true"
|
||||||
|
android:maxLength="10000"
|
||||||
|
android:maxLines="100"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/showMoreBtn"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/showMore"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="20dp" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Barrier
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:barrierDirection="left" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/commentBox"
|
||||||
|
layout="@layout/comment_component" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/commentariesTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:text="@string/commentariesTxt"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/listCommentaries"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2020 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<!-- 0dp dimensions are used to prevent this view from influencing the size of
|
||||||
|
the parent view if it uses "wrap_content". It is expanded to occupy the
|
||||||
|
entirety of the parent in code, after the parent's size has been
|
||||||
|
determined. See: https://github.com/google/ExoPlayer/issues/8726.
|
||||||
|
-->
|
||||||
|
<View android:id="@id/exo_controls_background"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@color/exo_black_opacity_60"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@id/exo_bottom_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
|
||||||
|
android:background="@color/exo_bottom_bar_background"
|
||||||
|
android:layoutDirection="ltr">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@id/exo_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|start"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
|
||||||
|
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
|
||||||
|
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
|
||||||
|
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/exo_position"
|
||||||
|
style="@style/ExoStyledControls.TimeText.Position" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/ExoStyledControls.TimeText.Separator"
|
||||||
|
android:text="/" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/exo_duration"
|
||||||
|
style="@style/ExoStyledControls.TimeText.Duration" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@id/exo_basic_controls"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layoutDirection="ltr">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_subtitle"
|
||||||
|
style="@style/ExoStyledControls.Button.Bottom.CC" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_settings"
|
||||||
|
style="@style/ExoStyledControls.Button.Bottom.Settings" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/exo_fullscreen_custom"
|
||||||
|
style="@style/ExoStyledControls.Button.Bottom.Settings"
|
||||||
|
android:src="@drawable/ic_fullscreen_24"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<View android:id="@id/exo_progress_placeholder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/exo_styled_progress_layout_height"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="@dimen/exo_styled_progress_margin_bottom"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@id/exo_center_controls"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="@dimen/exo_styled_controls_padding"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layoutDirection="ltr">
|
||||||
|
|
||||||
|
<include layout="@layout/exo_player_control_rewind_button" />
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_play_pause"
|
||||||
|
style="@style/ExoStyledControls.Button.Center.PlayPause"/>
|
||||||
|
|
||||||
|
<include layout="@layout/exo_player_control_ffwd_button" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</merge>
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#44000000">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout3"
|
||||||
|
android:layout_width="800dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="?attr/colorSurface"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/materialToolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/commentThread"
|
||||||
|
layout="@layout/view_commentary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/listCommentaries"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/commentBox"
|
||||||
|
layout="@layout/comment_component"
|
||||||
|
android:layout_width="700dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -27,9 +27,9 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="Logo"
|
android:contentDescription="Logo"
|
||||||
app:srcCompat="@drawable/icon" />
|
app:srcCompat="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
@ -39,11 +39,10 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/aboutLabel"
|
android:text="@string/aboutLabel"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Medium.Inverse"
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
android:textColor="@android:color/black"
|
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@
|
||||||
android:textAlignment="textStart"
|
android:textAlignment="textStart"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/gitlabUrl"
|
android:id="@+id/gitlabUrl"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -66,7 +65,7 @@
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="20dp" />
|
android:layout_height="20dp" />
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
@ -98,11 +97,10 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/aboutInstance"
|
android:text="@string/aboutInstance"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Medium.Inverse"
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
android:textColor="@android:color/black"
|
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="20dp" />
|
android:layout_height="20dp" />
|
||||||
|
|
||||||
|
@ -124,7 +122,7 @@
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
@ -135,7 +133,11 @@
|
||||||
android:text="@string/aboutLicense"
|
android:text="@string/aboutLicense"
|
||||||
android:textAlignment="textStart"
|
android:textAlignment="textStart"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:id="@+id/collapsingToolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="250dp"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:layout_scrollFlags="scroll|enterAlways"
|
||||||
|
app:layout_collapseMode="pin" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backgroundImage"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
app:layout_collapseMode="parallax"/>
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_collapseMode="pin"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profileImage"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tabs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_scrollFlags="scroll|enterAlways"/>
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/viewpager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -0,0 +1,153 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:context=".ChannelActivity">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/colorProfile"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/channelImg"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="70dp"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:contentDescription="@string/app_name"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/usernameProfile"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/followersIndicator"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subcriptionsTxt"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textAlignment="textStart"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView3"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/hostIndicator"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hostTxt"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textAlignment="textStart"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/subcriptionBtn"
|
||||||
|
style="@style/Widget.AppCompat.Button.Colored"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/subscribeBtn"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:visibility="invisible" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frameLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/linearLayout2"
|
||||||
|
tools:layout_editor_absoluteX="0dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Videos:"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:layout_editor_absoluteX="176dp"
|
||||||
|
tools:layout_editor_absoluteY="214dp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/listVideosChannel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -29,32 +29,41 @@
|
||||||
android:contentDescription="Logo"
|
android:contentDescription="Logo"
|
||||||
app:srcCompat="@drawable/icon" />
|
app:srcCompat="@drawable/icon" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
<TextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/hostInfoText"
|
android:id="@+id/hostInfoText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/hostInfoText"
|
android:text="@string/hostInfoText"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Medium.Inverse"
|
/>
|
||||||
android:textColor="@android:color/black" />
|
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
<EditText
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/hostText"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="10"
|
android:layout_margin="4dp"
|
||||||
android:hint="@string/hostText"
|
android:hint="@string/instance"
|
||||||
android:inputType="text" />
|
app:expandedHintEnabled="false">
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/hostText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="@string/hostText"
|
||||||
|
android:inputType="text" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/button"
|
android:id="@+id/button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -62,4 +71,4 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -1,98 +1,97 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".LoginActivity">
|
tools:context=".LoginActivity">
|
||||||
|
|
||||||
<FrameLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginEnd="8dp"
|
android:gravity="center"
|
||||||
android:layout_marginStart="8dp"
|
android:orientation="vertical"
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintWidth_max="500dp">
|
||||||
|
|
||||||
<LinearLayout
|
<ImageView
|
||||||
|
android:id="@+id/imageView2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:contentDescription="Logo"
|
||||||
|
app:srcCompat="@drawable/icon" />
|
||||||
|
|
||||||
<ImageView
|
<androidx.legacy.widget.Space
|
||||||
android:id="@+id/imageView2"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="30dp" />
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:contentDescription="Logo"
|
|
||||||
app:srcCompat="@drawable/icon" />
|
|
||||||
|
|
||||||
<Space
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/loginInfo"
|
||||||
android:layout_height="30dp" />
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/loginInfo"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium" />
|
||||||
|
|
||||||
<TextView
|
<androidx.legacy.widget.Space
|
||||||
android:id="@+id/loginInfo"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="30dp" />
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/loginInfo"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Medium.Inverse"
|
|
||||||
android:textColor="@android:color/black" />
|
|
||||||
|
|
||||||
<Space
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/userTxt"
|
||||||
android:layout_height="30dp" />
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:hint="@string/userTxt"
|
||||||
|
android:maxWidth="600dp">
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/userTxt"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/userTxt" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/userText"
|
android:id="@+id/userText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:hint="@string/userText"
|
android:hint="@string/userText"
|
||||||
android:inputType="text" />
|
android:inputType="text" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/passwordTxt"
|
android:id="@+id/passwordTxt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/passwordTxt" />
|
android:layout_margin="4dp"
|
||||||
|
android:hint="@string/passwordTxt"
|
||||||
|
android:maxWidth="600dp"
|
||||||
|
android:maxEms="10"
|
||||||
|
app:endIconMode="password_toggle">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/passwordText"
|
android:id="@+id/passwordText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:hint="@string/passwordText"
|
android:inputType="textPassword" />
|
||||||
android:inputType="text|textPassword" />
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/loginBtn"
|
android:id="@+id/loginBtn"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/loginBtn"
|
android:text="@string/loginBtn"
|
||||||
android:textAlignment="center" />
|
android:textAlignment="center" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/registerActionBtn"
|
android:id="@+id/registerActionBtn"
|
||||||
android:layout_width="match_parent"
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:text="@string/registerActionBtn"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="visible" />
|
android:text="@string/registerActionBtn"
|
||||||
|
android:visibility="invisible" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/drawer_layout"
|
android:id="@+id/drawer_layout"
|
||||||
|
@ -8,18 +8,39 @@
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:openDrawer="start">
|
tools:openDrawer="start">
|
||||||
|
|
||||||
<include
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
layout="@layout/app_bar_main"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<android.support.design.widget.NavigationView
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"/>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/content"
|
||||||
|
layout="@layout/content_main" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.navigation.NavigationView
|
||||||
android:id="@+id/nav_view"
|
android:id="@+id/nav_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
|
android:background="@color/colorMenu"
|
||||||
|
app:itemTextColor="@color/colorBody"
|
||||||
|
app:itemIconTint="@android:color/darker_gray"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
app:headerLayout="@layout/nav_header_main"
|
app:headerLayout="@layout/nav_header_main"
|
||||||
app:menu="@menu/activity_main_drawer" />
|
app:menu="@menu/activity_main_drawer" />
|
||||||
|
|
||||||
</android.support.v4.widget.DrawerLayout>
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
android:contentDescription="Logo"
|
android:contentDescription="Logo"
|
||||||
app:srcCompat="@drawable/icon" />
|
app:srcCompat="@drawable/icon" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Medium.Inverse"
|
android:textAppearance="@android:style/TextAppearance.Material.Medium.Inverse"
|
||||||
android:textColor="@android:color/black" />
|
android:textColor="@android:color/black" />
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp" />
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/registerBtn"
|
android:id="@+id/registerBtn"
|
||||||
|
style="@style/Widget.AppCompat.Button.Colored"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/registerBtn"
|
android:text="@string/registerBtn"
|
||||||
|
@ -98,4 +99,4 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,14 +1,55 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ReproductorActivity">
|
tools:context=".ReproductorActivity">
|
||||||
|
|
||||||
<ScrollView
|
<RelativeLayout
|
||||||
|
android:id="@+id/fullScreen"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/fullScreenExo"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" >
|
||||||
|
<androidx.media3.ui.PlayerView
|
||||||
|
android:id="@+id/fullscreenPlayer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#000"
|
||||||
|
app:use_controller="true"
|
||||||
|
app:show_buffering="always"
|
||||||
|
app:controller_layout_id="@layout/custom_player_controls"
|
||||||
|
app:player_layout_id="@layout/exo_player_view"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/nonFullScreen"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
@ -25,16 +66,25 @@
|
||||||
<WebView
|
<WebView
|
||||||
android:id="@+id/videoView"
|
android:id="@+id/videoView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="220dp">
|
android:layout_height="205dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
</WebView>
|
<androidx.media3.ui.PlayerView
|
||||||
|
android:id="@+id/exoPlayer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="205dp"
|
||||||
|
app:show_buffering="always"
|
||||||
|
app:use_controller="true"
|
||||||
|
app:controller_layout_id="@layout/custom_player_controls" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tittleVideoTxt"
|
android:id="@+id/tittleVideoTxt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="5dp"
|
android:paddingStart="5dp"
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Large"
|
android:textAppearance="@android:style/TextAppearance.Material.Display1"
|
||||||
|
android:textSize="18sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -42,140 +92,246 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="5dp"
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
android:textSize="12sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:id="@+id/actionsLayout"
|
android:id="@+id/actionsLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="50dp"
|
||||||
android:gravity="top"
|
android:gravity="top"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:id="@+id/likeLayout"
|
android:id="@+id/likeLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:adjustViewBounds="false"
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/likeBtn"
|
||||||
android:cropToPadding="false"
|
android:cropToPadding="false"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:visibility="visible"
|
||||||
app:srcCompat="@drawable/ic_like" />
|
app:srcCompat="@drawable/ic_like" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView"
|
android:id="@+id/textViewLike"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/likeBtn"
|
android:text="@string/likeBtn"
|
||||||
android:textAlignment="center" />
|
android:textAlignment="center" />
|
||||||
</LinearLayout>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/dislikeLayout"
|
android:id="@+id/dislikeLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView2"
|
android:id="@+id/imageView2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:adjustViewBounds="false"
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/dislikeBtn"
|
||||||
android:cropToPadding="false"
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
app:srcCompat="@drawable/ic_dislike" />
|
app:srcCompat="@drawable/ic_dislike" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView"
|
android:id="@+id/textViewDislike"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/dislikeBtn"
|
android:text="@string/dislikeBtn"
|
||||||
android:textAlignment="center" />
|
android:textAlignment="center" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
android:id="@+id/button4"
|
android:id="@+id/downloadLayout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/shareBtn"
|
android:orientation="vertical"
|
||||||
android:visibility="gone" />
|
android:visibility="visible">
|
||||||
|
|
||||||
<Button
|
<ImageView
|
||||||
android:id="@+id/button3"
|
android:id="@+id/downloadImage"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/reportBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_outline_cloud_download_24"
|
||||||
|
app:tint="#585858" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/downloadText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/downloadText"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/reportLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/reportBtn"
|
android:orientation="vertical"
|
||||||
android:visibility="gone" />
|
android:visibility="visible">
|
||||||
</LinearLayout>
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageViewAlert"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/reportBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_alert" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewAlert"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/reportBtn"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/shareLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageViewShare"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/shareBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:srcCompat="@drawable/ic_share" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewShare"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/shareBtn"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="60dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:gravity="center|center_vertical"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/userImg"
|
android:id="@+id/userImg"
|
||||||
android:layout_width="40dp"
|
android:layout_width="35dp"
|
||||||
android:layout_height="50dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="0dp"
|
android:layout_margin="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:adjustViewBounds="false"
|
android:adjustViewBounds="true"
|
||||||
android:cropToPadding="false"
|
android:cropToPadding="false"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="fitCenter"
|
||||||
app:srcCompat="@drawable/default_avatar" />
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/userTxt"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="70dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_weight="3"
|
||||||
android:layout_weight="2"
|
android:orientation="vertical">
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Large"
|
|
||||||
android:textColor="@android:color/black" />
|
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
|
android:id="@+id/userTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxWidth="300dp"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Large"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hostTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textStyle="italic" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/subscribeBtn"
|
android:id="@+id/subscribeBtn"
|
||||||
style="@android:style/Widget.Holo.Button.Small"
|
style="@style/Widget.MaterialComponents.Button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/subscribeBtn"
|
android:text="@string/subscribeBtn"
|
||||||
android:visibility="gone" />
|
android:textSize="12sp"
|
||||||
|
android:visibility="invisible" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/descriptionTxt"
|
android:id="@+id/descriptionTxt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLength="1000"
|
||||||
|
android:maxLines="100"
|
||||||
android:paddingLeft="5dp"
|
android:paddingLeft="5dp"
|
||||||
android:text="@string/descriptionTxt" />
|
android:text="@string/descriptionTxt"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<ScrollView
|
<TextView
|
||||||
|
android:id="@+id/descriptionVideoTxt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="80dp">
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:autoLink="web"
|
||||||
|
android:linksClickable="true"
|
||||||
|
android:maxLength="10000"
|
||||||
|
android:maxLines="100"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp" />
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/descriptionVideoTxt"
|
android:id="@+id/showMoreBtn"
|
||||||
android:layout_width="match_parent"
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:maxLength="1000"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1000"
|
android:layout_weight="1"
|
||||||
android:paddingLeft="5dp"
|
android:text="@string/showMore"
|
||||||
android:text="TextView"
|
android:visibility="gone" />
|
||||||
android:textStyle="italic" />
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/divider"
|
android:id="@+id/divider"
|
||||||
|
@ -183,7 +339,37 @@
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?android:attr/listDivider" />
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/commentariesTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:text="@string/commentariesTxt"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="20dp" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/commentBox"
|
||||||
|
layout="@layout/comment_component" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/listCommentaries"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".SplashActivity">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="32dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@string/app_name"
|
||||||
|
app:srcCompat="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hostInfoText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/charging"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Medium" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:backgroundTint="?attr/colorAccent"
|
||||||
|
android:indeterminate="true" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,25 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:theme="@style/P2playTheme.AppBarOverlay">
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="?attr/colorPrimary"
|
|
||||||
app:popupTheme="@style/P2playTheme.PopupOverlay" />
|
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
<include layout="@layout/content_main" />
|
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/commentaryLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/userImgCom"
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="57dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:layout_weight="3"
|
||||||
|
android:hint="@string/commentHolder">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/commentaryText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="textMultiLine" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/commentaryBtn"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/commentaryText" />
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
tools:context=".MainActivity"
|
tools:context=".MainActivity"
|
||||||
tools:showIn="@layout/app_bar_main">
|
tools:showIn="@layout/app_bar_main">
|
||||||
|
|
||||||
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/swipeContainer"
|
android:id="@+id/swipeContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/list"
|
android:id="@+id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -24,5 +24,17 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/mini"
|
||||||
|
layout="@layout/mini_player"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2020 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<!-- 0dp dimensions are used to prevent this view from influencing the size of
|
||||||
|
the parent view if it uses "wrap_content". It is expanded to occupy the
|
||||||
|
entirety of the parent in code, after the parent's size has been
|
||||||
|
determined. See: https://github.com/google/ExoPlayer/issues/8726.
|
||||||
|
-->
|
||||||
|
<View android:id="@id/exo_controls_background"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@color/exo_black_opacity_60"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@id/exo_bottom_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
|
||||||
|
android:background="@color/exo_bottom_bar_background"
|
||||||
|
android:layoutDirection="ltr">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@id/exo_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|start"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
|
||||||
|
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
|
||||||
|
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
|
||||||
|
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/exo_position"
|
||||||
|
style="@style/ExoStyledControls.TimeText.Position" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/ExoStyledControls.TimeText.Separator"
|
||||||
|
android:text="/" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/exo_duration"
|
||||||
|
style="@style/ExoStyledControls.TimeText.Duration" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@id/exo_basic_controls"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layoutDirection="ltr">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_subtitle"
|
||||||
|
style="@style/ExoStyledControls.Button.Bottom.CC" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_settings"
|
||||||
|
style="@style/ExoStyledControls.Button.Bottom.Settings" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/exo_fullscreen_custom"
|
||||||
|
style="@style/ExoStyledControls.Button.Bottom.Settings"
|
||||||
|
android:src="@drawable/ic_fullscreen_24"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<View android:id="@id/exo_progress_placeholder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="45dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@id/exo_center_controls"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="@dimen/exo_styled_controls_padding"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layoutDirection="ltr">
|
||||||
|
|
||||||
|
<include layout="@layout/exo_player_control_rewind_button" />
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_play_pause"
|
||||||
|
style="@style/ExoStyledControls.Button.Center.PlayPause"/>
|
||||||
|
|
||||||
|
<include layout="@layout/exo_player_control_ffwd_button" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</merge>
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:background="?attr/colorSurface"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout3"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginBottom="130dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/materialToolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/commentThread"
|
||||||
|
layout="@layout/view_commentary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/listCommentaries"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="10dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/commentBox"
|
||||||
|
layout="@layout/comment_component"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.AccountInfoFragment">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:padding="8dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/accountTitle"
|
||||||
|
style="@style/TextAppearance.Material3.BodyMedium"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/accountName" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/account"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="8dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hostTitle"
|
||||||
|
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/hostIndicator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/host"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="8dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/descriptionTitle"
|
||||||
|
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/descriptionTxt" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="" />
|
||||||
|
|
||||||
|
<androidx.legacy.widget.Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.AccountVideosFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/videosList"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.AccountChannelsFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/channelList"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/androidBackgroundSecondary"
|
||||||
|
android:elevation="5dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:id="@+id/mini_player">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/mini_player_image"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/default_avatar"
|
||||||
|
tools:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/mini_player_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:maxWidth="180dp"
|
||||||
|
android:text="Video"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/mini_player_image"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textColor="?attr/androidOnBackgroundSecondary"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/mini_player_author"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:maxWidth="180dp"
|
||||||
|
android:text="Author"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/mini_player_image"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/mini_play_pause"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:adjustViewBounds="false"
|
||||||
|
android:contentDescription="@string/likeBtn"
|
||||||
|
android:cropToPadding="false"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_pause_24"
|
||||||
|
app:tint="@color/colorAccent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -3,22 +3,21 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/nav_header_height"
|
android:layout_height="@dimen/nav_header_height"
|
||||||
android:background="@android:color/darker_gray"
|
android:background="@color/colorProfile"
|
||||||
android:gravity="bottom"
|
android:gravity="bottom"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/side_imageView"
|
android:id="@+id/side_imageView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="50dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:contentDescription="@string/nav_header_desc"
|
android:contentDescription="@string/nav_header_desc"
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
app:srcCompat="@mipmap/ic_launcher_round" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/side_usernameTxt"
|
android:id="@+id/side_usernameTxt"
|
||||||
|
@ -26,12 +25,15 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||||
android:text="@string/nav_header_title"
|
android:text="@string/nav_header_title"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/side_emailTxt"
|
android:id="@+id/side_emailTxt"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/nav_header_subtitle" />
|
android:text="@string/nav_header_subtitle"
|
||||||
|
android:textColor="@android:color/darker_gray" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/layout_root"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp" >
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/reportText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textMultiLine" >
|
||||||
|
<requestFocus />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputEditText>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/settings"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp" >
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="0dp"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/twoFactorText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<requestFocus />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputEditText>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/channelImage"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.0"
|
||||||
|
tools:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/channelName"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="TextView"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/channelImage"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/channelDescription"
|
||||||
|
android:layout_width="198dp"
|
||||||
|
android:layout_height="17dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="TextView"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/channelImage"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/channelName" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/subscribeBtn"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/subscribeBtn"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/userCommentImg"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:contentDescription="@string/app_name"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/userTxt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@android:color/darker_gray"
|
||||||
|
android:textStyle="italic" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/userCommentary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autoLink="web"
|
||||||
|
android:linksClickable="true"
|
||||||
|
android:maxLength="1000"
|
||||||
|
android:maxLines="10" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/replyBtn"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/reply"
|
||||||
|
android:textColor="?attr/colorSecondary"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -14,33 +14,77 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<ImageView
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/thumb"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="230dp"
|
android:layout_height="wrap_content"
|
||||||
app:srcCompat="@android:drawable/ic_menu_gallery" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/thumb"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="205dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@android:drawable/ic_menu_gallery" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/isLive"
|
||||||
|
android:layout_width="65dp"
|
||||||
|
android:layout_height="19dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:background="@drawable/live_shape"
|
||||||
|
android:ems="10"
|
||||||
|
android:paddingHorizontal="3dp"
|
||||||
|
android:text="@string/is_live_video"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="@color/durationColor"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:visibility="invisible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/duration"
|
||||||
|
android:layout_width="65dp"
|
||||||
|
android:layout_height="19dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:background="@drawable/round_text"
|
||||||
|
android:ems="10"
|
||||||
|
android:paddingHorizontal="3dp"
|
||||||
|
android:text="00:00"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="?attr/colorOnSecondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="63dp"
|
android:layout_height="55dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/userImg"
|
android:id="@+id/userImg"
|
||||||
android:layout_width="140dp"
|
android:layout_width="120dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:adjustViewBounds="false"
|
android:adjustViewBounds="true"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:cropToPadding="false"
|
android:cropToPadding="false"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="fitCenter"
|
||||||
app:srcCompat="@drawable/default_avatar" />
|
app:srcCompat="@drawable/default_avatar" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -48,26 +92,26 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLength="70"
|
android:maxLength="70"
|
||||||
android:text="TextView"
|
android:textSize="14sp"
|
||||||
android:textSize="18sp"
|
android:textStyle="bold"
|
||||||
android:textStyle="bold" />
|
android:theme="@style/MaterialAlertDialog.MaterialComponents.Title.Text" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/descriptionTxt"
|
android:id="@+id/descriptionTxt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="TextView"
|
android:textColor="@android:color/darker_gray"
|
||||||
android:textColor="@android:color/darker_gray" />
|
android:textSize="12sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Space
|
<androidx.legacy.widget.Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="15dp"
|
android:layout_height="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
|
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -3,16 +3,43 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:showIn="navigation_view">
|
tools:showIn="navigation_view">
|
||||||
|
|
||||||
<item android:title="Videos">
|
<item
|
||||||
|
android:id="@+id/ml"
|
||||||
|
android:icon="@android:color/darker_gray"
|
||||||
|
android:title="@string/nav_menu_myLibrary"
|
||||||
|
android:visible="false">
|
||||||
<menu>
|
<menu>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_subscriptions"
|
android:id="@+id/nav_myVideos"
|
||||||
android:icon="@drawable/ic_video_library_black_24dp"
|
android:icon="@drawable/ic_video_library_black_24dp"
|
||||||
|
android:title="@string/title_myVideos" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_subscriptions"
|
||||||
|
android:icon="@drawable/ic_live_tv_black_24dp"
|
||||||
android:title="@string/nav_subscriptions" />
|
android:title="@string/nav_subscriptions" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_history"
|
||||||
|
android:icon="@drawable/ic_history_black_24dp"
|
||||||
|
android:title="@string/nav_history" />
|
||||||
|
</menu>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
android:id="@+id/ai"
|
||||||
|
android:icon="@android:color/darker_gray"
|
||||||
|
android:title="@string/nav_menu_videos">
|
||||||
|
<menu>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_popular"
|
android:id="@+id/nav_popular"
|
||||||
android:icon="@android:drawable/btn_star"
|
android:icon="@android:drawable/btn_star"
|
||||||
android:title="@string/nav_popular" />
|
android:title="@string/nav_popular" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_trending"
|
||||||
|
android:icon="@drawable/ic_trending_up_black_24dp"
|
||||||
|
android:title="@string/nav_trending" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_likes"
|
||||||
|
android:icon="@drawable/ic_thumb_up_black_24dp"
|
||||||
|
android:title="@string/nav_likes" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_recent"
|
android:id="@+id/nav_recent"
|
||||||
android:icon="@drawable/ic_add_circle_black_24dp"
|
android:icon="@drawable/ic_add_circle_black_24dp"
|
||||||
|
@ -24,7 +51,10 @@
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
<item android:title="More">
|
<item
|
||||||
|
android:id="@+id/aiao"
|
||||||
|
android:icon="@android:color/white"
|
||||||
|
android:title="@string/nav_menu_more">
|
||||||
<menu>
|
<menu>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_about"
|
android:id="@+id/nav_about"
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/app_bar_search"
|
||||||
|
android:icon="@drawable/ic_search_black_24dp"
|
||||||
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
|
android:title="@string/action_login"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_login"
|
android:id="@+id/action_login"
|
||||||
android:title="@string/action_login"
|
android:title="@string/action_login"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue