Compare commits
No commits in common. "main" and "transcoding-upstream" have entirely different histories.
main
...
transcodin
350 changed files with 2997 additions and 6693 deletions
117
.github/workflows/build.yaml
vendored
117
.github/workflows/build.yaml
vendored
|
@ -5,27 +5,9 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# lint:
|
lint:
|
||||||
# name: Lint
|
name: Lint
|
||||||
# runs-on: ubuntu-22.04
|
|
||||||
# steps:
|
|
||||||
# - name: Checkout repository
|
|
||||||
# uses: actions/checkout@v4
|
|
||||||
# - name: Validate Gradle Wrapper
|
|
||||||
# uses: gradle/actions/wrapper-validation@v3
|
|
||||||
# - name: Set up JDK 17
|
|
||||||
# uses: actions/setup-java@v4
|
|
||||||
# with:
|
|
||||||
# java-version: 17
|
|
||||||
# distribution: temurin
|
|
||||||
# - name: Setup Gradle
|
|
||||||
# uses: gradle/actions/setup-gradle@v3
|
|
||||||
# - name: Build with Gradle
|
|
||||||
# run: ./gradlew lintDebug ktlintCheck
|
|
||||||
assemble:
|
|
||||||
name: Assemble
|
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
if: startsWith(github.event.head_commit.message, 'build:')
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -39,45 +21,62 @@ jobs:
|
||||||
- name: Setup Gradle
|
- name: Setup Gradle
|
||||||
uses: gradle/actions/setup-gradle@v3
|
uses: gradle/actions/setup-gradle@v3
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew assemble
|
run: ./gradlew lintDebug ktlintCheck
|
||||||
|
assemble:
|
||||||
|
name: Assemble
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Validate Gradle Wrapper
|
||||||
|
uses: gradle/actions/wrapper-validation@v3
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: 17
|
||||||
|
distribution: temurin
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v3
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew assembleDebug
|
||||||
# Upload all build artifacts in separate steps. This can be shortened once https://github.com/actions/upload-artifact/pull/354 is merged.
|
# Upload all build artifacts in separate steps. This can be shortened once https://github.com/actions/upload-artifact/pull/354 is merged.
|
||||||
- name: Upload artifact ananas-v0.10.3-0.14.2-libre-arm64-v8a.apk
|
- name: Upload artifact phone-libre-arm64-v8a-debug.apk
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: phone-libre-arm64-v8a.apk
|
name: phone-libre-arm64-v8a-debug.apk
|
||||||
path: ./app/phone/build/outputs/apk/libre/release/ananas-v0.10.3-0.14.2-libre-arm64-v8a.apk
|
path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-arm64-v8a-debug.apk
|
||||||
# - name: Upload artifact phone-libre-armeabi-v7a-debug.apk
|
- name: Upload artifact phone-libre-armeabi-v7a-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: phone-libre-armeabi-v7a-debug.apk
|
name: phone-libre-armeabi-v7a-debug.apk
|
||||||
# path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-armeabi-v7a-debug.apk
|
path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-armeabi-v7a-debug.apk
|
||||||
# - name: Upload artifact phone-libre-x86_64-debug.apk
|
- name: Upload artifact phone-libre-x86_64-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: phone-libre-x86_64-debug.apk
|
name: phone-libre-x86_64-debug.apk
|
||||||
# path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-x86_64-debug.apk
|
path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-x86_64-debug.apk
|
||||||
# - name: Upload artifact phone-libre-x86-debug.apk
|
- name: Upload artifact phone-libre-x86-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: phone-libre-x86-debug.apk
|
name: phone-libre-x86-debug.apk
|
||||||
# path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-x86-debug.apk
|
path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-x86-debug.apk
|
||||||
# - name: Upload artifact tv-libre-arm64-v8a-debug.apk
|
- name: Upload artifact tv-libre-arm64-v8a-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: tv-libre-arm64-v8a-debug.apk
|
name: tv-libre-arm64-v8a-debug.apk
|
||||||
# path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-arm64-v8a-debug.apk
|
path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-arm64-v8a-debug.apk
|
||||||
# - name: Upload artifact tv-libre-armeabi-v7a-debug.apk
|
- name: Upload artifact tv-libre-armeabi-v7a-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: tv-libre-armeabi-v7a-debug.apk
|
name: tv-libre-armeabi-v7a-debug.apk
|
||||||
# path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-armeabi-v7a-debug.apk
|
path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-armeabi-v7a-debug.apk
|
||||||
# - name: Upload artifact tv-libre-x86_64-debug.apk
|
- name: Upload artifact tv-libre-x86_64-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: tv-libre-x86_64-debug.apk
|
name: tv-libre-x86_64-debug.apk
|
||||||
# path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-x86_64-debug.apk
|
path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-x86_64-debug.apk
|
||||||
# - name: Upload artifact tv-libre-x86-debug.apk
|
- name: Upload artifact tv-libre-x86-debug.apk
|
||||||
# uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
# with:
|
with:
|
||||||
# name: tv-libre-x86-debug.apk
|
name: tv-libre-x86-debug.apk
|
||||||
# path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-x86-debug.apk
|
path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-x86-debug.apk
|
||||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -10,14 +10,10 @@ local.properties
|
||||||
|
|
||||||
# Android Studio generated files and folders
|
# Android Studio generated files and folders
|
||||||
captures/
|
captures/
|
||||||
app/phone/libre/release/
|
|
||||||
.kotlin
|
|
||||||
.externalNativeBuild/
|
.externalNativeBuild/
|
||||||
.cxx/
|
.cxx/
|
||||||
*.apk
|
*.apk
|
||||||
*.dm
|
|
||||||
output.json
|
output.json
|
||||||
app/phone/libre/release/output-metadata.json
|
|
||||||
|
|
||||||
# IntelliJ
|
# IntelliJ
|
||||||
*.iml
|
*.iml
|
||||||
|
@ -41,4 +37,3 @@ fastlane/report.xml
|
||||||
fastlane/Preview.html
|
fastlane/Preview.html
|
||||||
fastlane/screenshots
|
fastlane/screenshots
|
||||||
fastlane/test_output
|
fastlane/test_output
|
||||||
push.sh
|
|
||||||
|
|
7
PRIVACY
7
PRIVACY
|
@ -1,6 +1,7 @@
|
||||||
This privacy policy pertains the Ananas app.
|
This privacy policy pertains the Findroid app.
|
||||||
|
|
||||||
Ananas does not collect or access any personal information. No identifying information or user data of any kind is made available to third-parties.
|
Findroid does not collect or access any personal information. No identifying information or user data of any kind is made available to third-parties.
|
||||||
|
|
||||||
This Privacy Policy is effective as of Jun 24th, 2024 and will remain in effect except with respect to any changes in its provisions in the future, which will be in effect immediately after being posted on this page. We reserve the right to update or change our Privacy Policy at any time and you should check this Privacy Policy periodically. Your continued use of the Service after we post any modifications to the Privacy Policy on this page will constitute your acknowledgment of the modifications and your consent to abide and be bound by the modified Privacy Policy.
|
This Privacy Policy is effective as of Feb 8th, 2023 and will remain in effect except with respect to any changes in its provisions in the future, which will be in effect immediately after being posted on this page. We reserve the right to update or change our Privacy Policy at any time and you should check this Privacy Policy periodically. Your continued use of the Service after we post any modifications to the Privacy Policy on this page will constitute your acknowledgment of the modifications and your consent to abide and be bound by the modified Privacy Policy.
|
||||||
|
|
||||||
|
Findroid is published by Jarne Demeulemeester. Inquiries can be submitted to jarnedemeulemeester@gmail.com.
|
||||||
|
|
34
README.md
34
README.md
|
@ -1,6 +1,21 @@
|
||||||
|

|
||||||
|
|
||||||
|
# Findroid
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
Findroid is third-party Android application for Jellyfin that provides a native user interface to browse and play movies and series.
|
||||||
|
|
||||||
|
I am developing this application in my spare time.
|
||||||
|
|
||||||
|
**This project is in its early stages so expect bugs.**
|
||||||
|
|
||||||
|
<a href='https://play.google.com/store/apps/details?id=dev.jdtech.jellyfin'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' height="80"/></a><a href='http://www.amazon.com/gp/product/B0BTWC8DNZ'><img alt='Available at Amazon Appstore' src='https://user-images.githubusercontent.com/32322857/219019331-027a6775-7362-44bb-a026-281f71e9b37b.png' height="80"/></a><a href='https://apt.izzysoft.de/fdroid/index/apk/dev.jdtech.jellyfin'><img alt='Get it on IzzyOnDroid' src='https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png' height="80"/></a>
|
||||||
|
|
||||||
# Ananas
|
|
||||||
Personal fork
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
| Home | Library | Movie | Season | Episode |
|
| Home | Library | Movie | Season | Episode |
|
||||||
|-------------------------------------|-------------------------------------|---------------------------------|-----------------------------------|-------------------------------------|
|
|-------------------------------------|-------------------------------------|---------------------------------|-----------------------------------|-------------------------------------|
|
||||||
|
@ -9,9 +24,8 @@ Personal fork
|
||||||
## Features
|
## Features
|
||||||
- Completely native interface
|
- Completely native interface
|
||||||
- Supported media items: movies, series, seasons, episodes
|
- Supported media items: movies, series, seasons, episodes
|
||||||
- Direct play and Transcoding
|
- Direct play only, (no transcoding)
|
||||||
- Offline playback / downloads
|
- Offline playback / downloads
|
||||||
- Transcoding Downloads (Original - 720p - 480p - 360p)
|
|
||||||
- ExoPlayer
|
- ExoPlayer
|
||||||
- Video codecs: H.263, H.264, H.265, VP8, VP9, AV1
|
- Video codecs: H.263, H.264, H.265, VP8, VP9, AV1
|
||||||
- Support depends on Android device
|
- Support depends on Android device
|
||||||
|
@ -35,8 +49,20 @@ Personal fork
|
||||||
- Websocket connection (Syncplay)
|
- Websocket connection (Syncplay)
|
||||||
- Chromecast support
|
- Chromecast support
|
||||||
|
|
||||||
|
## Translating
|
||||||
|
[JDTech Weblate](https://weblate.jdtech.dev) is a selfhosted instance of Weblate where you can translate this project and future projects of mine.
|
||||||
|
|
||||||
|
## Questions?
|
||||||
|
[](https://discord.gg/tg5VvTFwTV)\
|
||||||
|
We have a Discord server to discuss future development or ask general questions.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This project is licensed under [GPLv3](LICENSE).
|
This project is licensed under [GPLv3](LICENSE).
|
||||||
|
|
||||||
|
The logo is a combination of the Jellyfin logo and the Android robot.
|
||||||
|
|
||||||
|
The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.
|
||||||
|
|
||||||
|
Android is a trademark of Google LLC.
|
||||||
|
|
||||||
|
Google Play and the Google Play logo are trademarks of Google LLC.
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.nomadics9.ananas",
|
|
||||||
"variantName": "AnanasRelease",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "armeabi-v7a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 16,
|
|
||||||
"versionName": "0.10.6-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.6-0.14.2-Ananas-armeabi-v7a.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "arm64-v8a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 16,
|
|
||||||
"versionName": "0.10.6-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.6-0.14.2-Ananas-arm64-v8a.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86_64"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 16,
|
|
||||||
"versionName": "0.10.6-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.6-0.14.2-Ananas-x86_64.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 16,
|
|
||||||
"versionName": "0.10.6-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.6-0.14.2-Ananas-x86.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File",
|
|
||||||
"baselineProfiles": [
|
|
||||||
{
|
|
||||||
"minApi": 28,
|
|
||||||
"maxApi": 30,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/1/ananas-v0.10.6-0.14.2-Ananas-armeabi-v7a.dm",
|
|
||||||
"baselineProfiles/1/ananas-v0.10.6-0.14.2-Ananas-arm64-v8a.dm",
|
|
||||||
"baselineProfiles/1/ananas-v0.10.6-0.14.2-Ananas-x86_64.dm",
|
|
||||||
"baselineProfiles/1/ananas-v0.10.6-0.14.2-Ananas-x86.dm"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minApi": 31,
|
|
||||||
"maxApi": 2147483647,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/0/ananas-v0.10.6-0.14.2-Ananas-armeabi-v7a.dm",
|
|
||||||
"baselineProfiles/0/ananas-v0.10.6-0.14.2-Ananas-arm64-v8a.dm",
|
|
||||||
"baselineProfiles/0/ananas-v0.10.6-0.14.2-Ananas-x86_64.dm",
|
|
||||||
"baselineProfiles/0/ananas-v0.10.6-0.14.2-Ananas-x86.dm"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minSdkVersionForDexing": 28
|
|
||||||
}
|
|
|
@ -10,23 +10,19 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.nomadics9.ananas"
|
namespace = "dev.jdtech.jellyfin"
|
||||||
compileSdk = Versions.compileSdk
|
compileSdk = Versions.compileSdk
|
||||||
buildToolsVersion = Versions.buildTools
|
buildToolsVersion = Versions.buildTools
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.nomadics9.ananas"
|
applicationId = "dev.jdtech.jellyfin"
|
||||||
minSdk = Versions.minSdk
|
minSdk = Versions.minSdk
|
||||||
targetSdk = Versions.targetSdk
|
targetSdk = Versions.targetSdk
|
||||||
|
|
||||||
versionCode = Versions.appCode
|
versionCode = Versions.appCode
|
||||||
versionName = Versions.appName
|
versionName = Versions.appName
|
||||||
|
|
||||||
testInstrumentationRunner = "com.nomadics9.ananas.HiltTestRunner"
|
testInstrumentationRunner = "dev.jdtech.jellyfin.HiltTestRunner"
|
||||||
buildConfigField( "String", "DEFAULT_SERVER_ADDRESS", "\" \"")
|
|
||||||
buildConfigField( "String", "REQUEST_SERVER_ADDRESS", "\" \"")
|
|
||||||
buildConfigField("String", "FORGET_PASSWORD_ADDRESS", "\" \"")
|
|
||||||
buildConfigField("String", "UPDATE_ADDRESS", "\" \"")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationVariants.all {
|
applicationVariants.all {
|
||||||
|
@ -35,7 +31,7 @@ android {
|
||||||
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
|
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
|
||||||
.forEach { output ->
|
.forEach { output ->
|
||||||
if (variant.buildType.name == "release") {
|
if (variant.buildType.name == "release") {
|
||||||
val outputFileName = "ananas-v${variant.versionName}-${variant.flavorName}-${output.getFilter("ABI")}.apk"
|
val outputFileName = "findroid-v${variant.versionName}-${variant.flavorName}-${output.getFilter("ABI")}.apk"
|
||||||
output.outputFileName = outputFileName
|
output.outputFileName = outputFileName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,18 +57,10 @@ android {
|
||||||
|
|
||||||
flavorDimensions += "variant"
|
flavorDimensions += "variant"
|
||||||
productFlavors {
|
productFlavors {
|
||||||
create("libre") {
|
register("libre") {
|
||||||
dimension = "variant"
|
dimension = "variant"
|
||||||
isDefault = true
|
isDefault = true
|
||||||
}
|
}
|
||||||
create("Ananas") {
|
|
||||||
dimension = "variant"
|
|
||||||
isDefault = false
|
|
||||||
buildConfigField( "String", "DEFAULT_SERVER_ADDRESS", "\"https://askar.tv\"")
|
|
||||||
buildConfigField( "String", "REQUEST_SERVER_ADDRESS", "\"https://r.askar.tv\"")
|
|
||||||
buildConfigField("String", "FORGET_PASSWORD_ADDRESS", "\"https://user.askar.tv/my/account\"")
|
|
||||||
buildConfigField("String", "UPDATE_ADDRESS", "\"https://fs.nmd.mov/p/ananas.apk\"")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
splits {
|
splits {
|
||||||
|
@ -134,7 +122,6 @@ dependencies {
|
||||||
implementation(libs.material)
|
implementation(libs.material)
|
||||||
implementation(libs.media3.ffmpeg.decoder)
|
implementation(libs.media3.ffmpeg.decoder)
|
||||||
implementation(libs.timber)
|
implementation(libs.timber)
|
||||||
implementation(libs.markwon)
|
|
||||||
|
|
||||||
coreLibraryDesugaring(libs.android.desugar.jdk)
|
coreLibraryDesugaring(libs.android.desugar.jdk)
|
||||||
|
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.nomadics9.ananas",
|
|
||||||
"variantName": "libreRelease",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "armeabi-v7a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 11,
|
|
||||||
"versionName": "0.10.1-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.1-0.14.2-libre-armeabi-v7a.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86_64"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 11,
|
|
||||||
"versionName": "0.10.1-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.1-0.14.2-libre-x86_64.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "arm64-v8a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 11,
|
|
||||||
"versionName": "0.10.1-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.1-0.14.2-libre-arm64-v8a.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 11,
|
|
||||||
"versionName": "0.10.1-0.14.2",
|
|
||||||
"outputFile": "ananas-v0.10.1-0.14.2-libre-x86.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File",
|
|
||||||
"baselineProfiles": [
|
|
||||||
{
|
|
||||||
"minApi": 28,
|
|
||||||
"maxApi": 30,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/1/ananas-v0.10.1-0.14.2-libre-armeabi-v7a.dm",
|
|
||||||
"baselineProfiles/1/ananas-v0.10.1-0.14.2-libre-x86_64.dm",
|
|
||||||
"baselineProfiles/1/ananas-v0.10.1-0.14.2-libre-arm64-v8a.dm",
|
|
||||||
"baselineProfiles/1/ananas-v0.10.1-0.14.2-libre-x86.dm"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minApi": 31,
|
|
||||||
"maxApi": 2147483647,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/0/ananas-v0.10.1-0.14.2-libre-armeabi-v7a.dm",
|
|
||||||
"baselineProfiles/0/ananas-v0.10.1-0.14.2-libre-x86_64.dm",
|
|
||||||
"baselineProfiles/0/ananas-v0.10.1-0.14.2-libre-arm64-v8a.dm",
|
|
||||||
"baselineProfiles/0/ananas-v0.10.1-0.14.2-libre-x86.dm"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minSdkVersionForDexing": 28
|
|
||||||
}
|
|
16
app/phone/proguard-rules.pro
vendored
16
app/phone/proguard-rules.pro
vendored
|
@ -20,16 +20,16 @@
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
-keepnames class com.nomadics9.ananas.models.PlayerItem
|
-keepnames class dev.jdtech.jellyfin.models.PlayerItem
|
||||||
|
|
||||||
# ProGuard thinks all SettingsFragments are unused
|
# ProGuard thinks all SettingsFragments are unused
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsLanguageFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsLanguageFragment
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsAppearanceFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsAppearanceFragment
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsDownloadsFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsDownloadsFragment
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsPlayerFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsPlayerFragment
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsDeviceFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsDeviceFragment
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsCacheFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsCacheFragment
|
||||||
-keep class com.nomadics9.ananas.fragments.SettingsNetworkFragment
|
-keep class dev.jdtech.jellyfin.fragments.SettingsNetworkFragment
|
||||||
|
|
||||||
# These classes are from okhttp and are not used in Android
|
# These classes are from okhttp and are not used in Android
|
||||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.hilt.work.HiltWorkerFactory
|
import androidx.hilt.work.HiltWorkerFactory
|
||||||
|
@ -19,7 +19,7 @@ import androidx.work.testing.WorkManagerTestInitHelper
|
||||||
import dagger.hilt.android.testing.HiltAndroidRule
|
import dagger.hilt.android.testing.HiltAndroidRule
|
||||||
import dagger.hilt.android.testing.HiltAndroidTest
|
import dagger.hilt.android.testing.HiltAndroidTest
|
||||||
import dagger.hilt.android.testing.UninstallModules
|
import dagger.hilt.android.testing.UninstallModules
|
||||||
import com.nomadics9.ananas.di.DatabaseModule
|
import dev.jdtech.jellyfin.di.DatabaseModule
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
import org.hamcrest.CoreMatchers.not
|
import org.hamcrest.CoreMatchers.not
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
@ -76,9 +76,9 @@ class MainActivityTest {
|
||||||
waitForElement(allOf(withText("Movies"), isDisplayed()))
|
waitForElement(allOf(withText("Movies"), isDisplayed()))
|
||||||
onView(withText("Movies")).perform(click())
|
onView(withText("Movies")).perform(click())
|
||||||
|
|
||||||
// Navigate to Battle of the Stars
|
// Navigate to The Boy in the Plastic Bubble
|
||||||
waitForElement(allOf(withText("Battle of the Stars"), isDisplayed()))
|
waitForElement(allOf(withText("The Boy in the Plastic Bubble"), isDisplayed()))
|
||||||
onView(withText("Battle of the Stars")).perform(click())
|
onView(withText("The Boy in the Plastic Bubble")).perform(click())
|
||||||
|
|
||||||
// Play the movie
|
// Play the movie
|
||||||
waitForElement(allOf(withId(R.id.play_button), isEnabled()))
|
waitForElement(allOf(withId(R.id.play_button), isEnabled()))
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.di
|
package dev.jdtech.jellyfin.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
|
@ -7,8 +7,8 @@ import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import com.nomadics9.ananas.database.ServerDatabase
|
import dev.jdtech.jellyfin.database.ServerDatabase
|
||||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
|
@ -1,72 +0,0 @@
|
||||||
package com.nomadics9.ananas.fragments
|
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.webkit.WebSettings
|
|
||||||
import android.webkit.WebView
|
|
||||||
import android.webkit.WebViewClient
|
|
||||||
import android.widget.ProgressBar
|
|
||||||
import androidx.activity.OnBackPressedCallback
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.nomadics9.ananas.BuildConfig
|
|
||||||
import com.nomadics9.ananas.R
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class RequestsWebViewFragment : Fragment() {
|
|
||||||
private lateinit var webView: WebView
|
|
||||||
private lateinit var progressBar: ProgressBar
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
val rootView = inflater.inflate(R.layout.fragment_webview, container, false)
|
|
||||||
|
|
||||||
webView = rootView.findViewById(R.id.webview)
|
|
||||||
progressBar = rootView.findViewById(R.id.progressBar)
|
|
||||||
|
|
||||||
val webSettings: WebSettings = webView.settings
|
|
||||||
webSettings.javaScriptEnabled = true // Enable JavaScript if required
|
|
||||||
|
|
||||||
// Set WebViewClient to handle loading URLs within the WebView
|
|
||||||
webView.webViewClient = object : WebViewClient() {
|
|
||||||
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
|
|
||||||
// Return false to indicate that the WebView should load the URL
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up WebView client to handle page loading events
|
|
||||||
webView.webViewClient = object : WebViewClient() {
|
|
||||||
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
|
||||||
super.onPageStarted(view, url, favicon)
|
|
||||||
progressBar.visibility = View.VISIBLE // Show progress bar when page starts loading
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPageFinished(view: WebView?, url: String?) {
|
|
||||||
super.onPageFinished(view, url)
|
|
||||||
progressBar.visibility = View.GONE // Hide progress bar when page finishes loading
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load your URL here
|
|
||||||
webView.loadUrl(BuildConfig.REQUEST_SERVER_ADDRESS)
|
|
||||||
|
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
|
|
||||||
override fun handleOnBackPressed() {
|
|
||||||
if (webView.canGoBack()) {
|
|
||||||
webView.goBack()
|
|
||||||
} else {
|
|
||||||
isEnabled = false
|
|
||||||
requireActivity().onBackPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return rootView
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,266 +0,0 @@
|
||||||
package com.nomadics9.ananas.fragments
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.Menu
|
|
||||||
import android.view.MenuInflater
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.core.view.MenuHost
|
|
||||||
import androidx.core.view.MenuProvider
|
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.viewModels
|
|
||||||
import androidx.lifecycle.Lifecycle
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import androidx.navigation.fragment.navArgs
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import com.nomadics9.ananas.adapters.EpisodeListAdapter
|
|
||||||
import com.nomadics9.ananas.databinding.FragmentSeasonBinding
|
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
|
||||||
import com.nomadics9.ananas.dialogs.getStorageSelectionDialog
|
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
|
||||||
import com.nomadics9.ananas.viewmodels.SeasonEvent
|
|
||||||
import com.nomadics9.ananas.viewmodels.SeasonViewModel
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.nomadics9.ananas.AppPreferences
|
|
||||||
import com.nomadics9.ananas.models.UiText
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class SeasonFragment : Fragment() {
|
|
||||||
|
|
||||||
private lateinit var binding: FragmentSeasonBinding
|
|
||||||
private val viewModel: SeasonViewModel by viewModels()
|
|
||||||
private val args: SeasonFragmentArgs by navArgs()
|
|
||||||
|
|
||||||
private lateinit var errorDialog: ErrorDialogFragment
|
|
||||||
private lateinit var downloadPreparingDialog: AlertDialog
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var appPreferences: AppPreferences
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?,
|
|
||||||
): View {
|
|
||||||
binding = FragmentSeasonBinding.inflate(inflater, container, false)
|
|
||||||
val menuHost: MenuHost = requireActivity()
|
|
||||||
menuHost.addMenuProvider(
|
|
||||||
object : MenuProvider {
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
|
||||||
menuInflater.inflate(com.nomadics9.ananas.core.R.menu.season_menu, menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
|
||||||
return when (menuItem.itemId) {
|
|
||||||
com.nomadics9.ananas.core.R.id.action_download_season -> {
|
|
||||||
if (requireContext().getExternalFilesDirs(null).filterNotNull().size > 1) {
|
|
||||||
val storageDialog = getStorageSelectionDialog(
|
|
||||||
requireContext(),
|
|
||||||
onItemSelected = { storageIndex ->
|
|
||||||
createEpisodesToDownloadDialog(storageIndex)
|
|
||||||
},
|
|
||||||
onCancel = {
|
|
||||||
},
|
|
||||||
)
|
|
||||||
viewModel.download()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
createEpisodesToDownloadDialog()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
viewLifecycleOwner,
|
|
||||||
Lifecycle.State.RESUMED,
|
|
||||||
)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
|
||||||
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
|
||||||
launch {
|
|
||||||
viewModel.uiState.collect { uiState ->
|
|
||||||
Timber.d("$uiState")
|
|
||||||
when (uiState) {
|
|
||||||
is SeasonViewModel.UiState.Normal -> bindUiStateNormal(uiState)
|
|
||||||
is SeasonViewModel.UiState.Loading -> bindUiStateLoading()
|
|
||||||
is SeasonViewModel.UiState.Error -> bindUiStateError(uiState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
launch {
|
|
||||||
|
|
||||||
viewModel.downloadStatus.collect { (status, progress) ->
|
|
||||||
when (status) {
|
|
||||||
10 -> {
|
|
||||||
downloadPreparingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
launch {
|
|
||||||
viewModel.downloadError.collect { uiText ->
|
|
||||||
createErrorDialog(uiText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
launch {
|
|
||||||
viewModel.eventsChannelFlow.collect { event ->
|
|
||||||
when (event) {
|
|
||||||
is SeasonEvent.NavigateBack -> findNavController().navigateUp()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.errorLayout.errorRetryButton.setOnClickListener {
|
|
||||||
viewModel.loadEpisodes(args.seriesId, args.seasonId, args.offline)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.errorLayout.errorDetailsButton.setOnClickListener {
|
|
||||||
errorDialog.show(parentFragmentManager, ErrorDialogFragment.TAG)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.episodesRecyclerView.adapter =
|
|
||||||
EpisodeListAdapter { episode ->
|
|
||||||
navigateToEpisodeBottomSheetFragment(episode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
|
|
||||||
viewModel.loadEpisodes(args.seriesId, args.seasonId, args.offline)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindUiStateNormal(uiState: SeasonViewModel.UiState.Normal) {
|
|
||||||
uiState.apply {
|
|
||||||
val adapter = binding.episodesRecyclerView.adapter as EpisodeListAdapter
|
|
||||||
adapter.submitList(uiState.episodes)
|
|
||||||
}
|
|
||||||
binding.loadingIndicator.isVisible = false
|
|
||||||
binding.episodesRecyclerView.isVisible = true
|
|
||||||
binding.errorLayout.errorPanel.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindUiStateLoading() {
|
|
||||||
binding.loadingIndicator.isVisible = true
|
|
||||||
binding.errorLayout.errorPanel.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindUiStateError(uiState: SeasonViewModel.UiState.Error) {
|
|
||||||
errorDialog = ErrorDialogFragment.newInstance(uiState.error)
|
|
||||||
binding.loadingIndicator.isVisible = false
|
|
||||||
binding.episodesRecyclerView.isVisible = false
|
|
||||||
binding.errorLayout.errorPanel.isVisible = true
|
|
||||||
checkIfLoginRequired(uiState.error.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createDownloadPreparingDialog() {
|
|
||||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
|
||||||
downloadPreparingDialog = builder
|
|
||||||
.setTitle(com.nomadics9.ananas.core.R.string.preparing_download)
|
|
||||||
.setView(com.nomadics9.ananas.R.layout.preparing_download_dialog)
|
|
||||||
.setCancelable(false)
|
|
||||||
.create()
|
|
||||||
downloadPreparingDialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createErrorDialog(uiText: UiText) {
|
|
||||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
|
||||||
builder
|
|
||||||
.setTitle(com.nomadics9.ananas.core.R.string.downloading_error)
|
|
||||||
.setMessage(uiText.asString(requireContext().resources))
|
|
||||||
.setPositiveButton(getString(com.nomadics9.ananas.core.R.string.close)) { _, _ ->
|
|
||||||
}
|
|
||||||
builder.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createEpisodesToDownloadDialog(storageIndex: Int = 0) {
|
|
||||||
if (!appPreferences.downloadQualityDefault)
|
|
||||||
createPickQualityDialog {
|
|
||||||
showDownloadDialog(storageIndex)
|
|
||||||
} else {
|
|
||||||
showDownloadDialog(storageIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showDownloadDialog(storageIndex: Int = 0) {
|
|
||||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
|
||||||
val dialog = builder
|
|
||||||
.setTitle(com.nomadics9.ananas.core.R.string.download_season_dialog_title)
|
|
||||||
.setMessage(com.nomadics9.ananas.core.R.string.download_season_dialog_question)
|
|
||||||
.setPositiveButton(com.nomadics9.ananas.core.R.string.download_season_dialog_download_all) { _, _ ->
|
|
||||||
createDownloadPreparingDialog()
|
|
||||||
viewModel.download(storageIndex = storageIndex, downloadWatched = true)
|
|
||||||
}
|
|
||||||
.setNegativeButton(com.nomadics9.ananas.core.R.string.download_season_dialog_download_unwatched) { _, _ ->
|
|
||||||
createDownloadPreparingDialog()
|
|
||||||
viewModel.download(storageIndex = storageIndex, downloadWatched = false)
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
dialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createPickQualityDialog(onQualitySelected: () -> Unit) {
|
|
||||||
val qualityEntries = resources.getStringArray(com.nomadics9.ananas.core.R.array.download_quality_entries)
|
|
||||||
val qualityValues = resources.getStringArray(com.nomadics9.ananas.core.R.array.download_quality_values)
|
|
||||||
val quality = appPreferences.downloadQuality
|
|
||||||
val currentQualityIndex = qualityValues.indexOf(quality)
|
|
||||||
|
|
||||||
var selectedQuality = quality
|
|
||||||
|
|
||||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
|
||||||
builder.setTitle("Download Quality")
|
|
||||||
builder.setSingleChoiceItems(qualityEntries, currentQualityIndex) { _, which ->
|
|
||||||
selectedQuality = qualityValues[which]
|
|
||||||
}
|
|
||||||
builder.setPositiveButton("Download") { dialog, _ ->
|
|
||||||
appPreferences.downloadQuality = selectedQuality
|
|
||||||
onQualitySelected()
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
builder.setNegativeButton("Cancel") { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
val dialog = builder.create()
|
|
||||||
dialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun navigateToEpisodeBottomSheetFragment(episode: FindroidEpisode) {
|
|
||||||
findNavController().navigate(
|
|
||||||
SeasonFragmentDirections.actionSeasonFragmentToEpisodeBottomSheetFragment(
|
|
||||||
episode.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
package com.nomadics9.ananas.fragments
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.core.content.res.ResourcesCompat
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import androidx.preference.Preference
|
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
|
||||||
import com.nomadics9.ananas.AppPreferences
|
|
||||||
import com.nomadics9.ananas.BuildConfig
|
|
||||||
import com.nomadics9.ananas.utils.restart
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import timber.log.Timber
|
|
||||||
import java.net.HttpURLConnection
|
|
||||||
import java.net.URL
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class SettingsFragment : PreferenceFragmentCompat() {
|
|
||||||
@Inject
|
|
||||||
lateinit var appPreferences: AppPreferences
|
|
||||||
|
|
||||||
private val updateUrl = BuildConfig.UPDATE_ADDRESS
|
|
||||||
private var isUpdateAvailable: Boolean = false
|
|
||||||
private var newLastModifiedDate: Date? = null
|
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
||||||
setPreferencesFromResource(CoreR.xml.fragment_settings, rootKey)
|
|
||||||
|
|
||||||
findPreference<Preference>("switchServer")?.setOnPreferenceClickListener {
|
|
||||||
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionNavigationSettingsToServerSelectFragment())
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("switchUser")?.setOnPreferenceClickListener {
|
|
||||||
val serverId = appPreferences.currentServer!!
|
|
||||||
findNavController().navigate(
|
|
||||||
TwoPaneSettingsFragmentDirections.actionNavigationSettingsToUsersFragment(
|
|
||||||
serverId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("switchAddress")?.setOnPreferenceClickListener {
|
|
||||||
val serverId = appPreferences.currentServer!!
|
|
||||||
findNavController().navigate(
|
|
||||||
TwoPaneSettingsFragmentDirections.actionNavigationSettingsToServerAddressesFragment(
|
|
||||||
serverId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("pref_offline_mode")?.setOnPreferenceClickListener {
|
|
||||||
activity?.restart()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("privacyPolicy")?.setOnPreferenceClickListener {
|
|
||||||
val intent = Intent(
|
|
||||||
Intent.ACTION_VIEW,
|
|
||||||
Uri.parse("https://github.com/nomadics9/ananas/blob/main/PRIVACY"),
|
|
||||||
)
|
|
||||||
startActivity(intent)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
findPreference<Preference>("appInfo")?.setOnPreferenceClickListener {
|
|
||||||
if (isUpdateAvailable && newLastModifiedDate != null) {
|
|
||||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(updateUrl))
|
|
||||||
startActivity(intent)
|
|
||||||
storeDate(newLastModifiedDate!!)
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionSettingsFragmentToAboutLibraries())
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("requests")?.setOnPreferenceClickListener {
|
|
||||||
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionNavigationSettingsToRequestsWebFragment())
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for updates when the settings screen is opened
|
|
||||||
checkForUpdates()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForUpdates() {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
val lastModifiedDate = fetchLastModifiedDate(updateUrl)
|
|
||||||
if (lastModifiedDate != null) {
|
|
||||||
Timber.d("Fetched Last-Modified date: $lastModifiedDate")
|
|
||||||
val storedDate = getStoredDate()
|
|
||||||
Timber.d("Stored date: $storedDate")
|
|
||||||
if (storedDate == Date(0L) || lastModifiedDate.after(storedDate)) {
|
|
||||||
Timber.d("Update available")
|
|
||||||
isUpdateAvailable = true
|
|
||||||
newLastModifiedDate = lastModifiedDate
|
|
||||||
showUpdateAvailable()
|
|
||||||
} else {
|
|
||||||
Timber.d("No update available")
|
|
||||||
isUpdateAvailable = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Timber.d("Failed to fetch Last-Modified date")
|
|
||||||
isUpdateAvailable = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun fetchLastModifiedDate(urlString: String): Date? {
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
var urlConnection: HttpURLConnection? = null
|
|
||||||
try {
|
|
||||||
val url = URL(urlString)
|
|
||||||
urlConnection = url.openConnection() as HttpURLConnection
|
|
||||||
urlConnection.requestMethod = "HEAD"
|
|
||||||
val lastModified = urlConnection.getHeaderField("Last-Modified")
|
|
||||||
if (lastModified != null) {
|
|
||||||
val dateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US)
|
|
||||||
dateFormat.parse(lastModified)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e, "Error fetching Last-Modified date")
|
|
||||||
null
|
|
||||||
} finally {
|
|
||||||
urlConnection?.disconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getStoredDate(): Date {
|
|
||||||
val sharedPreferences = preferenceManager.sharedPreferences
|
|
||||||
val storedDateString = sharedPreferences?.getString("stored_date", null)
|
|
||||||
Timber.d("Retrieved stored date string: $storedDateString")
|
|
||||||
return if (storedDateString != null) {
|
|
||||||
try {
|
|
||||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US).parse(storedDateString) ?: Date(0)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e, "Error parsing stored date string")
|
|
||||||
Date(0)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Date(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun storeDate(date: Date) {
|
|
||||||
val dateString = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US).format(date)
|
|
||||||
preferenceManager.sharedPreferences?.edit()?.putString("stored_date", dateString)?.apply()
|
|
||||||
Timber.d("Stored new date: $dateString")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showUpdateAvailable() {
|
|
||||||
val appInfoPreference = findPreference<Preference>("appInfo")
|
|
||||||
appInfoPreference?.let {
|
|
||||||
it.summary = "Update available!"
|
|
||||||
it.icon = ResourcesCompat.getDrawable(resources, CoreR.drawable.ic_download, null) // Ensure this drawable exists
|
|
||||||
Timber.d("Update available UI shown")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
@ -14,7 +14,7 @@ import com.google.android.material.color.DynamicColorsOptions
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class BaseApplication : Application(), Configuration.Provider, ImageLoaderFactory {
|
class BaseApplication : Application(), Configuration.Provider, ImageLoaderFactory {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -9,7 +9,7 @@ import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.media3.session.MediaSession
|
import androidx.media3.session.MediaSession
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerActivityViewModel
|
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
|
||||||
|
|
||||||
abstract class BasePlayerActivity : AppCompatActivity() {
|
abstract class BasePlayerActivity : AppCompatActivity() {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import coil.load
|
import coil.load
|
||||||
import com.nomadics9.ananas.api.JellyfinApi
|
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.User
|
import dev.jdtech.jellyfin.models.User
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||||
import org.jellyfin.sdk.model.api.ImageType
|
import org.jellyfin.sdk.model.api.ImageType
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
fun bindItemImage(imageView: ImageView, item: BaseItemDto) {
|
fun bindItemImage(imageView: ImageView, item: BaseItemDto) {
|
||||||
val itemId =
|
val itemId =
|
|
@ -1,10 +1,12 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.NavGraph
|
import androidx.navigation.NavGraph
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
@ -19,16 +21,12 @@ import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.google.android.material.navigation.NavigationBarView
|
import com.google.android.material.navigation.NavigationBarView
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||||
import com.nomadics9.ananas.databinding.ActivityMainBinding
|
import dev.jdtech.jellyfin.databinding.ActivityMainBinding
|
||||||
import com.nomadics9.ananas.viewmodels.MainViewModel
|
import dev.jdtech.jellyfin.viewmodels.MainViewModel
|
||||||
import com.nomadics9.ananas.work.SyncWorker
|
import dev.jdtech.jellyfin.work.SyncWorker
|
||||||
import com.nomadics9.ananas.repository.JellyfinRepository
|
|
||||||
import com.nomadics9.ananas.utils.restart
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
@ -40,9 +38,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var database: ServerDatabaseDao
|
lateinit var database: ServerDatabaseDao
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var jellyfinRepository: JellyfinRepository
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var appPreferences: AppPreferences
|
lateinit var appPreferences: AppPreferences
|
||||||
|
|
||||||
|
@ -53,6 +48,21 @@ class MainActivity : AppCompatActivity() {
|
||||||
scheduleUserDataSync()
|
scheduleUserDataSync()
|
||||||
applyTheme()
|
applyTheme()
|
||||||
setupActivity()
|
setupActivity()
|
||||||
|
|
||||||
|
// Temp fix insets because SDK 35 enables edge to edge by default. This will probably be removed once we move to compose
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
|
||||||
|
val bars = insets.getInsets(
|
||||||
|
WindowInsetsCompat.Type.systemBars()
|
||||||
|
or WindowInsetsCompat.Type.displayCutout(),
|
||||||
|
)
|
||||||
|
v.updatePadding(
|
||||||
|
left = bars.left,
|
||||||
|
top = bars.top,
|
||||||
|
right = bars.right,
|
||||||
|
bottom = bars.bottom,
|
||||||
|
)
|
||||||
|
WindowInsetsCompat.CONSUMED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(NavigationUiSaveStateControl::class)
|
@OptIn(NavigationUiSaveStateControl::class)
|
||||||
|
@ -76,18 +86,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
val navView: NavigationBarView = binding.navView as NavigationBarView
|
val navView: NavigationBarView = binding.navView as NavigationBarView
|
||||||
|
|
||||||
if (appPreferences.offlineMode) {
|
if (appPreferences.offlineMode) {
|
||||||
appPreferences.isOffline = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appPreferences.isOffline) {
|
|
||||||
navView.menu.clear()
|
navView.menu.clear()
|
||||||
navView.inflateMenu(CoreR.menu.bottom_nav_menu_offline)
|
navView.inflateMenu(CoreR.menu.bottom_nav_menu_offline)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!appPreferences.isOffline && appPreferences.autoOffline) {
|
|
||||||
testServerConnection()
|
|
||||||
}
|
|
||||||
|
|
||||||
setSupportActionBar(binding.mainToolbar)
|
setSupportActionBar(binding.mainToolbar)
|
||||||
|
|
||||||
// Passing each menu ID as a set of Ids because each
|
// Passing each menu ID as a set of Ids because each
|
||||||
|
@ -108,7 +110,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
navController.addOnDestinationChangedListener { _, destination, _ ->
|
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||||
binding.navView.visibility = when (destination.id) {
|
binding.navView.visibility = when (destination.id) {
|
||||||
R.id.twoPaneSettingsFragment, R.id.serverSelectFragment, R.id.addServerFragment, R.id.loginFragment, com.mikepenz.aboutlibraries.R.id.about_libraries_dest, R.id.usersFragment, R.id.serverAddressesFragment, R.id.requestsWebFragment -> View.GONE
|
R.id.twoPaneSettingsFragment, R.id.serverSelectFragment, R.id.addServerFragment, R.id.loginFragment, com.mikepenz.aboutlibraries.R.id.about_libraries_dest, R.id.usersFragment, R.id.serverAddressesFragment -> View.GONE
|
||||||
else -> View.VISIBLE
|
else -> View.VISIBLE
|
||||||
}
|
}
|
||||||
if (destination.id == com.mikepenz.aboutlibraries.R.id.about_libraries_dest) {
|
if (destination.id == com.mikepenz.aboutlibraries.R.id.about_libraries_dest) {
|
||||||
|
@ -168,18 +170,4 @@ class MainActivity : AppCompatActivity() {
|
||||||
setTheme(CoreR.style.ThemeOverlay_Findroid_Amoled)
|
setTheme(CoreR.style.ThemeOverlay_Findroid_Amoled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testServerConnection() {
|
|
||||||
val activity = this
|
|
||||||
lifecycleScope.launch {
|
|
||||||
try {
|
|
||||||
jellyfinRepository.getPublicSystemInfo()
|
|
||||||
// Give the UI a chance to load
|
|
||||||
delay(100)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
appPreferences.isOffline = true
|
|
||||||
activity.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.AppOpsManager
|
import android.app.AppOpsManager
|
||||||
import android.app.PictureInPictureParams
|
import android.app.PictureInPictureParams
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -34,25 +35,25 @@ import androidx.media3.ui.PlayerControlView
|
||||||
import androidx.media3.ui.PlayerView
|
import androidx.media3.ui.PlayerView
|
||||||
import androidx.navigation.navArgs
|
import androidx.navigation.navArgs
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.nomadics9.ananas.databinding.ActivityPlayerBinding
|
|
||||||
import com.nomadics9.ananas.dialogs.SpeedSelectionDialogFragment
|
|
||||||
import com.nomadics9.ananas.dialogs.TrackSelectionDialogFragment
|
|
||||||
import com.nomadics9.ananas.models.FindroidSegment
|
|
||||||
import com.nomadics9.ananas.utils.PlayerGestureHelper
|
|
||||||
import com.nomadics9.ananas.utils.PreviewScrubListener
|
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerActivityViewModel
|
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerEvents
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import dev.jdtech.jellyfin.databinding.ActivityPlayerBinding
|
||||||
|
import dev.jdtech.jellyfin.dialogs.SpeedSelectionDialogFragment
|
||||||
|
import dev.jdtech.jellyfin.dialogs.TrackSelectionDialogFragment
|
||||||
|
import dev.jdtech.jellyfin.models.VideoQuality
|
||||||
|
import dev.jdtech.jellyfin.utils.PlayerGestureHelper
|
||||||
|
import dev.jdtech.jellyfin.utils.PreviewScrubListener
|
||||||
|
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
|
||||||
|
import dev.jdtech.jellyfin.viewmodels.PlayerEvents
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
import com.nomadics9.ananas.models.VideoQuality
|
|
||||||
|
|
||||||
var isControlsLocked: Boolean = false
|
var isControlsLocked: Boolean = false
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class PlayerActivity : BasePlayerActivity() {
|
class PlayerActivity : BasePlayerActivity() {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var appPreferences: AppPreferences
|
lateinit var appPreferences: AppPreferences
|
||||||
|
|
||||||
|
@ -61,8 +62,6 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
override val viewModel: PlayerActivityViewModel by viewModels()
|
override val viewModel: PlayerActivityViewModel by viewModels()
|
||||||
private var previewScrubListener: PreviewScrubListener? = null
|
private var previewScrubListener: PreviewScrubListener? = null
|
||||||
private var wasZoom: Boolean = false
|
private var wasZoom: Boolean = false
|
||||||
private var oldSegment: FindroidSegment? = null
|
|
||||||
private var buttonPressed: Boolean = false
|
|
||||||
|
|
||||||
private val isPipSupported by lazy {
|
private val isPipSupported by lazy {
|
||||||
// Check if device has PiP feature
|
// Check if device has PiP feature
|
||||||
|
@ -111,12 +110,11 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
configureInsets(lockedControls)
|
configureInsets(lockedControls)
|
||||||
|
|
||||||
if (appPreferences.playerGestures) {
|
if (appPreferences.playerGestures) {
|
||||||
playerGestureHelper =
|
playerGestureHelper = PlayerGestureHelper(
|
||||||
PlayerGestureHelper(
|
|
||||||
appPreferences,
|
appPreferences,
|
||||||
this,
|
this,
|
||||||
binding.playerView,
|
binding.playerView,
|
||||||
getSystemService(AUDIO_SERVICE) as AudioManager,
|
getSystemService(Context.AUDIO_SERVICE) as AudioManager,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +127,7 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
val audioButton = binding.playerView.findViewById<ImageButton>(R.id.btn_audio_track)
|
val audioButton = binding.playerView.findViewById<ImageButton>(R.id.btn_audio_track)
|
||||||
val subtitleButton = binding.playerView.findViewById<ImageButton>(R.id.btn_subtitle)
|
val subtitleButton = binding.playerView.findViewById<ImageButton>(R.id.btn_subtitle)
|
||||||
val speedButton = binding.playerView.findViewById<ImageButton>(R.id.btn_speed)
|
val speedButton = binding.playerView.findViewById<ImageButton>(R.id.btn_speed)
|
||||||
val skipButton = binding.playerView.findViewById<Button>(R.id.btn_skip_intro)
|
val skipIntroButton = binding.playerView.findViewById<Button>(R.id.btn_skip_intro)
|
||||||
val watchCreditsButton = binding.playerView.findViewById<Button>(R.id.btn_watch_credits)
|
|
||||||
val pipButton = binding.playerView.findViewById<ImageButton>(R.id.btn_pip)
|
val pipButton = binding.playerView.findViewById<ImageButton>(R.id.btn_pip)
|
||||||
val lockButton = binding.playerView.findViewById<ImageButton>(R.id.btn_lockview)
|
val lockButton = binding.playerView.findViewById<ImageButton>(R.id.btn_lockview)
|
||||||
val unlockButton = binding.playerView.findViewById<ImageButton>(R.id.btn_unlock)
|
val unlockButton = binding.playerView.findViewById<ImageButton>(R.id.btn_unlock)
|
||||||
|
@ -144,101 +141,19 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
// Title
|
// Title
|
||||||
videoNameTextView.text = currentItemTitle
|
videoNameTextView.text = currentItemTitle
|
||||||
|
|
||||||
// Skip Button
|
// Skip Intro button
|
||||||
if (currentSegment != oldSegment) buttonPressed = false
|
skipIntroButton.isVisible = !isInPictureInPictureMode && currentIntro != null
|
||||||
// Button Visibility and Text
|
skipIntroButton.setOnClickListener {
|
||||||
when (currentSegment?.type) {
|
currentIntro?.let {
|
||||||
"intro" -> {
|
binding.playerView.player?.seekTo((it.introEnd * 1000).toLong())
|
||||||
skipButton.text =
|
|
||||||
getString(CoreR.string.skip_intro_button)
|
|
||||||
skipButton.isVisible =
|
|
||||||
!isInPictureInPictureMode &&
|
|
||||||
!buttonPressed &&
|
|
||||||
(
|
|
||||||
showSkip == true ||
|
|
||||||
(binding.playerView.isControllerFullyVisible && currentSegment?.skip == true)
|
|
||||||
)
|
|
||||||
watchCreditsButton.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
"credit" -> {
|
|
||||||
skipButton.text =
|
|
||||||
if (binding.playerView.player?.hasNextMediaItem() == true) {
|
|
||||||
getString(CoreR.string.skip_credit_button)
|
|
||||||
} else {
|
|
||||||
getString(CoreR.string.skip_credit_button_last)
|
|
||||||
}
|
|
||||||
skipButton.isVisible =
|
|
||||||
!isInPictureInPictureMode &&
|
|
||||||
!buttonPressed &&
|
|
||||||
currentSegment?.skip == true &&
|
|
||||||
!binding.playerView.isControllerFullyVisible
|
|
||||||
watchCreditsButton.isVisible = skipButton.isVisible
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
skipButton.isVisible = false
|
|
||||||
watchCreditsButton.isVisible = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.playerView.setControllerVisibilityListener(
|
|
||||||
PlayerView.ControllerVisibilityListener { visibility ->
|
|
||||||
when (currentSegment?.type) {
|
|
||||||
"intro" -> {
|
|
||||||
skipButton.isVisible =
|
|
||||||
!buttonPressed &&
|
|
||||||
(showSkip == true || (visibility == View.VISIBLE && currentSegment?.skip == true))
|
|
||||||
}
|
|
||||||
|
|
||||||
"credit" -> {
|
|
||||||
skipButton.isVisible =
|
|
||||||
!buttonPressed &&
|
|
||||||
currentSegment?.skip == true &&
|
|
||||||
visibility == View.GONE
|
|
||||||
watchCreditsButton.isVisible = skipButton.isVisible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
// onClick
|
|
||||||
if (currentSegment?.type == "credit") {
|
|
||||||
watchCreditsButton.setOnClickListener {
|
|
||||||
buttonPressed = true
|
|
||||||
skipButton.isVisible = false
|
|
||||||
watchCreditsButton.isVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
skipButton.setOnClickListener {
|
|
||||||
when (currentSegment?.type) {
|
|
||||||
"intro" -> {
|
|
||||||
currentSegment?.let {
|
|
||||||
binding.playerView.player?.seekTo((it.endTime * 1000).toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"credit" -> {
|
|
||||||
if (binding.playerView.player?.hasNextMediaItem() == true) {
|
|
||||||
binding.playerView.player?.seekToNext()
|
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buttonPressed = true
|
|
||||||
skipButton.isVisible = false
|
|
||||||
watchCreditsButton.isVisible = false
|
|
||||||
}
|
|
||||||
oldSegment = currentSegment
|
|
||||||
|
|
||||||
// Trickplay
|
// Trickplay
|
||||||
previewScrubListener?.let {
|
previewScrubListener?.let {
|
||||||
it.currentTrickplay = currentTrickplay
|
it.currentTrickplay = currentTrickplay
|
||||||
}
|
}
|
||||||
|
|
||||||
playerGestureHelper?.let {
|
|
||||||
it.currentTrickplay = currentTrickplay
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chapters
|
// Chapters
|
||||||
if (appPreferences.showChapterMarkers && currentChapters != null) {
|
if (appPreferences.showChapterMarkers && currentChapters != null) {
|
||||||
currentChapters?.let { chapters ->
|
currentChapters?.let { chapters ->
|
||||||
|
@ -276,8 +191,7 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
if (appPreferences.playerPipGesture) {
|
if (appPreferences.playerPipGesture) {
|
||||||
try {
|
try {
|
||||||
setPictureInPictureParams(pipParams(event.isPlaying))
|
setPictureInPictureParams(pipParams(event.isPlaying))
|
||||||
} catch (_: IllegalArgumentException) {
|
} catch (_: IllegalArgumentException) { }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,6 +290,7 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
viewModel.initializePlayer(args.items)
|
viewModel.initializePlayer(args.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingSuperCall")
|
||||||
override fun onUserLeaveHint() {
|
override fun onUserLeaveHint() {
|
||||||
super.onUserLeaveHint()
|
super.onUserLeaveHint()
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S &&
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S &&
|
||||||
|
@ -390,16 +305,14 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
private fun pipParams(enableAutoEnter: Boolean = viewModel.player.isPlaying): PictureInPictureParams {
|
private fun pipParams(enableAutoEnter: Boolean = viewModel.player.isPlaying): PictureInPictureParams {
|
||||||
val displayAspectRatio = Rational(binding.playerView.width, binding.playerView.height)
|
val displayAspectRatio = Rational(binding.playerView.width, binding.playerView.height)
|
||||||
|
|
||||||
val aspectRatio =
|
val aspectRatio = binding.playerView.player?.videoSize?.let {
|
||||||
binding.playerView.player?.videoSize?.let {
|
|
||||||
Rational(
|
Rational(
|
||||||
it.width.coerceAtMost((it.height * 2.39f).toInt()),
|
it.width.coerceAtMost((it.height * 2.39f).toInt()),
|
||||||
it.height.coerceAtMost((it.width * 2.39f).toInt()),
|
it.height.coerceAtMost((it.width * 2.39f).toInt()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sourceRectHint =
|
val sourceRectHint = if (displayAspectRatio < aspectRatio!!) {
|
||||||
if (displayAspectRatio < aspectRatio!!) {
|
|
||||||
val space = ((binding.playerView.height - (binding.playerView.width.toFloat() / aspectRatio.toFloat())) / 2).toInt()
|
val space = ((binding.playerView.height - (binding.playerView.width.toFloat() / aspectRatio.toFloat())) / 2).toInt()
|
||||||
Rect(
|
Rect(
|
||||||
0,
|
0,
|
||||||
|
@ -417,9 +330,7 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val builder =
|
val builder = PictureInPictureParams.Builder()
|
||||||
PictureInPictureParams
|
|
||||||
.Builder()
|
|
||||||
.setAspectRatio(aspectRatio)
|
.setAspectRatio(aspectRatio)
|
||||||
.setSourceRectHint(sourceRectHint)
|
.setSourceRectHint(sourceRectHint)
|
||||||
|
|
||||||
|
@ -479,8 +390,7 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
playerGestureHelper?.updateZoomMode(false)
|
playerGestureHelper?.updateZoomMode(false)
|
||||||
|
|
||||||
// Brightness mode Auto
|
// Brightness mode Auto
|
||||||
window.attributes =
|
window.attributes = window.attributes.apply {
|
||||||
window.attributes.apply {
|
|
||||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,14 +399,11 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
playerGestureHelper?.updateZoomMode(wasZoom)
|
playerGestureHelper?.updateZoomMode(wasZoom)
|
||||||
|
|
||||||
// Override auto brightness
|
// Override auto brightness
|
||||||
window.attributes =
|
window.attributes = window.attributes.apply {
|
||||||
window.attributes.apply {
|
screenBrightness = if (appPreferences.playerBrightnessRemember) {
|
||||||
screenBrightness =
|
|
||||||
if (appPreferences.playerBrightnessRemember) {
|
|
||||||
appPreferences.playerBrightness
|
appPreferences.playerBrightness
|
||||||
} else {
|
} else {
|
||||||
Settings.System
|
Settings.System.getInt(
|
||||||
.getInt(
|
|
||||||
contentResolver,
|
contentResolver,
|
||||||
Settings.System.SCREEN_BRIGHTNESS,
|
Settings.System.SCREEN_BRIGHTNESS,
|
||||||
).toFloat() / 255
|
).toFloat() / 255
|
|
@ -1,13 +1,13 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindCardItemImage
|
import dev.jdtech.jellyfin.bindCardItemImage
|
||||||
import com.nomadics9.ananas.databinding.CollectionItemBinding
|
import dev.jdtech.jellyfin.databinding.CollectionItemBinding
|
||||||
import com.nomadics9.ananas.models.FindroidCollection
|
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||||
|
|
||||||
class CollectionListAdapter(
|
class CollectionListAdapter(
|
||||||
private val onClickListener: (collection: FindroidCollection) -> Unit,
|
private val onClickListener: (collection: FindroidCollection) -> Unit,
|
|
@ -1,12 +1,12 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.databinding.DiscoveredServerItemBinding
|
import dev.jdtech.jellyfin.databinding.DiscoveredServerItemBinding
|
||||||
import com.nomadics9.ananas.models.DiscoveredServer
|
import dev.jdtech.jellyfin.models.DiscoveredServer
|
||||||
|
|
||||||
class DiscoveredServerListAdapter(
|
class DiscoveredServerListAdapter(
|
||||||
private val clickListener: (server: DiscoveredServer) -> Unit,
|
private val clickListener: (server: DiscoveredServer) -> Unit,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.text.Html.fromHtml
|
import android.text.Html.fromHtml
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
@ -9,15 +9,15 @@ import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindCardItemImage
|
import dev.jdtech.jellyfin.bindCardItemImage
|
||||||
import com.nomadics9.ananas.bindItemBackdropById
|
import dev.jdtech.jellyfin.bindItemBackdropById
|
||||||
import com.nomadics9.ananas.bindSeasonPoster
|
import dev.jdtech.jellyfin.bindSeasonPoster
|
||||||
import com.nomadics9.ananas.databinding.EpisodeItemBinding
|
import dev.jdtech.jellyfin.databinding.EpisodeItemBinding
|
||||||
import com.nomadics9.ananas.databinding.SeasonHeaderBinding
|
import dev.jdtech.jellyfin.databinding.SeasonHeaderBinding
|
||||||
import com.nomadics9.ananas.models.EpisodeItem
|
import dev.jdtech.jellyfin.models.EpisodeItem
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
private const val ITEM_VIEW_TYPE_HEADER = 0
|
private const val ITEM_VIEW_TYPE_HEADER = 0
|
||||||
private const val ITEM_VIEW_TYPE_EPISODE = 1
|
private const val ITEM_VIEW_TYPE_EPISODE = 1
|
|
@ -1,14 +1,14 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.Constants
|
import dev.jdtech.jellyfin.Constants
|
||||||
import com.nomadics9.ananas.databinding.FavoriteSectionBinding
|
import dev.jdtech.jellyfin.databinding.FavoriteSectionBinding
|
||||||
import com.nomadics9.ananas.models.FavoriteSection
|
import dev.jdtech.jellyfin.models.FavoriteSection
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
|
|
||||||
class FavoritesListAdapter(
|
class FavoritesListAdapter(
|
||||||
private val onItemClickListener: (item: FindroidItem) -> Unit,
|
private val onItemClickListener: (item: FindroidItem) -> Unit,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -8,13 +8,13 @@ import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindCardItemImage
|
import dev.jdtech.jellyfin.bindCardItemImage
|
||||||
import com.nomadics9.ananas.databinding.HomeEpisodeItemBinding
|
import dev.jdtech.jellyfin.databinding.HomeEpisodeItemBinding
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class HomeEpisodeListAdapter(private val onClickListener: (item: FindroidItem) -> Unit) : ListAdapter<FindroidItem, HomeEpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
|
class HomeEpisodeListAdapter(private val onClickListener: (item: FindroidItem) -> Unit) : ListAdapter<FindroidItem, HomeEpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
|
||||||
class EpisodeViewHolder(
|
class EpisodeViewHolder(
|
|
@ -1,12 +1,12 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindPersonImage
|
import dev.jdtech.jellyfin.bindPersonImage
|
||||||
import com.nomadics9.ananas.databinding.PersonItemBinding
|
import dev.jdtech.jellyfin.databinding.PersonItemBinding
|
||||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||||
|
|
||||||
class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Unit) : ListAdapter<BaseItemPerson, PersonListAdapter.PersonViewHolder>(DiffCallback) {
|
class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Unit) : ListAdapter<BaseItemPerson, PersonListAdapter.PersonViewHolder>(DiffCallback) {
|
|
@ -1,12 +1,12 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.databinding.ServerAddressListItemBinding
|
import dev.jdtech.jellyfin.databinding.ServerAddressListItemBinding
|
||||||
import com.nomadics9.ananas.models.ServerAddress
|
import dev.jdtech.jellyfin.models.ServerAddress
|
||||||
|
|
||||||
class ServerAddressAdapter(
|
class ServerAddressAdapter(
|
||||||
private val clickListener: (address: ServerAddress) -> Unit,
|
private val clickListener: (address: ServerAddress) -> Unit,
|
|
@ -1,12 +1,12 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.databinding.ServerItemBinding
|
import dev.jdtech.jellyfin.databinding.ServerItemBinding
|
||||||
import com.nomadics9.ananas.models.Server
|
import dev.jdtech.jellyfin.models.Server
|
||||||
|
|
||||||
class ServerGridAdapter(
|
class ServerGridAdapter(
|
||||||
private val onClickListener: (server: Server) -> Unit,
|
private val onClickListener: (server: Server) -> Unit,
|
|
@ -1,13 +1,13 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindUserImage
|
import dev.jdtech.jellyfin.bindUserImage
|
||||||
import com.nomadics9.ananas.databinding.UserListItemBinding
|
import dev.jdtech.jellyfin.databinding.UserListItemBinding
|
||||||
import com.nomadics9.ananas.models.User
|
import dev.jdtech.jellyfin.models.User
|
||||||
|
|
||||||
class UserListAdapter(
|
class UserListAdapter(
|
||||||
private val clickListener: (user: User) -> Unit,
|
private val clickListener: (user: User) -> Unit,
|
|
@ -1,13 +1,13 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindUserImage
|
import dev.jdtech.jellyfin.bindUserImage
|
||||||
import com.nomadics9.ananas.databinding.UserItemBinding
|
import dev.jdtech.jellyfin.databinding.UserItemBinding
|
||||||
import com.nomadics9.ananas.models.User
|
import dev.jdtech.jellyfin.models.User
|
||||||
|
|
||||||
class UserLoginListAdapter(
|
class UserLoginListAdapter(
|
||||||
private val clickListener: (user: User) -> Unit,
|
private val clickListener: (user: User) -> Unit,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -7,12 +7,12 @@ import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindItemImage
|
import dev.jdtech.jellyfin.bindItemImage
|
||||||
import com.nomadics9.ananas.databinding.BaseItemBinding
|
import dev.jdtech.jellyfin.databinding.BaseItemBinding
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class ViewItemListAdapter(
|
class ViewItemListAdapter(
|
||||||
private val onClickListener: (item: FindroidItem) -> Unit,
|
private val onClickListener: (item: FindroidItem) -> Unit,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -7,12 +7,12 @@ import androidx.core.view.isVisible
|
||||||
import androidx.paging.PagingDataAdapter
|
import androidx.paging.PagingDataAdapter
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.bindItemImage
|
import dev.jdtech.jellyfin.bindItemImage
|
||||||
import com.nomadics9.ananas.databinding.BaseItemBinding
|
import dev.jdtech.jellyfin.databinding.BaseItemBinding
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class ViewItemPagingAdapter(
|
class ViewItemPagingAdapter(
|
||||||
private val onClickListener: (item: FindroidItem) -> Unit,
|
private val onClickListener: (item: FindroidItem) -> Unit,
|
|
@ -1,17 +1,17 @@
|
||||||
package com.nomadics9.ananas.adapters
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nomadics9.ananas.databinding.CardOfflineBinding
|
import dev.jdtech.jellyfin.databinding.CardOfflineBinding
|
||||||
import com.nomadics9.ananas.databinding.NextUpSectionBinding
|
import dev.jdtech.jellyfin.databinding.NextUpSectionBinding
|
||||||
import com.nomadics9.ananas.databinding.ViewItemBinding
|
import dev.jdtech.jellyfin.databinding.ViewItemBinding
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.HomeItem
|
import dev.jdtech.jellyfin.models.HomeItem
|
||||||
import com.nomadics9.ananas.models.View
|
import dev.jdtech.jellyfin.models.View
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
private const val ITEM_VIEW_TYPE_NEXT_UP = 0
|
private const val ITEM_VIEW_TYPE_NEXT_UP = 0
|
||||||
private const val ITEM_VIEW_TYPE_VIEW = 1
|
private const val ITEM_VIEW_TYPE_VIEW = 1
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.di
|
package dev.jdtech.jellyfin.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
@ -6,7 +6,7 @@ import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import com.nomadics9.ananas.BaseApplication
|
import dev.jdtech.jellyfin.BaseApplication
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
|
@ -1,11 +1,11 @@
|
||||||
package com.nomadics9.ananas.dialogs
|
package dev.jdtech.jellyfin.dialogs
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.os.StatFs
|
import android.os.StatFs
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
fun getStorageSelectionDialog(
|
fun getStorageSelectionDialog(
|
||||||
context: Context,
|
context: Context,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
|
@ -14,12 +14,11 @@ import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.nomadics9.ananas.BuildConfig
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.DiscoveredServerListAdapter
|
import dev.jdtech.jellyfin.adapters.DiscoveredServerListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentAddServerBinding
|
import dev.jdtech.jellyfin.databinding.FragmentAddServerBinding
|
||||||
import com.nomadics9.ananas.viewmodels.AddServerEvent
|
import dev.jdtech.jellyfin.viewmodels.AddServerEvent
|
||||||
import com.nomadics9.ananas.viewmodels.AddServerViewModel
|
import dev.jdtech.jellyfin.viewmodels.AddServerViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@ -90,12 +89,7 @@ class AddServerFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BuildConfig.FLAVOR == "Ananas") {
|
|
||||||
fun connectToServerDirectly(serverAddress: String = BuildConfig.DEFAULT_SERVER_ADDRESS) {
|
|
||||||
viewModel.checkServer(serverAddress.removeSuffix("/"))
|
|
||||||
}
|
|
||||||
connectToServerDirectly()
|
|
||||||
}
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,16 +134,6 @@ class AddServerFragment : Fragment() {
|
||||||
viewModel.checkServer(serverAddress.removeSuffix("/"))
|
viewModel.checkServer(serverAddress.removeSuffix("/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private fun connectToServer() {
|
|
||||||
// val serverAddress = (binding.editTextServerAddress as AppCompatEditText).text.toString()
|
|
||||||
// if (serverAddress.isNotBlank()) {
|
|
||||||
// viewModel.checkServer(serverAddress.removeSuffix("/"))
|
|
||||||
// } else {
|
|
||||||
// viewModel.checkServer(BuildConfig.DEFAULT_SERVER_ADDRESS.removeSuffix("/"))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun navigateToLoginFragment() {
|
private fun navigateToLoginFragment() {
|
||||||
findNavController().navigate(AddServerFragmentDirections.actionAddServerFragmentToLoginFragment())
|
findNavController().navigate(AddServerFragmentDirections.actionAddServerFragmentToLoginFragment())
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -13,18 +13,18 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentFavoriteBinding
|
import dev.jdtech.jellyfin.databinding.FragmentFavoriteBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.viewmodels.CollectionViewModel
|
import dev.jdtech.jellyfin.viewmodels.CollectionViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class CollectionFragment : Fragment() {
|
class CollectionFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -13,19 +13,19 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentDownloadsBinding
|
import dev.jdtech.jellyfin.databinding.FragmentDownloadsBinding
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.utils.restart
|
import dev.jdtech.jellyfin.utils.restart
|
||||||
import com.nomadics9.ananas.viewmodels.DownloadsEvent
|
import dev.jdtech.jellyfin.viewmodels.DownloadsEvent
|
||||||
import com.nomadics9.ananas.viewmodels.DownloadsViewModel
|
import dev.jdtech.jellyfin.viewmodels.DownloadsViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class DownloadsFragment : Fragment() {
|
class DownloadsFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -21,23 +21,23 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.R
|
import dev.jdtech.jellyfin.R
|
||||||
import com.nomadics9.ananas.bindCardItemImage
|
import dev.jdtech.jellyfin.bindCardItemImage
|
||||||
import com.nomadics9.ananas.databinding.EpisodeBottomSheetBinding
|
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.dialogs.getStorageSelectionDialog
|
import dev.jdtech.jellyfin.dialogs.getStorageSelectionDialog
|
||||||
import com.nomadics9.ananas.dialogs.getVideoVersionDialog
|
import dev.jdtech.jellyfin.dialogs.getVideoVersionDialog
|
||||||
import com.nomadics9.ananas.models.FindroidSourceType
|
import dev.jdtech.jellyfin.models.FindroidSourceType
|
||||||
import com.nomadics9.ananas.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import com.nomadics9.ananas.models.UiText
|
import dev.jdtech.jellyfin.models.UiText
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.models.isDownloading
|
import dev.jdtech.jellyfin.models.isDownloading
|
||||||
import com.nomadics9.ananas.utils.setIconTintColorAttribute
|
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
|
||||||
import com.nomadics9.ananas.viewmodels.EpisodeBottomSheetEvent
|
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetEvent
|
||||||
import com.nomadics9.ananas.viewmodels.EpisodeBottomSheetViewModel
|
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.sdk.model.DateTime
|
import org.jellyfin.sdk.model.DateTime
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -48,7 +48,7 @@ import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import android.R as AndroidR
|
import android.R as AndroidR
|
||||||
import com.google.android.material.R as MaterialR
|
import com.google.android.material.R as MaterialR
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
|
class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -12,15 +12,15 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentFavoriteBinding
|
import dev.jdtech.jellyfin.databinding.FragmentFavoriteBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.viewmodels.FavoriteViewModel
|
import dev.jdtech.jellyfin.viewmodels.FavoriteViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -19,21 +19,21 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.adapters.ViewListAdapter
|
import dev.jdtech.jellyfin.adapters.ViewListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentHomeBinding
|
import dev.jdtech.jellyfin.databinding.FragmentHomeBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.utils.restart
|
import dev.jdtech.jellyfin.utils.restart
|
||||||
import com.nomadics9.ananas.viewmodels.HomeViewModel
|
import dev.jdtech.jellyfin.viewmodels.HomeViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class HomeFragment : Fragment() {
|
class HomeFragment : Fragment() {
|
||||||
|
@ -74,12 +74,6 @@ class HomeFragment : Fragment() {
|
||||||
val searchView = search.actionView as SearchView
|
val searchView = search.actionView as SearchView
|
||||||
searchView.queryHint = getString(CoreR.string.search_hint)
|
searchView.queryHint = getString(CoreR.string.search_hint)
|
||||||
|
|
||||||
val requests = menu.findItem(CoreR.id.action_requests)
|
|
||||||
requests.setOnMenuItemClickListener{
|
|
||||||
navigateToRequestsWebViewFragment()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
search.setOnActionExpandListener(
|
search.setOnActionExpandListener(
|
||||||
object : MenuItem.OnActionExpandListener {
|
object : MenuItem.OnActionExpandListener {
|
||||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||||
|
@ -208,7 +202,7 @@ class HomeFragment : Fragment() {
|
||||||
checkIfLoginRequired(uiState.error.message)
|
checkIfLoginRequired(uiState.error.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToLibraryFragment(view: com.nomadics9.ananas.models.View) {
|
private fun navigateToLibraryFragment(view: dev.jdtech.jellyfin.models.View) {
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
HomeFragmentDirections.actionNavigationHomeToLibraryFragment(
|
HomeFragmentDirections.actionNavigationHomeToLibraryFragment(
|
||||||
libraryId = view.id,
|
libraryId = view.id,
|
||||||
|
@ -257,10 +251,4 @@ class HomeFragment : Fragment() {
|
||||||
HomeFragmentDirections.actionHomeFragmentToSearchResultFragment(query),
|
HomeFragmentDirections.actionHomeFragmentToSearchResultFragment(query),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToRequestsWebViewFragment() {
|
|
||||||
findNavController().navigate(
|
|
||||||
HomeFragmentDirections.actionHomeFragmentToRequestsWebFragment()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -19,25 +19,24 @@ import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.adapters.ViewItemPagingAdapter
|
import dev.jdtech.jellyfin.adapters.ViewItemPagingAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentLibraryBinding
|
import dev.jdtech.jellyfin.databinding.FragmentLibraryBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.dialogs.SortDialogFragment
|
import dev.jdtech.jellyfin.dialogs.SortDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidBoxSet
|
import dev.jdtech.jellyfin.models.FindroidBoxSet
|
||||||
import com.nomadics9.ananas.models.FindroidFolder
|
import dev.jdtech.jellyfin.models.FindroidFolder
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.models.SortBy
|
import dev.jdtech.jellyfin.models.SortBy
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.viewmodels.LibraryViewModel
|
import dev.jdtech.jellyfin.viewmodels.LibraryViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.sdk.model.api.SortOrder
|
import org.jellyfin.sdk.model.api.SortOrder
|
||||||
import java.lang.IllegalArgumentException
|
import java.lang.IllegalArgumentException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class LibraryFragment : Fragment() {
|
class LibraryFragment : Fragment() {
|
||||||
|
@ -63,11 +62,6 @@ class LibraryFragment : Fragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
binding.itemsRecyclerView.layoutManager =
|
|
||||||
GridLayoutManager(context, preferences.spanCount)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val menuHost: MenuHost = requireActivity()
|
val menuHost: MenuHost = requireActivity()
|
||||||
menuHost.addMenuProvider(
|
menuHost.addMenuProvider(
|
||||||
object : MenuProvider {
|
object : MenuProvider {
|
|
@ -1,7 +1,5 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Html.fromHtml
|
import android.text.Html.fromHtml
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -18,18 +16,16 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.BuildConfig
|
import dev.jdtech.jellyfin.adapters.UserLoginListAdapter
|
||||||
import com.nomadics9.ananas.adapters.UserLoginListAdapter
|
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
import dev.jdtech.jellyfin.databinding.FragmentLoginBinding
|
||||||
import com.nomadics9.ananas.databinding.FragmentLoginBinding
|
import dev.jdtech.jellyfin.viewmodels.LoginEvent
|
||||||
import com.nomadics9.ananas.viewmodels.LoginEvent
|
import dev.jdtech.jellyfin.viewmodels.LoginViewModel
|
||||||
import com.nomadics9.ananas.viewmodels.LoginViewModel
|
|
||||||
import io.noties.markwon.Markwon
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class LoginFragment : Fragment() {
|
class LoginFragment : Fragment() {
|
||||||
|
@ -82,17 +78,6 @@ class LoginFragment : Fragment() {
|
||||||
(binding.editTextPassword as AppCompatEditText).requestFocus()
|
(binding.editTextPassword as AppCompatEditText).requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (BuildConfig.FLAVOR == "Ananas") {
|
|
||||||
binding.buttonForgetPassword.setOnClickListener {
|
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.FORGET_PASSWORD_ADDRESS))
|
|
||||||
startActivity(browserIntent)
|
|
||||||
}
|
|
||||||
binding.buttonForgetPassword.isVisible = true
|
|
||||||
} else {
|
|
||||||
binding.buttonForgetPassword.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
viewModel.uiState.collect { uiState ->
|
viewModel.uiState.collect { uiState ->
|
||||||
|
@ -158,21 +143,7 @@ class LoginFragment : Fragment() {
|
||||||
binding.editTextPasswordLayout.isEnabled = true
|
binding.editTextPasswordLayout.isEnabled = true
|
||||||
|
|
||||||
uiState.disclaimer?.let { disclaimer ->
|
uiState.disclaimer?.let { disclaimer ->
|
||||||
if (BuildConfig.FLAVOR == "Ananas") {
|
binding.loginDisclaimer.text = fromHtml(disclaimer, 0)
|
||||||
val lines = disclaimer.lines()
|
|
||||||
val lineToRemoveIndex = 3
|
|
||||||
val filteredLines = lines.toMutableList().apply {
|
|
||||||
if (size > lineToRemoveIndex) {
|
|
||||||
removeAt(lineToRemoveIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val filteredDisclaimer = filteredLines.joinToString("\n")
|
|
||||||
val markwon = Markwon.create(requireContext())
|
|
||||||
markwon.setMarkdown(binding.loginDisclaimer, filteredDisclaimer)
|
|
||||||
} else {
|
|
||||||
val markwon = Markwon.create(requireContext())
|
|
||||||
markwon.setMarkdown(binding.loginDisclaimer, disclaimer)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -19,15 +19,15 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.CollectionListAdapter
|
import dev.jdtech.jellyfin.adapters.CollectionListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentMediaBinding
|
import dev.jdtech.jellyfin.databinding.FragmentMediaBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidCollection
|
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.viewmodels.MediaViewModel
|
import dev.jdtech.jellyfin.viewmodels.MediaViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MediaFragment : Fragment() {
|
class MediaFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
@ -21,32 +21,32 @@ import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.R
|
import dev.jdtech.jellyfin.R
|
||||||
import com.nomadics9.ananas.adapters.PersonListAdapter
|
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
||||||
import com.nomadics9.ananas.bindItemBackdropImage
|
import dev.jdtech.jellyfin.bindItemBackdropImage
|
||||||
import com.nomadics9.ananas.databinding.FragmentMovieBinding
|
import dev.jdtech.jellyfin.databinding.FragmentMovieBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.dialogs.getStorageSelectionDialog
|
import dev.jdtech.jellyfin.dialogs.getStorageSelectionDialog
|
||||||
import com.nomadics9.ananas.dialogs.getVideoVersionDialog
|
import dev.jdtech.jellyfin.dialogs.getVideoVersionDialog
|
||||||
import com.nomadics9.ananas.models.AudioCodec
|
import dev.jdtech.jellyfin.models.AudioCodec
|
||||||
import com.nomadics9.ananas.models.DisplayProfile
|
import dev.jdtech.jellyfin.models.DisplayProfile
|
||||||
import com.nomadics9.ananas.models.FindroidSourceType
|
import dev.jdtech.jellyfin.models.FindroidSourceType
|
||||||
import com.nomadics9.ananas.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import com.nomadics9.ananas.models.UiText
|
import dev.jdtech.jellyfin.models.UiText
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.models.isDownloading
|
import dev.jdtech.jellyfin.models.isDownloading
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.utils.setIconTintColorAttribute
|
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
|
||||||
import com.nomadics9.ananas.viewmodels.MovieEvent
|
import dev.jdtech.jellyfin.viewmodels.MovieEvent
|
||||||
import com.nomadics9.ananas.viewmodels.MovieViewModel
|
import dev.jdtech.jellyfin.viewmodels.MovieViewModel
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MovieFragment : Fragment() {
|
class MovieFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -15,18 +15,18 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.ViewItemListAdapter
|
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||||
import com.nomadics9.ananas.bindItemImage
|
import dev.jdtech.jellyfin.bindItemImage
|
||||||
import com.nomadics9.ananas.databinding.FragmentPersonDetailBinding
|
import dev.jdtech.jellyfin.databinding.FragmentPersonDetailBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.viewmodels.PersonDetailViewModel
|
import dev.jdtech.jellyfin.viewmodels.PersonDetailViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
internal class PersonDetailFragment : Fragment() {
|
internal class PersonDetailFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -13,15 +13,15 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentSearchResultBinding
|
import dev.jdtech.jellyfin.databinding.FragmentSearchResultBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.viewmodels.SearchResultViewModel
|
import dev.jdtech.jellyfin.viewmodels.SearchResultViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.navigation.fragment.navArgs
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import dev.jdtech.jellyfin.adapters.EpisodeListAdapter
|
||||||
|
import dev.jdtech.jellyfin.databinding.FragmentSeasonBinding
|
||||||
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
|
import dev.jdtech.jellyfin.viewmodels.SeasonEvent
|
||||||
|
import dev.jdtech.jellyfin.viewmodels.SeasonViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class SeasonFragment : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentSeasonBinding
|
||||||
|
private val viewModel: SeasonViewModel by viewModels()
|
||||||
|
private val args: SeasonFragmentArgs by navArgs()
|
||||||
|
|
||||||
|
private lateinit var errorDialog: ErrorDialogFragment
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?,
|
||||||
|
): View {
|
||||||
|
binding = FragmentSeasonBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
launch {
|
||||||
|
viewModel.uiState.collect { uiState ->
|
||||||
|
Timber.d("$uiState")
|
||||||
|
when (uiState) {
|
||||||
|
is SeasonViewModel.UiState.Normal -> bindUiStateNormal(uiState)
|
||||||
|
is SeasonViewModel.UiState.Loading -> bindUiStateLoading()
|
||||||
|
is SeasonViewModel.UiState.Error -> bindUiStateError(uiState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
launch {
|
||||||
|
viewModel.eventsChannelFlow.collect { event ->
|
||||||
|
when (event) {
|
||||||
|
is SeasonEvent.NavigateBack -> findNavController().navigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.errorLayout.errorRetryButton.setOnClickListener {
|
||||||
|
viewModel.loadEpisodes(args.seriesId, args.seasonId, args.offline)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.errorLayout.errorDetailsButton.setOnClickListener {
|
||||||
|
errorDialog.show(parentFragmentManager, ErrorDialogFragment.TAG)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.episodesRecyclerView.adapter =
|
||||||
|
EpisodeListAdapter { episode ->
|
||||||
|
navigateToEpisodeBottomSheetFragment(episode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
viewModel.loadEpisodes(args.seriesId, args.seasonId, args.offline)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindUiStateNormal(uiState: SeasonViewModel.UiState.Normal) {
|
||||||
|
uiState.apply {
|
||||||
|
val adapter = binding.episodesRecyclerView.adapter as EpisodeListAdapter
|
||||||
|
adapter.submitList(uiState.episodes)
|
||||||
|
}
|
||||||
|
binding.loadingIndicator.isVisible = false
|
||||||
|
binding.episodesRecyclerView.isVisible = true
|
||||||
|
binding.errorLayout.errorPanel.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindUiStateLoading() {
|
||||||
|
binding.loadingIndicator.isVisible = true
|
||||||
|
binding.errorLayout.errorPanel.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindUiStateError(uiState: SeasonViewModel.UiState.Error) {
|
||||||
|
errorDialog = ErrorDialogFragment.newInstance(uiState.error)
|
||||||
|
binding.loadingIndicator.isVisible = false
|
||||||
|
binding.episodesRecyclerView.isVisible = false
|
||||||
|
binding.errorLayout.errorPanel.isVisible = true
|
||||||
|
checkIfLoginRequired(uiState.error.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun navigateToEpisodeBottomSheetFragment(episode: FindroidEpisode) {
|
||||||
|
findNavController().navigate(
|
||||||
|
SeasonFragmentDirections.actionSeasonFragmentToEpisodeBottomSheetFragment(
|
||||||
|
episode.id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -12,12 +12,12 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.ServerAddressAdapter
|
import dev.jdtech.jellyfin.adapters.ServerAddressAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentServerAddressesBinding
|
import dev.jdtech.jellyfin.databinding.FragmentServerAddressesBinding
|
||||||
import com.nomadics9.ananas.dialogs.AddServerAddressDialog
|
import dev.jdtech.jellyfin.dialogs.AddServerAddressDialog
|
||||||
import com.nomadics9.ananas.dialogs.DeleteServerAddressDialog
|
import dev.jdtech.jellyfin.dialogs.DeleteServerAddressDialog
|
||||||
import com.nomadics9.ananas.viewmodels.ServerAddressesEvent
|
import dev.jdtech.jellyfin.viewmodels.ServerAddressesEvent
|
||||||
import com.nomadics9.ananas.viewmodels.ServerAddressesViewModel
|
import dev.jdtech.jellyfin.viewmodels.ServerAddressesViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -11,11 +11,11 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.adapters.ServerGridAdapter
|
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentServerSelectBinding
|
import dev.jdtech.jellyfin.databinding.FragmentServerSelectBinding
|
||||||
import com.nomadics9.ananas.dialogs.DeleteServerDialogFragment
|
import dev.jdtech.jellyfin.dialogs.DeleteServerDialogFragment
|
||||||
import com.nomadics9.ananas.viewmodels.ServerSelectEvent
|
import dev.jdtech.jellyfin.viewmodels.ServerSelectEvent
|
||||||
import com.nomadics9.ananas.viewmodels.ServerSelectViewModel
|
import dev.jdtech.jellyfin.viewmodels.ServerSelectViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.SwitchPreferenceCompat
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class SettingsAppearanceFragment : PreferenceFragmentCompat() {
|
class SettingsAppearanceFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
@ -1,10 +1,10 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class SettingsCacheFragment : PreferenceFragmentCompat() {
|
class SettingsCacheFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
@ -1,12 +1,12 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.viewmodels.SettingsDeviceViewModel
|
import dev.jdtech.jellyfin.viewmodels.SettingsDeviceViewModel
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SettingsDeviceFragment : PreferenceFragmentCompat() {
|
class SettingsDeviceFragment : PreferenceFragmentCompat() {
|
|
@ -1,8 +1,8 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class SettingsDownloadsFragment : PreferenceFragmentCompat() {
|
class SettingsDownloadsFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
@ -0,0 +1,59 @@
|
||||||
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
|
import dev.jdtech.jellyfin.utils.restart
|
||||||
|
import javax.inject.Inject
|
||||||
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
@Inject
|
||||||
|
lateinit var appPreferences: AppPreferences
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
setPreferencesFromResource(CoreR.xml.fragment_settings, rootKey)
|
||||||
|
|
||||||
|
findPreference<Preference>("switchServer")?.setOnPreferenceClickListener {
|
||||||
|
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionNavigationSettingsToServerSelectFragment())
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>("switchUser")?.setOnPreferenceClickListener {
|
||||||
|
val serverId = appPreferences.currentServer!!
|
||||||
|
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionNavigationSettingsToUsersFragment(serverId))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>("switchAddress")?.setOnPreferenceClickListener {
|
||||||
|
val serverId = appPreferences.currentServer!!
|
||||||
|
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionNavigationSettingsToServerAddressesFragment(serverId))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>("pref_offline_mode")?.setOnPreferenceClickListener {
|
||||||
|
activity?.restart()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>("privacyPolicy")?.setOnPreferenceClickListener {
|
||||||
|
val intent = Intent(
|
||||||
|
Intent.ACTION_VIEW,
|
||||||
|
Uri.parse("https://github.com/jarnedemeulemeester/findroid/blob/main/PRIVACY"),
|
||||||
|
)
|
||||||
|
startActivity(intent)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>("appInfo")?.setOnPreferenceClickListener {
|
||||||
|
findNavController().navigate(TwoPaneSettingsFragmentDirections.actionSettingsFragmentToAboutLibraries())
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -7,7 +7,7 @@ import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class SettingsLanguageFragment : PreferenceFragmentCompat() {
|
class SettingsLanguageFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
@ -1,11 +1,11 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.nomadics9.ananas.Constants
|
import dev.jdtech.jellyfin.Constants
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class SettingsNetworkFragment : PreferenceFragmentCompat() {
|
class SettingsNetworkFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -7,7 +7,7 @@ import android.text.InputType
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
class SettingsPlayerFragment : PreferenceFragmentCompat() {
|
class SettingsPlayerFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -18,29 +18,29 @@ import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import com.google.android.material.R
|
import com.google.android.material.R
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.adapters.PersonListAdapter
|
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
||||||
import com.nomadics9.ananas.adapters.ViewItemListAdapter
|
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||||
import com.nomadics9.ananas.bindCardItemImage
|
import dev.jdtech.jellyfin.bindCardItemImage
|
||||||
import com.nomadics9.ananas.bindItemBackdropImage
|
import dev.jdtech.jellyfin.bindItemBackdropImage
|
||||||
import com.nomadics9.ananas.databinding.FragmentShowBinding
|
import dev.jdtech.jellyfin.databinding.FragmentShowBinding
|
||||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidSeason
|
import dev.jdtech.jellyfin.models.FindroidSeason
|
||||||
import com.nomadics9.ananas.models.FindroidSourceType
|
import dev.jdtech.jellyfin.models.FindroidSourceType
|
||||||
import com.nomadics9.ananas.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import com.nomadics9.ananas.models.isDownloaded
|
import dev.jdtech.jellyfin.models.isDownloaded
|
||||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||||
import com.nomadics9.ananas.utils.setIconTintColorAttribute
|
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||||
import com.nomadics9.ananas.viewmodels.ShowEvent
|
import dev.jdtech.jellyfin.viewmodels.ShowEvent
|
||||||
import com.nomadics9.ananas.viewmodels.ShowViewModel
|
import dev.jdtech.jellyfin.viewmodels.ShowViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ShowFragment : Fragment() {
|
class ShowFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.PreferenceHeaderFragmentCompat
|
import androidx.preference.PreferenceHeaderFragmentCompat
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.fragments
|
package dev.jdtech.jellyfin.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -12,12 +12,12 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.AppNavigationDirections
|
import dev.jdtech.jellyfin.AppNavigationDirections
|
||||||
import com.nomadics9.ananas.adapters.UserListAdapter
|
import dev.jdtech.jellyfin.adapters.UserListAdapter
|
||||||
import com.nomadics9.ananas.databinding.FragmentUsersBinding
|
import dev.jdtech.jellyfin.databinding.FragmentUsersBinding
|
||||||
import com.nomadics9.ananas.dialogs.DeleteUserDialogFragment
|
import dev.jdtech.jellyfin.dialogs.DeleteUserDialogFragment
|
||||||
import com.nomadics9.ananas.viewmodels.UsersEvent
|
import dev.jdtech.jellyfin.viewmodels.UsersEvent
|
||||||
import com.nomadics9.ananas.viewmodels.UsersViewModel
|
import dev.jdtech.jellyfin.viewmodels.UsersViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.nomadics9.ananas.utils
|
package dev.jdtech.jellyfin.utils
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.nomadics9.ananas.AppNavigationDirections
|
import dev.jdtech.jellyfin.AppNavigationDirections
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
fun Fragment.checkIfLoginRequired(error: String?) {
|
fun Fragment.checkIfLoginRequired(error: String?) {
|
|
@ -1,8 +1,7 @@
|
||||||
package com.nomadics9.ananas.utils
|
package dev.jdtech.jellyfin.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
|
@ -20,20 +19,15 @@ import android.view.animation.DecelerateInterpolator
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.media3.ui.AspectRatioFrameLayout
|
import androidx.media3.ui.AspectRatioFrameLayout
|
||||||
import androidx.media3.ui.PlayerView
|
import androidx.media3.ui.PlayerView
|
||||||
import coil.transform.RoundedCornersTransformation
|
import dev.jdtech.jellyfin.AppPreferences
|
||||||
import com.nomadics9.ananas.AppPreferences
|
import dev.jdtech.jellyfin.Constants
|
||||||
import com.nomadics9.ananas.Constants
|
import dev.jdtech.jellyfin.PlayerActivity
|
||||||
import com.nomadics9.ananas.PlayerActivity
|
import dev.jdtech.jellyfin.isControlsLocked
|
||||||
import com.nomadics9.ananas.isControlsLocked
|
import dev.jdtech.jellyfin.models.PlayerChapter
|
||||||
import com.nomadics9.ananas.models.PlayerChapter
|
import dev.jdtech.jellyfin.mpv.MPVPlayer
|
||||||
import com.nomadics9.ananas.models.Trickplay
|
|
||||||
import com.nomadics9.ananas.mpv.MPVPlayer
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import coil.load
|
|
||||||
|
|
||||||
class PlayerGestureHelper(
|
class PlayerGestureHelper(
|
||||||
private val appPreferences: AppPreferences,
|
private val appPreferences: AppPreferences,
|
||||||
private val activity: PlayerActivity,
|
private val activity: PlayerActivity,
|
||||||
|
@ -68,10 +62,6 @@ class PlayerGestureHelper(
|
||||||
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||||
private val screenHeight = Resources.getSystem().displayMetrics.heightPixels
|
private val screenHeight = Resources.getSystem().displayMetrics.heightPixels
|
||||||
|
|
||||||
var currentTrickplay: Trickplay? = null
|
|
||||||
private val roundedCorners = RoundedCornersTransformation(10f)
|
|
||||||
private var currentBitMap: Bitmap? = null
|
|
||||||
|
|
||||||
private var currentNumberOfPointers: Int = 0
|
private var currentNumberOfPointers: Int = 0
|
||||||
|
|
||||||
private val tapGestureDetector = GestureDetector(
|
private val tapGestureDetector = GestureDetector(
|
||||||
|
@ -275,13 +265,6 @@ class PlayerGestureHelper(
|
||||||
activity.binding.progressScrubberLayout.visibility = View.VISIBLE
|
activity.binding.progressScrubberLayout.visibility = View.VISIBLE
|
||||||
activity.binding.progressScrubberText.text = "${longToTimestamp(difference)} [${longToTimestamp(newPos, true)}]"
|
activity.binding.progressScrubberText.text = "${longToTimestamp(difference)} [${longToTimestamp(newPos, true)}]"
|
||||||
swipeGestureValueTrackerProgress = newPos
|
swipeGestureValueTrackerProgress = newPos
|
||||||
|
|
||||||
if (currentTrickplay != null) {
|
|
||||||
onMove(newPos)
|
|
||||||
} else {
|
|
||||||
activity.binding.imagePreviewGesture.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
swipeGestureProgressOpen = true
|
swipeGestureProgressOpen = true
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -488,28 +471,11 @@ class PlayerGestureHelper(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onMove(position: Long) {
|
|
||||||
val trickplay = currentTrickplay ?: return
|
|
||||||
val image = trickplay.images[position.div(trickplay.interval).toInt()]
|
|
||||||
|
|
||||||
if (currentBitMap != image) {
|
|
||||||
activity.binding.imagePreviewGesture.load(image) {
|
|
||||||
dispatcher(Dispatchers.Main.immediate)
|
|
||||||
transformations(roundedCorners)
|
|
||||||
}
|
|
||||||
currentBitMap = image
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (appPreferences.playerBrightnessRemember) {
|
if (appPreferences.playerBrightnessRemember) {
|
||||||
activity.window.attributes.screenBrightness = appPreferences.playerBrightness
|
activity.window.attributes.screenBrightness = appPreferences.playerBrightness
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!appPreferences.playerTrickPlayGesture) {
|
|
||||||
activity.binding.imagePreviewGesture.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
updateZoomMode(appPreferences.playerStartMaximized)
|
updateZoomMode(appPreferences.playerStartMaximized)
|
||||||
|
|
||||||
@Suppress("ClickableViewAccessibility")
|
@Suppress("ClickableViewAccessibility")
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.utils
|
package dev.jdtech.jellyfin.utils
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -8,7 +8,7 @@ import androidx.media3.common.Player
|
||||||
import androidx.media3.ui.TimeBar
|
import androidx.media3.ui.TimeBar
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
import com.nomadics9.ananas.models.Trickplay
|
import dev.jdtech.jellyfin.models.Trickplay
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
|
@ -37,16 +37,7 @@
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/main_toolbar"
|
android:id="@+id/main_toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize">
|
android:layout_height="?attr/actionBarSize" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="65dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:contentDescription="@string/app_name"
|
|
||||||
android:src="@drawable/ic_launcher_foreground" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.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"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
@ -40,17 +39,8 @@
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/main_toolbar"
|
android:id="@+id/main_toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize">
|
android:layout_height="?attr/actionBarSize" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="65dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:contentDescription="@string/app_name"
|
|
||||||
android:src="@drawable/ic_launcher_foreground" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -16,11 +16,8 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/progress_scrubber_layout"
|
android:id="@+id/progress_scrubber_layout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginTop="64dp"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:background="@drawable/overlay_background"
|
android:background="@drawable/overlay_background"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
@ -28,20 +25,10 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/image_preview_gesture"
|
|
||||||
android:layout_width="272dp"
|
|
||||||
android:layout_height="153dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginBottom="10dp"
|
|
||||||
|
|
||||||
android:contentDescription="@string/player_trickplay" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/progress_scrubber_text"
|
android:id="@+id/progress_scrubber_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
|
||||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
tools:text="+00:00:10 [00:00:20]" />
|
tools:text="+00:00:10 [00:00:20]" />
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center">
|
android:layout_gravity="center">
|
||||||
|
|
||||||
|
|
||||||
<!-- Video surface will be inserted as the first child of the content frame. -->
|
<!-- Video surface will be inserted as the first child of the content frame. -->
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
@ -49,6 +48,24 @@
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_skip_intro"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|bottom"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginBottom="64dp"
|
||||||
|
android:text="@string/player_controls_skip_intro"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:backgroundTint="@color/player_background"
|
||||||
|
app:icon="@drawable/ic_skip_forward"
|
||||||
|
app:iconGravity="end"
|
||||||
|
app:iconTint="@android:color/white"
|
||||||
|
app:strokeColor="@android:color/white"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</androidx.media3.ui.AspectRatioFrameLayout>
|
</androidx.media3.ui.AspectRatioFrameLayout>
|
||||||
|
|
||||||
<androidx.media3.ui.SubtitleView
|
<androidx.media3.ui.SubtitleView
|
||||||
|
@ -72,33 +89,4 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:animation_enabled="false"/>
|
app:animation_enabled="false"/>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_gravity="end|bottom"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:layout_marginBottom="64dp">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btn_watch_credits"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:text="@string/watch_credits"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btn_skip_intro"
|
|
||||||
style="@style/Widget.Material3.Button.Icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:icon="@drawable/ic_skip_forward"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</merge>
|
</merge>
|
|
@ -141,24 +141,10 @@
|
||||||
android:visibility="invisible" />
|
android:visibility="invisible" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="24dp">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_forget_password"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/forget_password" />
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/login_disclaimer"
|
android:id="@+id/login_disclaimer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
|
||||||
android:layout_marginHorizontal="24dp"
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_margin="24dp"
|
android:layout_margin="24dp"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<WebView
|
|
||||||
android:id="@+id/webview"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progressBar"
|
|
||||||
style="?android:attr/progressBarStyleLarge"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true" />
|
|
||||||
</RelativeLayout>
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/homeFragment"
|
android:id="@+id/homeFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.HomeFragment"
|
android:name="dev.jdtech.jellyfin.fragments.HomeFragment"
|
||||||
android:label="@string/title_home"
|
android:label="@string/title_home"
|
||||||
tools:layout="@layout/fragment_home">
|
tools:layout="@layout/fragment_home">
|
||||||
<action
|
<action
|
||||||
|
@ -49,14 +49,11 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_homeFragment_to_searchResultFragment"
|
android:id="@+id/action_homeFragment_to_searchResultFragment"
|
||||||
app:destination="@id/searchResultFragment" />
|
app:destination="@id/searchResultFragment" />
|
||||||
<action
|
|
||||||
android:id="@+id/action_homeFragment_to_requestsWebFragment"
|
|
||||||
app:destination="@id/requestsWebFragment" />
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/mediaFragment"
|
android:id="@+id/mediaFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.MediaFragment"
|
android:name="dev.jdtech.jellyfin.fragments.MediaFragment"
|
||||||
android:label="@string/title_media"
|
android:label="@string/title_media"
|
||||||
tools:layout="@layout/fragment_media">
|
tools:layout="@layout/fragment_media">
|
||||||
<action
|
<action
|
||||||
|
@ -73,7 +70,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/twoPaneSettingsFragment"
|
android:id="@+id/twoPaneSettingsFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.TwoPaneSettingsFragment"
|
android:name="dev.jdtech.jellyfin.fragments.TwoPaneSettingsFragment"
|
||||||
android:label="@string/title_settings">
|
android:label="@string/title_settings">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_navigation_settings_to_serverSelectFragment"
|
android:id="@+id/action_navigation_settings_to_serverSelectFragment"
|
||||||
|
@ -87,23 +84,13 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_settingsFragment_to_about_libraries"
|
android:id="@+id/action_settingsFragment_to_about_libraries"
|
||||||
app:destination="@id/about_libraries" />
|
app:destination="@id/about_libraries" />
|
||||||
<action
|
|
||||||
android:id="@+id/action_navigation_settings_to_requestsWebFragment"
|
|
||||||
app:destination="@id/requestsWebFragment" />
|
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/settingsFragment"
|
android:id="@+id/settingsFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.SettingsFragment">
|
android:name="dev.jdtech.jellyfin.fragments.SettingsFragment" />
|
||||||
</fragment>
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/requestsWebFragment"
|
|
||||||
android:name="com.nomadics9.ananas.fragments.RequestsWebViewFragment"
|
|
||||||
android:label="Requests"
|
|
||||||
tools:layout="@layout/fragment_webview">
|
|
||||||
</fragment>
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/libraryFragment"
|
android:id="@+id/libraryFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.LibraryFragment"
|
android:name="dev.jdtech.jellyfin.fragments.LibraryFragment"
|
||||||
android:label="{libraryName}"
|
android:label="{libraryName}"
|
||||||
tools:layout="@layout/fragment_library">
|
tools:layout="@layout/fragment_library">
|
||||||
<argument
|
<argument
|
||||||
|
@ -135,14 +122,14 @@
|
||||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||||
<argument
|
<argument
|
||||||
android:name="libraryType"
|
android:name="libraryType"
|
||||||
app:argType="com.nomadics9.ananas.models.CollectionType" />
|
app:argType="dev.jdtech.jellyfin.models.CollectionType" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_libraryFragment_self"
|
android:id="@+id/action_libraryFragment_self"
|
||||||
app:destination="@id/libraryFragment" />
|
app:destination="@id/libraryFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/showFragment"
|
android:id="@+id/showFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.ShowFragment"
|
android:name="dev.jdtech.jellyfin.fragments.ShowFragment"
|
||||||
android:label="{itemName}"
|
android:label="{itemName}"
|
||||||
tools:layout="@layout/fragment_show">
|
tools:layout="@layout/fragment_show">
|
||||||
<argument
|
<argument
|
||||||
|
@ -171,7 +158,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/movieFragment"
|
android:id="@+id/movieFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.MovieFragment"
|
android:name="dev.jdtech.jellyfin.fragments.MovieFragment"
|
||||||
android:label="{itemName}"
|
android:label="{itemName}"
|
||||||
tools:layout="@layout/fragment_movie">
|
tools:layout="@layout/fragment_movie">
|
||||||
<argument
|
<argument
|
||||||
|
@ -192,7 +179,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/seasonFragment"
|
android:id="@+id/seasonFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.SeasonFragment"
|
android:name="dev.jdtech.jellyfin.fragments.SeasonFragment"
|
||||||
android:label="{seasonName}"
|
android:label="{seasonName}"
|
||||||
tools:layout="@layout/fragment_season">
|
tools:layout="@layout/fragment_season">
|
||||||
<argument
|
<argument
|
||||||
|
@ -224,7 +211,7 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/episodeBottomSheetFragment"
|
android:id="@+id/episodeBottomSheetFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.EpisodeBottomSheetFragment"
|
android:name="dev.jdtech.jellyfin.fragments.EpisodeBottomSheetFragment"
|
||||||
android:label="EpisodeBottomSheetFragment"
|
android:label="EpisodeBottomSheetFragment"
|
||||||
tools:layout="@layout/episode_bottom_sheet">
|
tools:layout="@layout/episode_bottom_sheet">
|
||||||
<argument
|
<argument
|
||||||
|
@ -239,7 +226,7 @@
|
||||||
</dialog>
|
</dialog>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/favoriteFragment"
|
android:id="@+id/favoriteFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.FavoriteFragment"
|
android:name="dev.jdtech.jellyfin.fragments.FavoriteFragment"
|
||||||
android:label="@string/title_favorite"
|
android:label="@string/title_favorite"
|
||||||
tools:layout="@layout/fragment_favorite">
|
tools:layout="@layout/fragment_favorite">
|
||||||
<action
|
<action
|
||||||
|
@ -254,7 +241,7 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/collectionFragment"
|
android:id="@+id/collectionFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.CollectionFragment"
|
android:name="dev.jdtech.jellyfin.fragments.CollectionFragment"
|
||||||
android:label="{collectionName}"
|
android:label="{collectionName}"
|
||||||
tools:layout="@layout/fragment_favorite">
|
tools:layout="@layout/fragment_favorite">
|
||||||
<argument
|
<argument
|
||||||
|
@ -277,7 +264,7 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/searchResultFragment"
|
android:id="@+id/searchResultFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.SearchResultFragment"
|
android:name="dev.jdtech.jellyfin.fragments.SearchResultFragment"
|
||||||
android:label="{query}"
|
android:label="{query}"
|
||||||
tools:layout="@layout/fragment_search_result">
|
tools:layout="@layout/fragment_search_result">
|
||||||
<action
|
<action
|
||||||
|
@ -295,7 +282,7 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/addServerFragment"
|
android:id="@+id/addServerFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.AddServerFragment"
|
android:name="dev.jdtech.jellyfin.fragments.AddServerFragment"
|
||||||
android:label="@string/add_server"
|
android:label="@string/add_server"
|
||||||
tools:layout="@layout/fragment_add_server">
|
tools:layout="@layout/fragment_add_server">
|
||||||
<action
|
<action
|
||||||
|
@ -304,7 +291,7 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/serverSelectFragment"
|
android:id="@+id/serverSelectFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.ServerSelectFragment"
|
android:name="dev.jdtech.jellyfin.fragments.ServerSelectFragment"
|
||||||
android:label="@string/select_server"
|
android:label="@string/select_server"
|
||||||
tools:layout="@layout/fragment_server_select">
|
tools:layout="@layout/fragment_server_select">
|
||||||
<action
|
<action
|
||||||
|
@ -321,7 +308,7 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/loginFragment"
|
android:id="@+id/loginFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.LoginFragment"
|
android:name="dev.jdtech.jellyfin.fragments.LoginFragment"
|
||||||
android:label="@string/login"
|
android:label="@string/login"
|
||||||
tools:layout="@layout/fragment_login">
|
tools:layout="@layout/fragment_login">
|
||||||
<action
|
<action
|
||||||
|
@ -337,7 +324,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/personDetailFragment"
|
android:id="@+id/personDetailFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.PersonDetailFragment"
|
android:name="dev.jdtech.jellyfin.fragments.PersonDetailFragment"
|
||||||
android:label="@string/person_detail_title"
|
android:label="@string/person_detail_title"
|
||||||
tools:layout="@layout/fragment_person_detail">
|
tools:layout="@layout/fragment_person_detail">
|
||||||
|
|
||||||
|
@ -355,12 +342,12 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:id="@+id/playerActivity"
|
android:id="@+id/playerActivity"
|
||||||
android:name="com.nomadics9.ananas.PlayerActivity"
|
android:name="dev.jdtech.jellyfin.PlayerActivity"
|
||||||
android:label="activity_player"
|
android:label="activity_player"
|
||||||
tools:layout="@layout/activity_player">
|
tools:layout="@layout/activity_player">
|
||||||
<argument
|
<argument
|
||||||
android:name="items"
|
android:name="items"
|
||||||
app:argType="com.nomadics9.ananas.models.PlayerItem[]" />
|
app:argType="dev.jdtech.jellyfin.models.PlayerItem[]" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<include app:graph="@navigation/aboutlibs_navigation" />
|
<include app:graph="@navigation/aboutlibs_navigation" />
|
||||||
|
@ -370,7 +357,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/usersFragment"
|
android:id="@+id/usersFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.UsersFragment"
|
android:name="dev.jdtech.jellyfin.fragments.UsersFragment"
|
||||||
android:label="@string/users"
|
android:label="@string/users"
|
||||||
tools:layout="@layout/fragment_users">
|
tools:layout="@layout/fragment_users">
|
||||||
<action
|
<action
|
||||||
|
@ -388,7 +375,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/serverAddressesFragment"
|
android:id="@+id/serverAddressesFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.ServerAddressesFragment"
|
android:name="dev.jdtech.jellyfin.fragments.ServerAddressesFragment"
|
||||||
android:label="@string/addresses"
|
android:label="@string/addresses"
|
||||||
tools:layout="@layout/fragment_server_addresses">
|
tools:layout="@layout/fragment_server_addresses">
|
||||||
<action
|
<action
|
||||||
|
@ -403,7 +390,7 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/downloadsFragment"
|
android:id="@+id/downloadsFragment"
|
||||||
android:name="com.nomadics9.ananas.fragments.DownloadsFragment"
|
android:name="dev.jdtech.jellyfin.fragments.DownloadsFragment"
|
||||||
android:label="@string/title_download"
|
android:label="@string/title_download"
|
||||||
tools:layout="@layout/fragment_favorite">
|
tools:layout="@layout/fragment_favorite">
|
||||||
<action
|
<action
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="watch_credits">Watch credits</string>
|
|
||||||
</resources>
|
|
|
@ -9,12 +9,12 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.nomadics9.ananas"
|
namespace = "dev.jdtech.jellyfin"
|
||||||
compileSdk = Versions.compileSdk
|
compileSdk = Versions.compileSdk
|
||||||
buildToolsVersion = Versions.buildTools
|
buildToolsVersion = Versions.buildTools
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.nomadics9.ananas"
|
applicationId = "dev.jdtech.jellyfin"
|
||||||
minSdk = Versions.minSdk
|
minSdk = Versions.minSdk
|
||||||
targetSdk = Versions.targetSdk
|
targetSdk = Versions.targetSdk
|
||||||
|
|
||||||
|
@ -81,15 +81,14 @@ ktlint {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
val composeBom = platform(libs.androidx.compose.bom)
|
|
||||||
|
|
||||||
implementation(projects.core)
|
implementation(projects.core)
|
||||||
implementation(projects.data)
|
implementation(projects.data)
|
||||||
implementation(projects.preferences)
|
implementation(projects.preferences)
|
||||||
implementation(projects.player.core)
|
implementation(projects.player.core)
|
||||||
implementation(projects.player.video)
|
implementation(projects.player.video)
|
||||||
implementation(libs.androidx.activity.compose)
|
implementation(libs.androidx.activity.compose)
|
||||||
implementation(composeBom)
|
implementation(libs.androidx.compose.foundation)
|
||||||
|
implementation(libs.androidx.compose.runtime)
|
||||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||||
implementation(libs.androidx.compose.material3)
|
implementation(libs.androidx.compose.material3)
|
||||||
implementation(libs.androidx.core)
|
implementation(libs.androidx.core)
|
||||||
|
@ -99,7 +98,6 @@ dependencies {
|
||||||
implementation(libs.androidx.media3.ui)
|
implementation(libs.androidx.media3.ui)
|
||||||
implementation(libs.androidx.media3.session)
|
implementation(libs.androidx.media3.session)
|
||||||
implementation(libs.androidx.paging.compose)
|
implementation(libs.androidx.paging.compose)
|
||||||
implementation(libs.androidx.tv.foundation)
|
|
||||||
implementation(libs.androidx.tv.material)
|
implementation(libs.androidx.tv.material)
|
||||||
implementation(libs.coil.compose)
|
implementation(libs.coil.compose)
|
||||||
implementation(libs.coil.svg)
|
implementation(libs.coil.svg)
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.nomadics9.ananas.debug",
|
|
||||||
"variantName": "libreDebug",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "armeabi-v7a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-armeabi-v7a-debug.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86_64"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-x86_64-debug.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "arm64-v8a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-arm64-v8a-debug.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-x86-debug.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File",
|
|
||||||
"minSdkVersionForDexing": 28
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,87 +0,0 @@
|
||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.nomadics9.ananas",
|
|
||||||
"variantName": "libreRelease",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "armeabi-v7a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-armeabi-v7a-release.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-x86-release.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "arm64-v8a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-arm64-v8a-release.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86_64"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 6,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-x86_64-release.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File",
|
|
||||||
"baselineProfiles": [
|
|
||||||
{
|
|
||||||
"minApi": 28,
|
|
||||||
"maxApi": 30,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/1/tv-libre-armeabi-v7a-release.dm",
|
|
||||||
"baselineProfiles/1/tv-libre-x86-release.dm",
|
|
||||||
"baselineProfiles/1/tv-libre-arm64-v8a-release.dm",
|
|
||||||
"baselineProfiles/1/tv-libre-x86_64-release.dm"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minApi": 31,
|
|
||||||
"maxApi": 2147483647,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/0/tv-libre-armeabi-v7a-release.dm",
|
|
||||||
"baselineProfiles/0/tv-libre-x86-release.dm",
|
|
||||||
"baselineProfiles/0/tv-libre-arm64-v8a-release.dm",
|
|
||||||
"baselineProfiles/0/tv-libre-x86_64-release.dm"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minSdkVersionForDexing": 28
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,87 +0,0 @@
|
||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.nomadics9.ananas.staging",
|
|
||||||
"variantName": "libreStaging",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "armeabi-v7a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 1,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-armeabi-v7a-staging.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86_64"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 1,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-x86_64-staging.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "x86"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 1,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-x86-staging.apk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ONE_OF_MANY",
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"filterType": "ABI",
|
|
||||||
"value": "arm64-v8a"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 1,
|
|
||||||
"versionName": "0.14.2",
|
|
||||||
"outputFile": "tv-libre-arm64-v8a-staging.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File",
|
|
||||||
"baselineProfiles": [
|
|
||||||
{
|
|
||||||
"minApi": 28,
|
|
||||||
"maxApi": 30,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/1/tv-libre-armeabi-v7a-staging.dm",
|
|
||||||
"baselineProfiles/1/tv-libre-x86_64-staging.dm",
|
|
||||||
"baselineProfiles/1/tv-libre-x86-staging.dm",
|
|
||||||
"baselineProfiles/1/tv-libre-arm64-v8a-staging.dm"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minApi": 31,
|
|
||||||
"maxApi": 2147483647,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/0/tv-libre-armeabi-v7a-staging.dm",
|
|
||||||
"baselineProfiles/0/tv-libre-x86_64-staging.dm",
|
|
||||||
"baselineProfiles/0/tv-libre-x86-staging.dm",
|
|
||||||
"baselineProfiles/0/tv-libre-arm64-v8a-staging.dm"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minSdkVersionForDexing": 28
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
@ -6,11 +6,11 @@ import androidx.activity.compose.setContent
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import com.ramcosta.composedestinations.DestinationsNavHost
|
import com.ramcosta.composedestinations.DestinationsNavHost
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||||
import com.nomadics9.ananas.destinations.AddServerScreenDestination
|
import dev.jdtech.jellyfin.destinations.AddServerScreenDestination
|
||||||
import com.nomadics9.ananas.destinations.LoginScreenDestination
|
import dev.jdtech.jellyfin.destinations.LoginScreenDestination
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
import com.nomadics9.ananas.viewmodels.MainViewModel
|
import dev.jdtech.jellyfin.viewmodels.MainViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas
|
package dev.jdtech.jellyfin
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
@ -9,11 +9,11 @@ import com.ramcosta.composedestinations.annotation.ActivityDestination
|
||||||
import com.ramcosta.composedestinations.manualcomposablecalls.composable
|
import com.ramcosta.composedestinations.manualcomposablecalls.composable
|
||||||
import com.ramcosta.composedestinations.scope.resultRecipient
|
import com.ramcosta.composedestinations.scope.resultRecipient
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.nomadics9.ananas.destinations.PlayerActivityDestination
|
import dev.jdtech.jellyfin.destinations.PlayerActivityDestination
|
||||||
import com.nomadics9.ananas.destinations.PlayerScreenDestination
|
import dev.jdtech.jellyfin.destinations.PlayerScreenDestination
|
||||||
import com.nomadics9.ananas.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import com.nomadics9.ananas.ui.PlayerScreen
|
import dev.jdtech.jellyfin.ui.PlayerScreen
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
|
|
||||||
data class PlayerActivityNavArgs(
|
data class PlayerActivityNavArgs(
|
||||||
val items: ArrayList<PlayerItem>,
|
val items: ArrayList<PlayerItem>,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.ui
|
package dev.jdtech.jellyfin.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
@ -38,13 +38,13 @@ import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
import com.nomadics9.ananas.destinations.LoginScreenDestination
|
import dev.jdtech.jellyfin.destinations.LoginScreenDestination
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
import com.nomadics9.ananas.ui.theme.spacings
|
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||||
import com.nomadics9.ananas.utils.ObserveAsEvents
|
import dev.jdtech.jellyfin.utils.ObserveAsEvents
|
||||||
import com.nomadics9.ananas.viewmodels.AddServerEvent
|
import dev.jdtech.jellyfin.viewmodels.AddServerEvent
|
||||||
import com.nomadics9.ananas.viewmodels.AddServerViewModel
|
import dev.jdtech.jellyfin.viewmodels.AddServerViewModel
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@Destination
|
@Destination
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -115,7 +115,7 @@ private fun AddServerScreenLayout(
|
||||||
},
|
},
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
autoCorrect = false,
|
autoCorrectEnabled = false,
|
||||||
keyboardType = KeyboardType.Uri,
|
keyboardType = KeyboardType.Uri,
|
||||||
imeAction = ImeAction.Go,
|
imeAction = ImeAction.Go,
|
||||||
),
|
),
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.ui
|
package dev.jdtech.jellyfin.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
@ -6,6 +6,9 @@ import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
@ -19,31 +22,28 @@ import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.tv.foundation.lazy.list.TvLazyColumn
|
|
||||||
import androidx.tv.foundation.lazy.list.TvLazyRow
|
|
||||||
import androidx.tv.foundation.lazy.list.items
|
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
import com.nomadics9.ananas.destinations.MovieScreenDestination
|
import dev.jdtech.jellyfin.destinations.MovieScreenDestination
|
||||||
import com.nomadics9.ananas.destinations.PlayerActivityDestination
|
import dev.jdtech.jellyfin.destinations.PlayerActivityDestination
|
||||||
import com.nomadics9.ananas.destinations.ShowScreenDestination
|
import dev.jdtech.jellyfin.destinations.ShowScreenDestination
|
||||||
import com.nomadics9.ananas.models.FindroidEpisode
|
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.models.HomeItem
|
import dev.jdtech.jellyfin.models.HomeItem
|
||||||
import com.nomadics9.ananas.ui.components.Direction
|
import dev.jdtech.jellyfin.ui.components.Direction
|
||||||
import com.nomadics9.ananas.ui.components.ItemCard
|
import dev.jdtech.jellyfin.ui.components.ItemCard
|
||||||
import com.nomadics9.ananas.ui.dummy.dummyHomeItems
|
import dev.jdtech.jellyfin.ui.dummy.dummyHomeItems
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
import com.nomadics9.ananas.ui.theme.spacings
|
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||||
import com.nomadics9.ananas.utils.ObserveAsEvents
|
import dev.jdtech.jellyfin.utils.ObserveAsEvents
|
||||||
import com.nomadics9.ananas.viewmodels.HomeViewModel
|
import dev.jdtech.jellyfin.viewmodels.HomeViewModel
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@Destination
|
@Destination
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -107,7 +107,7 @@ private fun HomeScreenLayout(
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
TvLazyColumn(
|
LazyColumn(
|
||||||
contentPadding = PaddingValues(bottom = MaterialTheme.spacings.large),
|
contentPadding = PaddingValues(bottom = MaterialTheme.spacings.large),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
@ -122,7 +122,7 @@ private fun HomeScreenLayout(
|
||||||
modifier = Modifier.padding(start = MaterialTheme.spacings.large),
|
modifier = Modifier.padding(start = MaterialTheme.spacings.large),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
||||||
TvLazyRow(
|
LazyRow(
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||||
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.large),
|
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.large),
|
||||||
) {
|
) {
|
||||||
|
@ -145,7 +145,7 @@ private fun HomeScreenLayout(
|
||||||
modifier = Modifier.padding(start = MaterialTheme.spacings.large),
|
modifier = Modifier.padding(start = MaterialTheme.spacings.large),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
||||||
TvLazyRow(
|
LazyRow(
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||||
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.large),
|
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.large),
|
||||||
) {
|
) {
|
|
@ -1,7 +1,10 @@
|
||||||
package com.nomadics9.ananas.ui
|
package dev.jdtech.jellyfin.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
@ -14,21 +17,18 @@ import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.tv.foundation.lazy.grid.TvGridCells
|
|
||||||
import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid
|
|
||||||
import androidx.tv.foundation.lazy.grid.items
|
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
import com.nomadics9.ananas.destinations.LibraryScreenDestination
|
import dev.jdtech.jellyfin.destinations.LibraryScreenDestination
|
||||||
import com.nomadics9.ananas.models.CollectionType
|
import dev.jdtech.jellyfin.models.CollectionType
|
||||||
import com.nomadics9.ananas.models.FindroidCollection
|
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||||
import com.nomadics9.ananas.ui.components.Direction
|
import dev.jdtech.jellyfin.ui.components.Direction
|
||||||
import com.nomadics9.ananas.ui.components.ItemCard
|
import dev.jdtech.jellyfin.ui.components.ItemCard
|
||||||
import com.nomadics9.ananas.ui.dummy.dummyCollections
|
import dev.jdtech.jellyfin.ui.dummy.dummyCollections
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
import com.nomadics9.ananas.ui.theme.spacings
|
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||||
import com.nomadics9.ananas.viewmodels.MediaViewModel
|
import dev.jdtech.jellyfin.viewmodels.MediaViewModel
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@Destination
|
@Destination
|
||||||
|
@ -72,8 +72,8 @@ private fun LibrariesScreenLayout(
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
TvLazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = TvGridCells.Fixed(3),
|
columns = GridCells.Fixed(3),
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.large),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.large),
|
||||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.large),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.large),
|
||||||
contentPadding = PaddingValues(
|
contentPadding = PaddingValues(
|
|
@ -1,8 +1,11 @@
|
||||||
package com.nomadics9.ananas.ui
|
package dev.jdtech.jellyfin.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
|
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||||
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
@ -15,27 +18,24 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import androidx.tv.foundation.lazy.grid.TvGridCells
|
|
||||||
import androidx.tv.foundation.lazy.grid.TvGridItemSpan
|
|
||||||
import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid
|
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
import com.nomadics9.ananas.destinations.LibraryScreenDestination
|
import dev.jdtech.jellyfin.destinations.LibraryScreenDestination
|
||||||
import com.nomadics9.ananas.destinations.MovieScreenDestination
|
import dev.jdtech.jellyfin.destinations.MovieScreenDestination
|
||||||
import com.nomadics9.ananas.destinations.ShowScreenDestination
|
import dev.jdtech.jellyfin.destinations.ShowScreenDestination
|
||||||
import com.nomadics9.ananas.models.CollectionType
|
import dev.jdtech.jellyfin.models.CollectionType
|
||||||
import com.nomadics9.ananas.models.FindroidFolder
|
import dev.jdtech.jellyfin.models.FindroidFolder
|
||||||
import com.nomadics9.ananas.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import com.nomadics9.ananas.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import com.nomadics9.ananas.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import com.nomadics9.ananas.ui.components.Direction
|
import dev.jdtech.jellyfin.ui.components.Direction
|
||||||
import com.nomadics9.ananas.ui.components.ItemCard
|
import dev.jdtech.jellyfin.ui.components.ItemCard
|
||||||
import com.nomadics9.ananas.ui.dummy.dummyMovies
|
import dev.jdtech.jellyfin.ui.dummy.dummyMovies
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
import com.nomadics9.ananas.ui.theme.spacings
|
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||||
import com.nomadics9.ananas.viewmodels.LibraryViewModel
|
import dev.jdtech.jellyfin.viewmodels.LibraryViewModel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
@ -86,8 +86,8 @@ private fun LibraryScreenLayout(
|
||||||
is LibraryViewModel.UiState.Loading -> Text(text = "LOADING")
|
is LibraryViewModel.UiState.Loading -> Text(text = "LOADING")
|
||||||
is LibraryViewModel.UiState.Normal -> {
|
is LibraryViewModel.UiState.Normal -> {
|
||||||
val items = uiState.items.collectAsLazyPagingItems()
|
val items = uiState.items.collectAsLazyPagingItems()
|
||||||
TvLazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = TvGridCells.Fixed(5),
|
columns = GridCells.Fixed(5),
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||||
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.default * 2, vertical = MaterialTheme.spacings.large),
|
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.default * 2, vertical = MaterialTheme.spacings.large),
|
||||||
|
@ -95,7 +95,7 @@ private fun LibraryScreenLayout(
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.focusRequester(focusRequester),
|
.focusRequester(focusRequester),
|
||||||
) {
|
) {
|
||||||
item(span = { TvGridItemSpan(this.maxLineSpan) }) {
|
item(span = { GridItemSpan(this.maxLineSpan) }) {
|
||||||
Text(
|
Text(
|
||||||
text = libraryName,
|
text = libraryName,
|
||||||
style = MaterialTheme.typography.displayMedium,
|
style = MaterialTheme.typography.displayMedium,
|
|
@ -1,4 +1,4 @@
|
||||||
package com.nomadics9.ananas.ui
|
package dev.jdtech.jellyfin.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
@ -41,15 +41,15 @@ import androidx.tv.material3.Text
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
import com.ramcosta.composedestinations.navigation.popUpTo
|
import com.ramcosta.composedestinations.navigation.popUpTo
|
||||||
import com.nomadics9.ananas.NavGraphs
|
import dev.jdtech.jellyfin.NavGraphs
|
||||||
import com.nomadics9.ananas.destinations.MainScreenDestination
|
import dev.jdtech.jellyfin.destinations.MainScreenDestination
|
||||||
import com.nomadics9.ananas.models.UiText
|
import dev.jdtech.jellyfin.models.UiText
|
||||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||||
import com.nomadics9.ananas.ui.theme.spacings
|
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||||
import com.nomadics9.ananas.utils.ObserveAsEvents
|
import dev.jdtech.jellyfin.utils.ObserveAsEvents
|
||||||
import com.nomadics9.ananas.viewmodels.LoginEvent
|
import dev.jdtech.jellyfin.viewmodels.LoginEvent
|
||||||
import com.nomadics9.ananas.viewmodels.LoginViewModel
|
import dev.jdtech.jellyfin.viewmodels.LoginViewModel
|
||||||
import com.nomadics9.ananas.core.R as CoreR
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
@Destination
|
@Destination
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -152,7 +152,7 @@ private fun LoginScreenLayout(
|
||||||
label = { Text(text = stringResource(id = CoreR.string.edit_text_username_hint)) },
|
label = { Text(text = stringResource(id = CoreR.string.edit_text_username_hint)) },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
autoCorrect = false,
|
autoCorrectEnabled = false,
|
||||||
keyboardType = KeyboardType.Text,
|
keyboardType = KeyboardType.Text,
|
||||||
imeAction = ImeAction.Next,
|
imeAction = ImeAction.Next,
|
||||||
),
|
),
|
||||||
|
@ -175,7 +175,7 @@ private fun LoginScreenLayout(
|
||||||
label = { Text(text = stringResource(id = CoreR.string.edit_text_password_hint)) },
|
label = { Text(text = stringResource(id = CoreR.string.edit_text_password_hint)) },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
autoCorrect = false,
|
autoCorrectEnabled = false,
|
||||||
keyboardType = KeyboardType.Password,
|
keyboardType = KeyboardType.Password,
|
||||||
imeAction = ImeAction.Go,
|
imeAction = ImeAction.Go,
|
||||||
),
|
),
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue