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:
|
||||
|
||||
jobs:
|
||||
# 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
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-22.04
|
||||
if: startsWith(github.event.head_commit.message, 'build:')
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
@ -39,45 +21,62 @@ jobs:
|
|||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
- 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.
|
||||
- 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
|
||||
with:
|
||||
name: phone-libre-arm64-v8a.apk
|
||||
path: ./app/phone/build/outputs/apk/libre/release/ananas-v0.10.3-0.14.2-libre-arm64-v8a.apk
|
||||
# - name: Upload artifact phone-libre-armeabi-v7a-debug.apk
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: 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
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: 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
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: 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
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: 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
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: 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
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: 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
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: tv-libre-x86-debug.apk
|
||||
# path: ./app/tv/build/outputs/apk/libre/debug/tv-libre-x86-debug.apk
|
||||
name: phone-libre-arm64-v8a-debug.apk
|
||||
path: ./app/phone/build/outputs/apk/libre/debug/phone-libre-arm64-v8a-debug.apk
|
||||
- name: Upload artifact phone-libre-armeabi-v7a-debug.apk
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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
|
||||
captures/
|
||||
app/phone/libre/release/
|
||||
.kotlin
|
||||
.externalNativeBuild/
|
||||
.cxx/
|
||||
*.apk
|
||||
*.dm
|
||||
output.json
|
||||
app/phone/libre/release/output-metadata.json
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
|
@ -41,4 +37,3 @@ fastlane/report.xml
|
|||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
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.
|
||||
|
|
36
README.md
36
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
|
||||
| Home | Library | Movie | Season | Episode |
|
||||
|-------------------------------------|-------------------------------------|---------------------------------|-----------------------------------|-------------------------------------|
|
||||
|
@ -9,9 +24,8 @@ Personal fork
|
|||
## Features
|
||||
- Completely native interface
|
||||
- Supported media items: movies, series, seasons, episodes
|
||||
- Direct play and Transcoding
|
||||
- Offline playback / downloads
|
||||
- Transcoding Downloads (Original - 720p - 480p - 360p)
|
||||
- Direct play only, (no transcoding)
|
||||
- Offline playback / downloads
|
||||
- ExoPlayer
|
||||
- Video codecs: H.263, H.264, H.265, VP8, VP9, AV1
|
||||
- Support depends on Android device
|
||||
|
@ -35,8 +49,20 @@ Personal fork
|
|||
- Websocket connection (Syncplay)
|
||||
- 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
|
||||
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 {
|
||||
namespace = "com.nomadics9.ananas"
|
||||
namespace = "dev.jdtech.jellyfin"
|
||||
compileSdk = Versions.compileSdk
|
||||
buildToolsVersion = Versions.buildTools
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.nomadics9.ananas"
|
||||
applicationId = "dev.jdtech.jellyfin"
|
||||
minSdk = Versions.minSdk
|
||||
targetSdk = Versions.targetSdk
|
||||
|
||||
versionCode = Versions.appCode
|
||||
versionName = Versions.appName
|
||||
|
||||
testInstrumentationRunner = "com.nomadics9.ananas.HiltTestRunner"
|
||||
buildConfigField( "String", "DEFAULT_SERVER_ADDRESS", "\" \"")
|
||||
buildConfigField( "String", "REQUEST_SERVER_ADDRESS", "\" \"")
|
||||
buildConfigField("String", "FORGET_PASSWORD_ADDRESS", "\" \"")
|
||||
buildConfigField("String", "UPDATE_ADDRESS", "\" \"")
|
||||
testInstrumentationRunner = "dev.jdtech.jellyfin.HiltTestRunner"
|
||||
}
|
||||
|
||||
applicationVariants.all {
|
||||
|
@ -35,7 +31,7 @@ android {
|
|||
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
|
||||
.forEach { output ->
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -61,18 +57,10 @@ android {
|
|||
|
||||
flavorDimensions += "variant"
|
||||
productFlavors {
|
||||
create("libre") {
|
||||
register("libre") {
|
||||
dimension = "variant"
|
||||
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 {
|
||||
|
@ -134,7 +122,6 @@ dependencies {
|
|||
implementation(libs.material)
|
||||
implementation(libs.media3.ffmpeg.decoder)
|
||||
implementation(libs.timber)
|
||||
implementation(libs.markwon)
|
||||
|
||||
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.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keepnames class com.nomadics9.ananas.models.PlayerItem
|
||||
-keepnames class dev.jdtech.jellyfin.models.PlayerItem
|
||||
|
||||
# ProGuard thinks all SettingsFragments are unused
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsLanguageFragment
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsAppearanceFragment
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsDownloadsFragment
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsPlayerFragment
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsDeviceFragment
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsCacheFragment
|
||||
-keep class com.nomadics9.ananas.fragments.SettingsNetworkFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsLanguageFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsAppearanceFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsDownloadsFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsPlayerFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsDeviceFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsCacheFragment
|
||||
-keep class dev.jdtech.jellyfin.fragments.SettingsNetworkFragment
|
||||
|
||||
# These classes are from okhttp and are not used in Android
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.util.Log
|
||||
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.HiltAndroidTest
|
||||
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.not
|
||||
import org.junit.Before
|
||||
|
@ -76,9 +76,9 @@ class MainActivityTest {
|
|||
waitForElement(allOf(withText("Movies"), isDisplayed()))
|
||||
onView(withText("Movies")).perform(click())
|
||||
|
||||
// Navigate to Battle of the Stars
|
||||
waitForElement(allOf(withText("Battle of the Stars"), isDisplayed()))
|
||||
onView(withText("Battle of the Stars")).perform(click())
|
||||
// Navigate to The Boy in the Plastic Bubble
|
||||
waitForElement(allOf(withText("The Boy in the Plastic Bubble"), isDisplayed()))
|
||||
onView(withText("The Boy in the Plastic Bubble")).perform(click())
|
||||
|
||||
// Play the movie
|
||||
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.ViewTreeObserver
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.di
|
||||
package dev.jdtech.jellyfin.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
|
@ -7,8 +7,8 @@ import dagger.Provides
|
|||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import com.nomadics9.ananas.database.ServerDatabase
|
||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
||||
import dev.jdtech.jellyfin.database.ServerDatabase
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import javax.inject.Singleton
|
||||
|
||||
@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 androidx.appcompat.app.AppCompatDelegate
|
||||
|
@ -14,7 +14,7 @@ import com.google.android.material.color.DynamicColorsOptions
|
|||
import dagger.hilt.android.HiltAndroidApp
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@HiltAndroidApp
|
||||
class BaseApplication : Application(), Configuration.Provider, ImageLoaderFactory {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
@ -9,7 +9,7 @@ import androidx.core.view.WindowInsetsCompat
|
|||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.media3.session.MediaSession
|
||||
import com.nomadics9.ananas.viewmodels.PlayerActivityViewModel
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
|
||||
|
||||
abstract class BasePlayerActivity : AppCompatActivity() {
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.DrawableRes
|
||||
import coil.load
|
||||
import com.nomadics9.ananas.api.JellyfinApi
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.User
|
||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.User
|
||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||
import org.jellyfin.sdk.model.api.ImageType
|
||||
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) {
|
||||
val itemId =
|
|
@ -1,10 +1,12 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
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.NavGraph
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
|
@ -19,16 +21,12 @@ import androidx.work.OneTimeWorkRequestBuilder
|
|||
import androidx.work.WorkManager
|
||||
import com.google.android.material.navigation.NavigationBarView
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
||||
import com.nomadics9.ananas.databinding.ActivityMainBinding
|
||||
import com.nomadics9.ananas.viewmodels.MainViewModel
|
||||
import com.nomadics9.ananas.work.SyncWorker
|
||||
import com.nomadics9.ananas.repository.JellyfinRepository
|
||||
import com.nomadics9.ananas.utils.restart
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import dev.jdtech.jellyfin.databinding.ActivityMainBinding
|
||||
import dev.jdtech.jellyfin.viewmodels.MainViewModel
|
||||
import dev.jdtech.jellyfin.work.SyncWorker
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
@ -40,9 +38,6 @@ class MainActivity : AppCompatActivity() {
|
|||
@Inject
|
||||
lateinit var database: ServerDatabaseDao
|
||||
|
||||
@Inject
|
||||
lateinit var jellyfinRepository: JellyfinRepository
|
||||
|
||||
@Inject
|
||||
lateinit var appPreferences: AppPreferences
|
||||
|
||||
|
@ -53,6 +48,21 @@ class MainActivity : AppCompatActivity() {
|
|||
scheduleUserDataSync()
|
||||
applyTheme()
|
||||
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)
|
||||
|
@ -76,18 +86,10 @@ class MainActivity : AppCompatActivity() {
|
|||
val navView: NavigationBarView = binding.navView as NavigationBarView
|
||||
|
||||
if (appPreferences.offlineMode) {
|
||||
appPreferences.isOffline = true
|
||||
}
|
||||
|
||||
if (appPreferences.isOffline) {
|
||||
navView.menu.clear()
|
||||
navView.inflateMenu(CoreR.menu.bottom_nav_menu_offline)
|
||||
}
|
||||
|
||||
if (!appPreferences.isOffline && appPreferences.autoOffline) {
|
||||
testServerConnection()
|
||||
}
|
||||
|
||||
setSupportActionBar(binding.mainToolbar)
|
||||
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
|
@ -108,7 +110,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||
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
|
||||
}
|
||||
if (destination.id == com.mikepenz.aboutlibraries.R.id.about_libraries_dest) {
|
||||
|
@ -168,18 +170,4 @@ class MainActivity : AppCompatActivity() {
|
|||
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.PictureInPictureParams
|
||||
import android.content.Context
|
||||
|
@ -34,25 +35,25 @@ import androidx.media3.ui.PlayerControlView
|
|||
import androidx.media3.ui.PlayerView
|
||||
import androidx.navigation.navArgs
|
||||
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 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 timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import com.nomadics9.ananas.models.VideoQuality
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
var isControlsLocked: Boolean = false
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PlayerActivity : BasePlayerActivity() {
|
||||
|
||||
@Inject
|
||||
lateinit var appPreferences: AppPreferences
|
||||
|
||||
|
@ -61,8 +62,6 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
override val viewModel: PlayerActivityViewModel by viewModels()
|
||||
private var previewScrubListener: PreviewScrubListener? = null
|
||||
private var wasZoom: Boolean = false
|
||||
private var oldSegment: FindroidSegment? = null
|
||||
private var buttonPressed: Boolean = false
|
||||
|
||||
private val isPipSupported by lazy {
|
||||
// Check if device has PiP feature
|
||||
|
@ -111,13 +110,12 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
configureInsets(lockedControls)
|
||||
|
||||
if (appPreferences.playerGestures) {
|
||||
playerGestureHelper =
|
||||
PlayerGestureHelper(
|
||||
appPreferences,
|
||||
this,
|
||||
binding.playerView,
|
||||
getSystemService(AUDIO_SERVICE) as AudioManager,
|
||||
)
|
||||
playerGestureHelper = PlayerGestureHelper(
|
||||
appPreferences,
|
||||
this,
|
||||
binding.playerView,
|
||||
getSystemService(Context.AUDIO_SERVICE) as AudioManager,
|
||||
)
|
||||
}
|
||||
|
||||
binding.playerView.findViewById<View>(R.id.back_button).setOnClickListener {
|
||||
|
@ -129,8 +127,7 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
val audioButton = binding.playerView.findViewById<ImageButton>(R.id.btn_audio_track)
|
||||
val subtitleButton = binding.playerView.findViewById<ImageButton>(R.id.btn_subtitle)
|
||||
val speedButton = binding.playerView.findViewById<ImageButton>(R.id.btn_speed)
|
||||
val skipButton = binding.playerView.findViewById<Button>(R.id.btn_skip_intro)
|
||||
val watchCreditsButton = binding.playerView.findViewById<Button>(R.id.btn_watch_credits)
|
||||
val skipIntroButton = binding.playerView.findViewById<Button>(R.id.btn_skip_intro)
|
||||
val pipButton = binding.playerView.findViewById<ImageButton>(R.id.btn_pip)
|
||||
val lockButton = binding.playerView.findViewById<ImageButton>(R.id.btn_lockview)
|
||||
val unlockButton = binding.playerView.findViewById<ImageButton>(R.id.btn_unlock)
|
||||
|
@ -144,101 +141,19 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
// Title
|
||||
videoNameTextView.text = currentItemTitle
|
||||
|
||||
// Skip Button
|
||||
if (currentSegment != oldSegment) buttonPressed = false
|
||||
// Button Visibility and Text
|
||||
when (currentSegment?.type) {
|
||||
"intro" -> {
|
||||
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
|
||||
// Skip Intro button
|
||||
skipIntroButton.isVisible = !isInPictureInPictureMode && currentIntro != null
|
||||
skipIntroButton.setOnClickListener {
|
||||
currentIntro?.let {
|
||||
binding.playerView.player?.seekTo((it.introEnd * 1000).toLong())
|
||||
}
|
||||
}
|
||||
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
|
||||
previewScrubListener?.let {
|
||||
it.currentTrickplay = currentTrickplay
|
||||
}
|
||||
|
||||
playerGestureHelper?.let {
|
||||
it.currentTrickplay = currentTrickplay
|
||||
}
|
||||
|
||||
// Chapters
|
||||
if (appPreferences.showChapterMarkers && currentChapters != null) {
|
||||
currentChapters?.let { chapters ->
|
||||
|
@ -276,8 +191,7 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
if (appPreferences.playerPipGesture) {
|
||||
try {
|
||||
setPictureInPictureParams(pipParams(event.isPlaying))
|
||||
} catch (_: IllegalArgumentException) {
|
||||
}
|
||||
} catch (_: IllegalArgumentException) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +290,7 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
viewModel.initializePlayer(args.items)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingSuperCall")
|
||||
override fun onUserLeaveHint() {
|
||||
super.onUserLeaveHint()
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S &&
|
||||
|
@ -390,38 +305,34 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
private fun pipParams(enableAutoEnter: Boolean = viewModel.player.isPlaying): PictureInPictureParams {
|
||||
val displayAspectRatio = Rational(binding.playerView.width, binding.playerView.height)
|
||||
|
||||
val aspectRatio =
|
||||
binding.playerView.player?.videoSize?.let {
|
||||
Rational(
|
||||
it.width.coerceAtMost((it.height * 2.39f).toInt()),
|
||||
it.height.coerceAtMost((it.width * 2.39f).toInt()),
|
||||
)
|
||||
}
|
||||
val aspectRatio = binding.playerView.player?.videoSize?.let {
|
||||
Rational(
|
||||
it.width.coerceAtMost((it.height * 2.39f).toInt()),
|
||||
it.height.coerceAtMost((it.width * 2.39f).toInt()),
|
||||
)
|
||||
}
|
||||
|
||||
val sourceRectHint =
|
||||
if (displayAspectRatio < aspectRatio!!) {
|
||||
val space = ((binding.playerView.height - (binding.playerView.width.toFloat() / aspectRatio.toFloat())) / 2).toInt()
|
||||
Rect(
|
||||
0,
|
||||
space,
|
||||
binding.playerView.width,
|
||||
(binding.playerView.width.toFloat() / aspectRatio.toFloat()).toInt() + space,
|
||||
)
|
||||
} else {
|
||||
val space = ((binding.playerView.width - (binding.playerView.height.toFloat() * aspectRatio.toFloat())) / 2).toInt()
|
||||
Rect(
|
||||
space,
|
||||
0,
|
||||
(binding.playerView.height.toFloat() * aspectRatio.toFloat()).toInt() + space,
|
||||
binding.playerView.height,
|
||||
)
|
||||
}
|
||||
val sourceRectHint = if (displayAspectRatio < aspectRatio!!) {
|
||||
val space = ((binding.playerView.height - (binding.playerView.width.toFloat() / aspectRatio.toFloat())) / 2).toInt()
|
||||
Rect(
|
||||
0,
|
||||
space,
|
||||
binding.playerView.width,
|
||||
(binding.playerView.width.toFloat() / aspectRatio.toFloat()).toInt() + space,
|
||||
)
|
||||
} else {
|
||||
val space = ((binding.playerView.width - (binding.playerView.height.toFloat() * aspectRatio.toFloat())) / 2).toInt()
|
||||
Rect(
|
||||
space,
|
||||
0,
|
||||
(binding.playerView.height.toFloat() * aspectRatio.toFloat()).toInt() + space,
|
||||
binding.playerView.height,
|
||||
)
|
||||
}
|
||||
|
||||
val builder =
|
||||
PictureInPictureParams
|
||||
.Builder()
|
||||
.setAspectRatio(aspectRatio)
|
||||
.setSourceRectHint(sourceRectHint)
|
||||
val builder = PictureInPictureParams.Builder()
|
||||
.setAspectRatio(aspectRatio)
|
||||
.setSourceRectHint(sourceRectHint)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
builder.setAutoEnterEnabled(enableAutoEnter)
|
||||
|
@ -479,29 +390,25 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
playerGestureHelper?.updateZoomMode(false)
|
||||
|
||||
// Brightness mode Auto
|
||||
window.attributes =
|
||||
window.attributes.apply {
|
||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
}
|
||||
window.attributes = window.attributes.apply {
|
||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
}
|
||||
}
|
||||
false -> {
|
||||
binding.playerView.useController = true
|
||||
playerGestureHelper?.updateZoomMode(wasZoom)
|
||||
|
||||
// Override auto brightness
|
||||
window.attributes =
|
||||
window.attributes.apply {
|
||||
screenBrightness =
|
||||
if (appPreferences.playerBrightnessRemember) {
|
||||
appPreferences.playerBrightness
|
||||
} else {
|
||||
Settings.System
|
||||
.getInt(
|
||||
contentResolver,
|
||||
Settings.System.SCREEN_BRIGHTNESS,
|
||||
).toFloat() / 255
|
||||
}
|
||||
window.attributes = window.attributes.apply {
|
||||
screenBrightness = if (appPreferences.playerBrightnessRemember) {
|
||||
appPreferences.playerBrightness
|
||||
} else {
|
||||
Settings.System.getInt(
|
||||
contentResolver,
|
||||
Settings.System.SCREEN_BRIGHTNESS,
|
||||
).toFloat() / 255
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindCardItemImage
|
||||
import com.nomadics9.ananas.databinding.CollectionItemBinding
|
||||
import com.nomadics9.ananas.models.FindroidCollection
|
||||
import dev.jdtech.jellyfin.bindCardItemImage
|
||||
import dev.jdtech.jellyfin.databinding.CollectionItemBinding
|
||||
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||
|
||||
class CollectionListAdapter(
|
||||
private val onClickListener: (collection: FindroidCollection) -> Unit,
|
||||
|
@ -47,4 +47,4 @@ class CollectionListAdapter(
|
|||
}
|
||||
holder.bind(collection)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.databinding.DiscoveredServerItemBinding
|
||||
import com.nomadics9.ananas.models.DiscoveredServer
|
||||
import dev.jdtech.jellyfin.databinding.DiscoveredServerItemBinding
|
||||
import dev.jdtech.jellyfin.models.DiscoveredServer
|
||||
|
||||
class DiscoveredServerListAdapter(
|
||||
private val clickListener: (server: DiscoveredServer) -> Unit,
|
||||
|
@ -55,4 +55,4 @@ class DiscoveredServerListAdapter(
|
|||
holder.itemView.setOnClickListener { clickListener(server) }
|
||||
holder.bind(server)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.text.Html.fromHtml
|
||||
import android.util.TypedValue
|
||||
|
@ -9,15 +9,15 @@ import androidx.core.view.isVisible
|
|||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindCardItemImage
|
||||
import com.nomadics9.ananas.bindItemBackdropById
|
||||
import com.nomadics9.ananas.bindSeasonPoster
|
||||
import com.nomadics9.ananas.databinding.EpisodeItemBinding
|
||||
import com.nomadics9.ananas.databinding.SeasonHeaderBinding
|
||||
import com.nomadics9.ananas.models.EpisodeItem
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.bindCardItemImage
|
||||
import dev.jdtech.jellyfin.bindItemBackdropById
|
||||
import dev.jdtech.jellyfin.bindSeasonPoster
|
||||
import dev.jdtech.jellyfin.databinding.EpisodeItemBinding
|
||||
import dev.jdtech.jellyfin.databinding.SeasonHeaderBinding
|
||||
import dev.jdtech.jellyfin.models.EpisodeItem
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
private const val ITEM_VIEW_TYPE_HEADER = 0
|
||||
private const val ITEM_VIEW_TYPE_EPISODE = 1
|
||||
|
@ -123,4 +123,4 @@ class EpisodeListAdapter(
|
|||
is EpisodeItem.Episode -> ITEM_VIEW_TYPE_EPISODE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.Constants
|
||||
import com.nomadics9.ananas.databinding.FavoriteSectionBinding
|
||||
import com.nomadics9.ananas.models.FavoriteSection
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.Constants
|
||||
import dev.jdtech.jellyfin.databinding.FavoriteSectionBinding
|
||||
import dev.jdtech.jellyfin.models.FavoriteSection
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
|
||||
class FavoritesListAdapter(
|
||||
private val onItemClickListener: (item: FindroidItem) -> Unit,
|
||||
|
@ -59,4 +59,4 @@ class FavoritesListAdapter(
|
|||
val collection = getItem(position)
|
||||
holder.bind(collection, onItemClickListener)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
|
@ -8,13 +8,13 @@ import androidx.core.view.isVisible
|
|||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindCardItemImage
|
||||
import com.nomadics9.ananas.databinding.HomeEpisodeItemBinding
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.bindCardItemImage
|
||||
import dev.jdtech.jellyfin.databinding.HomeEpisodeItemBinding
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class HomeEpisodeListAdapter(private val onClickListener: (item: FindroidItem) -> Unit) : ListAdapter<FindroidItem, HomeEpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
|
||||
class EpisodeViewHolder(
|
||||
|
@ -81,4 +81,4 @@ class HomeEpisodeListAdapter(private val onClickListener: (item: FindroidItem) -
|
|||
}
|
||||
holder.bind(item)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindPersonImage
|
||||
import com.nomadics9.ananas.databinding.PersonItemBinding
|
||||
import dev.jdtech.jellyfin.bindPersonImage
|
||||
import dev.jdtech.jellyfin.databinding.PersonItemBinding
|
||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||
|
||||
class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Unit) : ListAdapter<BaseItemPerson, PersonListAdapter.PersonViewHolder>(DiffCallback) {
|
||||
|
@ -45,4 +45,4 @@ class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Uni
|
|||
holder.bind(item)
|
||||
holder.itemView.setOnClickListener { clickListener(item) }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.databinding.ServerAddressListItemBinding
|
||||
import com.nomadics9.ananas.models.ServerAddress
|
||||
import dev.jdtech.jellyfin.databinding.ServerAddressListItemBinding
|
||||
import dev.jdtech.jellyfin.models.ServerAddress
|
||||
|
||||
class ServerAddressAdapter(
|
||||
private val clickListener: (address: ServerAddress) -> Unit,
|
||||
|
@ -48,4 +48,4 @@ class ServerAddressAdapter(
|
|||
holder.itemView.setOnLongClickListener { longClickListener(address) }
|
||||
holder.bind(address)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.databinding.ServerItemBinding
|
||||
import com.nomadics9.ananas.models.Server
|
||||
import dev.jdtech.jellyfin.databinding.ServerItemBinding
|
||||
import dev.jdtech.jellyfin.models.Server
|
||||
|
||||
class ServerGridAdapter(
|
||||
private val onClickListener: (server: Server) -> Unit,
|
||||
|
@ -46,4 +46,4 @@ class ServerGridAdapter(
|
|||
}
|
||||
holder.bind(server)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindUserImage
|
||||
import com.nomadics9.ananas.databinding.UserListItemBinding
|
||||
import com.nomadics9.ananas.models.User
|
||||
import dev.jdtech.jellyfin.bindUserImage
|
||||
import dev.jdtech.jellyfin.databinding.UserListItemBinding
|
||||
import dev.jdtech.jellyfin.models.User
|
||||
|
||||
class UserListAdapter(
|
||||
private val clickListener: (user: User) -> Unit,
|
||||
|
@ -50,4 +50,4 @@ class UserListAdapter(
|
|||
holder.itemView.setOnLongClickListener { longClickListener(user) }
|
||||
holder.bind(user)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindUserImage
|
||||
import com.nomadics9.ananas.databinding.UserItemBinding
|
||||
import com.nomadics9.ananas.models.User
|
||||
import dev.jdtech.jellyfin.bindUserImage
|
||||
import dev.jdtech.jellyfin.databinding.UserItemBinding
|
||||
import dev.jdtech.jellyfin.models.User
|
||||
|
||||
class UserLoginListAdapter(
|
||||
private val clickListener: (user: User) -> Unit,
|
||||
|
@ -48,4 +48,4 @@ class UserLoginListAdapter(
|
|||
holder.itemView.setOnClickListener { clickListener(user) }
|
||||
holder.bind(user)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -7,12 +7,12 @@ import androidx.core.view.isVisible
|
|||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindItemImage
|
||||
import com.nomadics9.ananas.databinding.BaseItemBinding
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.bindItemImage
|
||||
import dev.jdtech.jellyfin.databinding.BaseItemBinding
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class ViewItemListAdapter(
|
||||
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.View
|
||||
|
@ -7,12 +7,12 @@ import androidx.core.view.isVisible
|
|||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.bindItemImage
|
||||
import com.nomadics9.ananas.databinding.BaseItemBinding
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.bindItemImage
|
||||
import dev.jdtech.jellyfin.databinding.BaseItemBinding
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class ViewItemPagingAdapter(
|
||||
private val onClickListener: (item: FindroidItem) -> Unit,
|
||||
|
@ -70,4 +70,4 @@ class ViewItemPagingAdapter(
|
|||
holder.bind(item, fixedWidth)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
package com.nomadics9.ananas.adapters
|
||||
package dev.jdtech.jellyfin.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nomadics9.ananas.databinding.CardOfflineBinding
|
||||
import com.nomadics9.ananas.databinding.NextUpSectionBinding
|
||||
import com.nomadics9.ananas.databinding.ViewItemBinding
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.HomeItem
|
||||
import com.nomadics9.ananas.models.View
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.databinding.CardOfflineBinding
|
||||
import dev.jdtech.jellyfin.databinding.NextUpSectionBinding
|
||||
import dev.jdtech.jellyfin.databinding.ViewItemBinding
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.HomeItem
|
||||
import dev.jdtech.jellyfin.models.View
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
private const val ITEM_VIEW_TYPE_NEXT_UP = 0
|
||||
private const val ITEM_VIEW_TYPE_VIEW = 1
|
||||
|
@ -125,4 +125,4 @@ class ViewListAdapter(
|
|||
is HomeItem.ViewItem -> ITEM_VIEW_TYPE_VIEW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.di
|
||||
package dev.jdtech.jellyfin.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
|
@ -6,7 +6,7 @@ import dagger.Provides
|
|||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import com.nomadics9.ananas.BaseApplication
|
||||
import dev.jdtech.jellyfin.BaseApplication
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
|
@ -1,11 +1,11 @@
|
|||
package com.nomadics9.ananas.dialogs
|
||||
package dev.jdtech.jellyfin.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import android.os.StatFs
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
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(
|
||||
context: Context,
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
|
@ -14,12 +14,11 @@ import androidx.lifecycle.Lifecycle
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.nomadics9.ananas.BuildConfig
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.DiscoveredServerListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentAddServerBinding
|
||||
import com.nomadics9.ananas.viewmodels.AddServerEvent
|
||||
import com.nomadics9.ananas.viewmodels.AddServerViewModel
|
||||
import dev.jdtech.jellyfin.adapters.DiscoveredServerListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentAddServerBinding
|
||||
import dev.jdtech.jellyfin.viewmodels.AddServerEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.AddServerViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -140,16 +134,6 @@ class AddServerFragment : Fragment() {
|
|||
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() {
|
||||
findNavController().navigate(AddServerFragmentDirections.actionAddServerFragmentToLoginFragment())
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -13,18 +13,18 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentFavoriteBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.viewmodels.CollectionViewModel
|
||||
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentFavoriteBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.viewmodels.CollectionViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class CollectionFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -13,19 +13,19 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentDownloadsBinding
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.utils.restart
|
||||
import com.nomadics9.ananas.viewmodels.DownloadsEvent
|
||||
import com.nomadics9.ananas.viewmodels.DownloadsViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentDownloadsBinding
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.utils.restart
|
||||
import dev.jdtech.jellyfin.viewmodels.DownloadsEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.DownloadsViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DownloadsFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.app.DownloadManager
|
||||
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.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.R
|
||||
import com.nomadics9.ananas.bindCardItemImage
|
||||
import com.nomadics9.ananas.databinding.EpisodeBottomSheetBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.dialogs.getStorageSelectionDialog
|
||||
import com.nomadics9.ananas.dialogs.getVideoVersionDialog
|
||||
import com.nomadics9.ananas.models.FindroidSourceType
|
||||
import com.nomadics9.ananas.models.PlayerItem
|
||||
import com.nomadics9.ananas.models.UiText
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.models.isDownloading
|
||||
import com.nomadics9.ananas.utils.setIconTintColorAttribute
|
||||
import com.nomadics9.ananas.viewmodels.EpisodeBottomSheetEvent
|
||||
import com.nomadics9.ananas.viewmodels.EpisodeBottomSheetViewModel
|
||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.R
|
||||
import dev.jdtech.jellyfin.bindCardItemImage
|
||||
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.dialogs.getStorageSelectionDialog
|
||||
import dev.jdtech.jellyfin.dialogs.getVideoVersionDialog
|
||||
import dev.jdtech.jellyfin.models.FindroidSourceType
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.models.UiText
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.models.isDownloading
|
||||
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
|
||||
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jellyfin.sdk.model.DateTime
|
||||
import timber.log.Timber
|
||||
|
@ -48,7 +48,7 @@ import java.util.UUID
|
|||
import javax.inject.Inject
|
||||
import android.R as AndroidR
|
||||
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
|
||||
class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -12,15 +12,15 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentFavoriteBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.viewmodels.FavoriteViewModel
|
||||
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentFavoriteBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.viewmodels.FavoriteViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -19,21 +19,21 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.adapters.ViewListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentHomeBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.utils.restart
|
||||
import com.nomadics9.ananas.viewmodels.HomeViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.adapters.ViewListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentHomeBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.utils.restart
|
||||
import dev.jdtech.jellyfin.viewmodels.HomeViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class HomeFragment : Fragment() {
|
||||
|
@ -74,12 +74,6 @@ class HomeFragment : Fragment() {
|
|||
val searchView = search.actionView as SearchView
|
||||
searchView.queryHint = getString(CoreR.string.search_hint)
|
||||
|
||||
val requests = menu.findItem(CoreR.id.action_requests)
|
||||
requests.setOnMenuItemClickListener{
|
||||
navigateToRequestsWebViewFragment()
|
||||
true
|
||||
}
|
||||
|
||||
search.setOnActionExpandListener(
|
||||
object : MenuItem.OnActionExpandListener {
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
|
@ -208,7 +202,7 @@ class HomeFragment : Fragment() {
|
|||
checkIfLoginRequired(uiState.error.message)
|
||||
}
|
||||
|
||||
private fun navigateToLibraryFragment(view: com.nomadics9.ananas.models.View) {
|
||||
private fun navigateToLibraryFragment(view: dev.jdtech.jellyfin.models.View) {
|
||||
findNavController().navigate(
|
||||
HomeFragmentDirections.actionNavigationHomeToLibraryFragment(
|
||||
libraryId = view.id,
|
||||
|
@ -257,10 +251,4 @@ class HomeFragment : Fragment() {
|
|||
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.view.LayoutInflater
|
||||
|
@ -19,25 +19,24 @@ import androidx.navigation.fragment.findNavController
|
|||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.paging.LoadState
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.adapters.ViewItemPagingAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentLibraryBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.dialogs.SortDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidBoxSet
|
||||
import com.nomadics9.ananas.models.FindroidFolder
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.models.SortBy
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.viewmodels.LibraryViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.adapters.ViewItemPagingAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentLibraryBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.dialogs.SortDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidBoxSet
|
||||
import dev.jdtech.jellyfin.models.FindroidFolder
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.models.SortBy
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.viewmodels.LibraryViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jellyfin.sdk.model.api.SortOrder
|
||||
import java.lang.IllegalArgumentException
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class LibraryFragment : Fragment() {
|
||||
|
@ -63,11 +62,6 @@ class LibraryFragment : Fragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.itemsRecyclerView.layoutManager =
|
||||
GridLayoutManager(context, preferences.spanCount)
|
||||
|
||||
|
||||
|
||||
val menuHost: MenuHost = requireActivity()
|
||||
menuHost.addMenuProvider(
|
||||
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.text.Html.fromHtml
|
||||
import android.view.LayoutInflater
|
||||
|
@ -18,18 +16,16 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.BuildConfig
|
||||
import com.nomadics9.ananas.adapters.UserLoginListAdapter
|
||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
||||
import com.nomadics9.ananas.databinding.FragmentLoginBinding
|
||||
import com.nomadics9.ananas.viewmodels.LoginEvent
|
||||
import com.nomadics9.ananas.viewmodels.LoginViewModel
|
||||
import io.noties.markwon.Markwon
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.adapters.UserLoginListAdapter
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import dev.jdtech.jellyfin.databinding.FragmentLoginBinding
|
||||
import dev.jdtech.jellyfin.viewmodels.LoginEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.LoginViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class LoginFragment : Fragment() {
|
||||
|
@ -82,17 +78,6 @@ class LoginFragment : Fragment() {
|
|||
(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.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
viewModel.uiState.collect { uiState ->
|
||||
|
@ -158,21 +143,7 @@ class LoginFragment : Fragment() {
|
|||
binding.editTextPasswordLayout.isEnabled = true
|
||||
|
||||
uiState.disclaimer?.let { disclaimer ->
|
||||
if (BuildConfig.FLAVOR == "Ananas") {
|
||||
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)
|
||||
}
|
||||
binding.loginDisclaimer.text = fromHtml(disclaimer, 0)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -19,15 +19,15 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.CollectionListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentMediaBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidCollection
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.viewmodels.MediaViewModel
|
||||
import dev.jdtech.jellyfin.adapters.CollectionListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentMediaBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.viewmodels.MediaViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MediaFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.app.DownloadManager
|
||||
import android.content.Intent
|
||||
|
@ -21,32 +21,32 @@ import androidx.navigation.fragment.findNavController
|
|||
import androidx.navigation.fragment.navArgs
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.R
|
||||
import com.nomadics9.ananas.adapters.PersonListAdapter
|
||||
import com.nomadics9.ananas.bindItemBackdropImage
|
||||
import com.nomadics9.ananas.databinding.FragmentMovieBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.dialogs.getStorageSelectionDialog
|
||||
import com.nomadics9.ananas.dialogs.getVideoVersionDialog
|
||||
import com.nomadics9.ananas.models.AudioCodec
|
||||
import com.nomadics9.ananas.models.DisplayProfile
|
||||
import com.nomadics9.ananas.models.FindroidSourceType
|
||||
import com.nomadics9.ananas.models.PlayerItem
|
||||
import com.nomadics9.ananas.models.UiText
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.models.isDownloading
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.utils.setIconTintColorAttribute
|
||||
import com.nomadics9.ananas.viewmodels.MovieEvent
|
||||
import com.nomadics9.ananas.viewmodels.MovieViewModel
|
||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.R
|
||||
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
||||
import dev.jdtech.jellyfin.bindItemBackdropImage
|
||||
import dev.jdtech.jellyfin.databinding.FragmentMovieBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.dialogs.getStorageSelectionDialog
|
||||
import dev.jdtech.jellyfin.dialogs.getVideoVersionDialog
|
||||
import dev.jdtech.jellyfin.models.AudioCodec
|
||||
import dev.jdtech.jellyfin.models.DisplayProfile
|
||||
import dev.jdtech.jellyfin.models.FindroidSourceType
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.models.UiText
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.models.isDownloading
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
|
||||
import dev.jdtech.jellyfin.viewmodels.MovieEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.MovieViewModel
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MovieFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -15,18 +15,18 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.ViewItemListAdapter
|
||||
import com.nomadics9.ananas.bindItemImage
|
||||
import com.nomadics9.ananas.databinding.FragmentPersonDetailBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.viewmodels.PersonDetailViewModel
|
||||
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||
import dev.jdtech.jellyfin.bindItemImage
|
||||
import dev.jdtech.jellyfin.databinding.FragmentPersonDetailBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.viewmodels.PersonDetailViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
internal class PersonDetailFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -13,15 +13,15 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.FavoritesListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentSearchResultBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.viewmodels.SearchResultViewModel
|
||||
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentSearchResultBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.viewmodels.SearchResultViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
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.view.LayoutInflater
|
||||
|
@ -12,12 +12,12 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.ServerAddressAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentServerAddressesBinding
|
||||
import com.nomadics9.ananas.dialogs.AddServerAddressDialog
|
||||
import com.nomadics9.ananas.dialogs.DeleteServerAddressDialog
|
||||
import com.nomadics9.ananas.viewmodels.ServerAddressesEvent
|
||||
import com.nomadics9.ananas.viewmodels.ServerAddressesViewModel
|
||||
import dev.jdtech.jellyfin.adapters.ServerAddressAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentServerAddressesBinding
|
||||
import dev.jdtech.jellyfin.dialogs.AddServerAddressDialog
|
||||
import dev.jdtech.jellyfin.dialogs.DeleteServerAddressDialog
|
||||
import dev.jdtech.jellyfin.viewmodels.ServerAddressesEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.ServerAddressesViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -11,11 +11,11 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.adapters.ServerGridAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentServerSelectBinding
|
||||
import com.nomadics9.ananas.dialogs.DeleteServerDialogFragment
|
||||
import com.nomadics9.ananas.viewmodels.ServerSelectEvent
|
||||
import com.nomadics9.ananas.viewmodels.ServerSelectViewModel
|
||||
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentServerSelectBinding
|
||||
import dev.jdtech.jellyfin.dialogs.DeleteServerDialogFragment
|
||||
import dev.jdtech.jellyfin.viewmodels.ServerSelectEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.ServerSelectViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class SettingsAppearanceFragment : PreferenceFragmentCompat() {
|
||||
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.text.InputType
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class SettingsCacheFragment : PreferenceFragmentCompat() {
|
||||
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 androidx.fragment.app.viewModels
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.viewmodels.SettingsDeviceViewModel
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.viewmodels.SettingsDeviceViewModel
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SettingsDeviceFragment : PreferenceFragmentCompat() {
|
|
@ -1,8 +1,8 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class SettingsDownloadsFragment : PreferenceFragmentCompat() {
|
||||
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.net.Uri
|
||||
|
@ -7,7 +7,7 @@ import android.os.Bundle
|
|||
import android.provider.Settings
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class SettingsLanguageFragment : PreferenceFragmentCompat() {
|
||||
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.text.InputType
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.nomadics9.ananas.Constants
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.Constants
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class SettingsNetworkFragment : PreferenceFragmentCompat() {
|
||||
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.os.Bundle
|
||||
|
@ -7,7 +7,7 @@ import android.text.InputType
|
|||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
class SettingsPlayerFragment : PreferenceFragmentCompat() {
|
||||
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.net.Uri
|
||||
|
@ -18,29 +18,29 @@ import androidx.navigation.fragment.findNavController
|
|||
import androidx.navigation.fragment.navArgs
|
||||
import com.google.android.material.R
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.adapters.PersonListAdapter
|
||||
import com.nomadics9.ananas.adapters.ViewItemListAdapter
|
||||
import com.nomadics9.ananas.bindCardItemImage
|
||||
import com.nomadics9.ananas.bindItemBackdropImage
|
||||
import com.nomadics9.ananas.databinding.FragmentShowBinding
|
||||
import com.nomadics9.ananas.dialogs.ErrorDialogFragment
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidSeason
|
||||
import com.nomadics9.ananas.models.FindroidSourceType
|
||||
import com.nomadics9.ananas.models.PlayerItem
|
||||
import com.nomadics9.ananas.models.isDownloaded
|
||||
import com.nomadics9.ananas.utils.checkIfLoginRequired
|
||||
import com.nomadics9.ananas.utils.setIconTintColorAttribute
|
||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
||||
import com.nomadics9.ananas.viewmodels.ShowEvent
|
||||
import com.nomadics9.ananas.viewmodels.ShowViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
||||
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||
import dev.jdtech.jellyfin.bindCardItemImage
|
||||
import dev.jdtech.jellyfin.bindItemBackdropImage
|
||||
import dev.jdtech.jellyfin.databinding.FragmentShowBinding
|
||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidSeason
|
||||
import dev.jdtech.jellyfin.models.FindroidSourceType
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.models.isDownloaded
|
||||
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
|
||||
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||
import dev.jdtech.jellyfin.viewmodels.ShowEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.ShowViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ShowFragment : Fragment() {
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceHeaderFragmentCompat
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.fragments
|
||||
package dev.jdtech.jellyfin.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -12,12 +12,12 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.AppNavigationDirections
|
||||
import com.nomadics9.ananas.adapters.UserListAdapter
|
||||
import com.nomadics9.ananas.databinding.FragmentUsersBinding
|
||||
import com.nomadics9.ananas.dialogs.DeleteUserDialogFragment
|
||||
import com.nomadics9.ananas.viewmodels.UsersEvent
|
||||
import com.nomadics9.ananas.viewmodels.UsersViewModel
|
||||
import dev.jdtech.jellyfin.AppNavigationDirections
|
||||
import dev.jdtech.jellyfin.adapters.UserListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentUsersBinding
|
||||
import dev.jdtech.jellyfin.dialogs.DeleteUserDialogFragment
|
||||
import dev.jdtech.jellyfin.viewmodels.UsersEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.UsersViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
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.navigation.fragment.findNavController
|
||||
import com.nomadics9.ananas.AppNavigationDirections
|
||||
import dev.jdtech.jellyfin.AppNavigationDirections
|
||||
import timber.log.Timber
|
||||
|
||||
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.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
|
@ -20,20 +19,15 @@ import android.view.animation.DecelerateInterpolator
|
|||
import android.widget.ImageView
|
||||
import androidx.media3.ui.AspectRatioFrameLayout
|
||||
import androidx.media3.ui.PlayerView
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.nomadics9.ananas.AppPreferences
|
||||
import com.nomadics9.ananas.Constants
|
||||
import com.nomadics9.ananas.PlayerActivity
|
||||
import com.nomadics9.ananas.isControlsLocked
|
||||
import com.nomadics9.ananas.models.PlayerChapter
|
||||
import com.nomadics9.ananas.models.Trickplay
|
||||
import com.nomadics9.ananas.mpv.MPVPlayer
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.Constants
|
||||
import dev.jdtech.jellyfin.PlayerActivity
|
||||
import dev.jdtech.jellyfin.isControlsLocked
|
||||
import dev.jdtech.jellyfin.models.PlayerChapter
|
||||
import dev.jdtech.jellyfin.mpv.MPVPlayer
|
||||
import timber.log.Timber
|
||||
import kotlin.math.abs
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import coil.load
|
||||
|
||||
class PlayerGestureHelper(
|
||||
private val appPreferences: AppPreferences,
|
||||
private val activity: PlayerActivity,
|
||||
|
@ -68,10 +62,6 @@ class PlayerGestureHelper(
|
|||
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||
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 val tapGestureDetector = GestureDetector(
|
||||
|
@ -275,13 +265,6 @@ class PlayerGestureHelper(
|
|||
activity.binding.progressScrubberLayout.visibility = View.VISIBLE
|
||||
activity.binding.progressScrubberText.text = "${longToTimestamp(difference)} [${longToTimestamp(newPos, true)}]"
|
||||
swipeGestureValueTrackerProgress = newPos
|
||||
|
||||
if (currentTrickplay != null) {
|
||||
onMove(newPos)
|
||||
} else {
|
||||
activity.binding.imagePreviewGesture.visibility = View.GONE
|
||||
}
|
||||
|
||||
swipeGestureProgressOpen = true
|
||||
true
|
||||
} else {
|
||||
|
@ -488,28 +471,11 @@ class PlayerGestureHelper(
|
|||
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 {
|
||||
if (appPreferences.playerBrightnessRemember) {
|
||||
activity.window.attributes.screenBrightness = appPreferences.playerBrightness
|
||||
}
|
||||
|
||||
if (!appPreferences.playerTrickPlayGesture) {
|
||||
activity.binding.imagePreviewGesture.visibility = View.GONE
|
||||
}
|
||||
|
||||
updateZoomMode(appPreferences.playerStartMaximized)
|
||||
|
||||
@Suppress("ClickableViewAccessibility")
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas.utils
|
||||
package dev.jdtech.jellyfin.utils
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.view.View
|
||||
|
@ -8,7 +8,7 @@ import androidx.media3.common.Player
|
|||
import androidx.media3.ui.TimeBar
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.nomadics9.ananas.models.Trickplay
|
||||
import dev.jdtech.jellyfin.models.Trickplay
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import timber.log.Timber
|
||||
|
|
@ -37,16 +37,7 @@
|
|||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/main_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
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>
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
@ -40,17 +39,8 @@
|
|||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/main_toolbar"
|
||||
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>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -16,11 +16,8 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/progress_scrubber_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="64dp"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/overlay_background"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
|
@ -28,20 +25,10 @@
|
|||
android:visibility="gone"
|
||||
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
|
||||
android:id="@+id/progress_scrubber_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:textColor="@android:color/white"
|
||||
tools:text="+00:00:10 [00:00:20]" />
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center">
|
||||
|
||||
|
||||
<!-- Video surface will be inserted as the first child of the content frame. -->
|
||||
|
||||
<View
|
||||
|
@ -49,6 +48,24 @@
|
|||
android:textColor="@android:color/white"
|
||||
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.SubtitleView
|
||||
|
@ -72,33 +89,4 @@
|
|||
android:layout_height="match_parent"
|
||||
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>
|
|
@ -141,24 +141,10 @@
|
|||
android:visibility="invisible" />
|
||||
</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
|
||||
android:id="@+id/login_disclaimer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_margin="24dp"
|
||||
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
|
||||
android:id="@+id/homeFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.HomeFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.HomeFragment"
|
||||
android:label="@string/title_home"
|
||||
tools:layout="@layout/fragment_home">
|
||||
<action
|
||||
|
@ -49,14 +49,11 @@
|
|||
<action
|
||||
android:id="@+id/action_homeFragment_to_searchResultFragment"
|
||||
app:destination="@id/searchResultFragment" />
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_requestsWebFragment"
|
||||
app:destination="@id/requestsWebFragment" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/mediaFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.MediaFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.MediaFragment"
|
||||
android:label="@string/title_media"
|
||||
tools:layout="@layout/fragment_media">
|
||||
<action
|
||||
|
@ -73,7 +70,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/twoPaneSettingsFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.TwoPaneSettingsFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.TwoPaneSettingsFragment"
|
||||
android:label="@string/title_settings">
|
||||
<action
|
||||
android:id="@+id/action_navigation_settings_to_serverSelectFragment"
|
||||
|
@ -87,23 +84,13 @@
|
|||
<action
|
||||
android:id="@+id/action_settingsFragment_to_about_libraries"
|
||||
app:destination="@id/about_libraries" />
|
||||
<action
|
||||
android:id="@+id/action_navigation_settings_to_requestsWebFragment"
|
||||
app:destination="@id/requestsWebFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/settingsFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.SettingsFragment">
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/requestsWebFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.RequestsWebViewFragment"
|
||||
android:label="Requests"
|
||||
tools:layout="@layout/fragment_webview">
|
||||
</fragment>
|
||||
android:name="dev.jdtech.jellyfin.fragments.SettingsFragment" />
|
||||
<fragment
|
||||
android:id="@+id/libraryFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.LibraryFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.LibraryFragment"
|
||||
android:label="{libraryName}"
|
||||
tools:layout="@layout/fragment_library">
|
||||
<argument
|
||||
|
@ -135,14 +122,14 @@
|
|||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<argument
|
||||
android:name="libraryType"
|
||||
app:argType="com.nomadics9.ananas.models.CollectionType" />
|
||||
app:argType="dev.jdtech.jellyfin.models.CollectionType" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_self"
|
||||
app:destination="@id/libraryFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/showFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.ShowFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.ShowFragment"
|
||||
android:label="{itemName}"
|
||||
tools:layout="@layout/fragment_show">
|
||||
<argument
|
||||
|
@ -171,7 +158,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/movieFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.MovieFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.MovieFragment"
|
||||
android:label="{itemName}"
|
||||
tools:layout="@layout/fragment_movie">
|
||||
<argument
|
||||
|
@ -192,7 +179,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/seasonFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.SeasonFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.SeasonFragment"
|
||||
android:label="{seasonName}"
|
||||
tools:layout="@layout/fragment_season">
|
||||
<argument
|
||||
|
@ -224,7 +211,7 @@
|
|||
</fragment>
|
||||
<dialog
|
||||
android:id="@+id/episodeBottomSheetFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.EpisodeBottomSheetFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.EpisodeBottomSheetFragment"
|
||||
android:label="EpisodeBottomSheetFragment"
|
||||
tools:layout="@layout/episode_bottom_sheet">
|
||||
<argument
|
||||
|
@ -239,7 +226,7 @@
|
|||
</dialog>
|
||||
<fragment
|
||||
android:id="@+id/favoriteFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.FavoriteFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.FavoriteFragment"
|
||||
android:label="@string/title_favorite"
|
||||
tools:layout="@layout/fragment_favorite">
|
||||
<action
|
||||
|
@ -254,7 +241,7 @@
|
|||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/collectionFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.CollectionFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.CollectionFragment"
|
||||
android:label="{collectionName}"
|
||||
tools:layout="@layout/fragment_favorite">
|
||||
<argument
|
||||
|
@ -277,7 +264,7 @@
|
|||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/searchResultFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.SearchResultFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.SearchResultFragment"
|
||||
android:label="{query}"
|
||||
tools:layout="@layout/fragment_search_result">
|
||||
<action
|
||||
|
@ -295,7 +282,7 @@
|
|||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/addServerFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.AddServerFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.AddServerFragment"
|
||||
android:label="@string/add_server"
|
||||
tools:layout="@layout/fragment_add_server">
|
||||
<action
|
||||
|
@ -304,7 +291,7 @@
|
|||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/serverSelectFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.ServerSelectFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.ServerSelectFragment"
|
||||
android:label="@string/select_server"
|
||||
tools:layout="@layout/fragment_server_select">
|
||||
<action
|
||||
|
@ -321,7 +308,7 @@
|
|||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/loginFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.LoginFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.LoginFragment"
|
||||
android:label="@string/login"
|
||||
tools:layout="@layout/fragment_login">
|
||||
<action
|
||||
|
@ -337,7 +324,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/personDetailFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.PersonDetailFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.PersonDetailFragment"
|
||||
android:label="@string/person_detail_title"
|
||||
tools:layout="@layout/fragment_person_detail">
|
||||
|
||||
|
@ -355,12 +342,12 @@
|
|||
|
||||
<activity
|
||||
android:id="@+id/playerActivity"
|
||||
android:name="com.nomadics9.ananas.PlayerActivity"
|
||||
android:name="dev.jdtech.jellyfin.PlayerActivity"
|
||||
android:label="activity_player"
|
||||
tools:layout="@layout/activity_player">
|
||||
<argument
|
||||
android:name="items"
|
||||
app:argType="com.nomadics9.ananas.models.PlayerItem[]" />
|
||||
app:argType="dev.jdtech.jellyfin.models.PlayerItem[]" />
|
||||
</activity>
|
||||
|
||||
<include app:graph="@navigation/aboutlibs_navigation" />
|
||||
|
@ -370,7 +357,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/usersFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.UsersFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.UsersFragment"
|
||||
android:label="@string/users"
|
||||
tools:layout="@layout/fragment_users">
|
||||
<action
|
||||
|
@ -388,7 +375,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/serverAddressesFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.ServerAddressesFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.ServerAddressesFragment"
|
||||
android:label="@string/addresses"
|
||||
tools:layout="@layout/fragment_server_addresses">
|
||||
<action
|
||||
|
@ -403,7 +390,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/downloadsFragment"
|
||||
android:name="com.nomadics9.ananas.fragments.DownloadsFragment"
|
||||
android:name="dev.jdtech.jellyfin.fragments.DownloadsFragment"
|
||||
android:label="@string/title_download"
|
||||
tools:layout="@layout/fragment_favorite">
|
||||
<action
|
||||
|
@ -422,4 +409,4 @@
|
|||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
</fragment>
|
||||
|
||||
</navigation>
|
||||
</navigation>
|
|
@ -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 {
|
||||
namespace = "com.nomadics9.ananas"
|
||||
namespace = "dev.jdtech.jellyfin"
|
||||
compileSdk = Versions.compileSdk
|
||||
buildToolsVersion = Versions.buildTools
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.nomadics9.ananas"
|
||||
applicationId = "dev.jdtech.jellyfin"
|
||||
minSdk = Versions.minSdk
|
||||
targetSdk = Versions.targetSdk
|
||||
|
||||
|
@ -81,15 +81,14 @@ ktlint {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
val composeBom = platform(libs.androidx.compose.bom)
|
||||
|
||||
implementation(projects.core)
|
||||
implementation(projects.data)
|
||||
implementation(projects.preferences)
|
||||
implementation(projects.player.core)
|
||||
implementation(projects.player.video)
|
||||
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.material3)
|
||||
implementation(libs.androidx.core)
|
||||
|
@ -99,7 +98,6 @@ dependencies {
|
|||
implementation(libs.androidx.media3.ui)
|
||||
implementation(libs.androidx.media3.session)
|
||||
implementation(libs.androidx.paging.compose)
|
||||
implementation(libs.androidx.tv.foundation)
|
||||
implementation(libs.androidx.tv.material)
|
||||
implementation(libs.coil.compose)
|
||||
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 coil.ImageLoader
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
|
@ -6,11 +6,11 @@ import androidx.activity.compose.setContent
|
|||
import androidx.activity.viewModels
|
||||
import com.ramcosta.composedestinations.DestinationsNavHost
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.database.ServerDatabaseDao
|
||||
import com.nomadics9.ananas.destinations.AddServerScreenDestination
|
||||
import com.nomadics9.ananas.destinations.LoginScreenDestination
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import com.nomadics9.ananas.viewmodels.MainViewModel
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import dev.jdtech.jellyfin.destinations.AddServerScreenDestination
|
||||
import dev.jdtech.jellyfin.destinations.LoginScreenDestination
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.viewmodels.MainViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
|
@ -1,4 +1,4 @@
|
|||
package com.nomadics9.ananas
|
||||
package dev.jdtech.jellyfin
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.WindowManager
|
||||
|
@ -9,11 +9,11 @@ import com.ramcosta.composedestinations.annotation.ActivityDestination
|
|||
import com.ramcosta.composedestinations.manualcomposablecalls.composable
|
||||
import com.ramcosta.composedestinations.scope.resultRecipient
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.nomadics9.ananas.destinations.PlayerActivityDestination
|
||||
import com.nomadics9.ananas.destinations.PlayerScreenDestination
|
||||
import com.nomadics9.ananas.models.PlayerItem
|
||||
import com.nomadics9.ananas.ui.PlayerScreen
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.destinations.PlayerActivityDestination
|
||||
import dev.jdtech.jellyfin.destinations.PlayerScreenDestination
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.ui.PlayerScreen
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
|
||||
data class PlayerActivityNavArgs(
|
||||
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.Column
|
||||
|
@ -38,13 +38,13 @@ import androidx.tv.material3.MaterialTheme
|
|||
import androidx.tv.material3.Text
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.nomadics9.ananas.destinations.LoginScreenDestination
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import com.nomadics9.ananas.ui.theme.spacings
|
||||
import com.nomadics9.ananas.utils.ObserveAsEvents
|
||||
import com.nomadics9.ananas.viewmodels.AddServerEvent
|
||||
import com.nomadics9.ananas.viewmodels.AddServerViewModel
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.destinations.LoginScreenDestination
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import dev.jdtech.jellyfin.utils.ObserveAsEvents
|
||||
import dev.jdtech.jellyfin.viewmodels.AddServerEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.AddServerViewModel
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@Destination
|
||||
@Composable
|
||||
|
@ -115,7 +115,7 @@ private fun AddServerScreenLayout(
|
|||
},
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
autoCorrect = false,
|
||||
autoCorrectEnabled = false,
|
||||
keyboardType = KeyboardType.Uri,
|
||||
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.PaddingValues
|
||||
|
@ -6,6 +6,9 @@ import androidx.compose.foundation.layout.Spacer
|
|||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
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.LaunchedEffect
|
||||
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.tooling.preview.Preview
|
||||
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.Text
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.nomadics9.ananas.destinations.MovieScreenDestination
|
||||
import com.nomadics9.ananas.destinations.PlayerActivityDestination
|
||||
import com.nomadics9.ananas.destinations.ShowScreenDestination
|
||||
import com.nomadics9.ananas.models.FindroidEpisode
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.models.HomeItem
|
||||
import com.nomadics9.ananas.ui.components.Direction
|
||||
import com.nomadics9.ananas.ui.components.ItemCard
|
||||
import com.nomadics9.ananas.ui.dummy.dummyHomeItems
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import com.nomadics9.ananas.ui.theme.spacings
|
||||
import com.nomadics9.ananas.utils.ObserveAsEvents
|
||||
import com.nomadics9.ananas.viewmodels.HomeViewModel
|
||||
import com.nomadics9.ananas.viewmodels.PlayerItemsEvent
|
||||
import com.nomadics9.ananas.viewmodels.PlayerViewModel
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.destinations.MovieScreenDestination
|
||||
import dev.jdtech.jellyfin.destinations.PlayerActivityDestination
|
||||
import dev.jdtech.jellyfin.destinations.ShowScreenDestination
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.models.HomeItem
|
||||
import dev.jdtech.jellyfin.ui.components.Direction
|
||||
import dev.jdtech.jellyfin.ui.components.ItemCard
|
||||
import dev.jdtech.jellyfin.ui.dummy.dummyHomeItems
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import dev.jdtech.jellyfin.utils.ObserveAsEvents
|
||||
import dev.jdtech.jellyfin.viewmodels.HomeViewModel
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@Destination
|
||||
@Composable
|
||||
|
@ -107,7 +107,7 @@ private fun HomeScreenLayout(
|
|||
}
|
||||
else -> Unit
|
||||
}
|
||||
TvLazyColumn(
|
||||
LazyColumn(
|
||||
contentPadding = PaddingValues(bottom = MaterialTheme.spacings.large),
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
@ -122,7 +122,7 @@ private fun HomeScreenLayout(
|
|||
modifier = Modifier.padding(start = MaterialTheme.spacings.large),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
||||
TvLazyRow(
|
||||
LazyRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.large),
|
||||
) {
|
||||
|
@ -145,7 +145,7 @@ private fun HomeScreenLayout(
|
|||
modifier = Modifier.padding(start = MaterialTheme.spacings.large),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
||||
TvLazyRow(
|
||||
LazyRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||
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.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.LaunchedEffect
|
||||
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.tooling.preview.Preview
|
||||
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 com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.nomadics9.ananas.destinations.LibraryScreenDestination
|
||||
import com.nomadics9.ananas.models.CollectionType
|
||||
import com.nomadics9.ananas.models.FindroidCollection
|
||||
import com.nomadics9.ananas.ui.components.Direction
|
||||
import com.nomadics9.ananas.ui.components.ItemCard
|
||||
import com.nomadics9.ananas.ui.dummy.dummyCollections
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import com.nomadics9.ananas.ui.theme.spacings
|
||||
import com.nomadics9.ananas.viewmodels.MediaViewModel
|
||||
import dev.jdtech.jellyfin.destinations.LibraryScreenDestination
|
||||
import dev.jdtech.jellyfin.models.CollectionType
|
||||
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||
import dev.jdtech.jellyfin.ui.components.Direction
|
||||
import dev.jdtech.jellyfin.ui.components.ItemCard
|
||||
import dev.jdtech.jellyfin.ui.dummy.dummyCollections
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import dev.jdtech.jellyfin.viewmodels.MediaViewModel
|
||||
import java.util.UUID
|
||||
|
||||
@Destination
|
||||
|
@ -72,8 +72,8 @@ private fun LibrariesScreenLayout(
|
|||
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
TvLazyVerticalGrid(
|
||||
columns = TvGridCells.Fixed(3),
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(3),
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.large),
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.large),
|
||||
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.PaddingValues
|
||||
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.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
|
@ -15,27 +18,24 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.paging.PagingData
|
||||
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.Text
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.nomadics9.ananas.destinations.LibraryScreenDestination
|
||||
import com.nomadics9.ananas.destinations.MovieScreenDestination
|
||||
import com.nomadics9.ananas.destinations.ShowScreenDestination
|
||||
import com.nomadics9.ananas.models.CollectionType
|
||||
import com.nomadics9.ananas.models.FindroidFolder
|
||||
import com.nomadics9.ananas.models.FindroidItem
|
||||
import com.nomadics9.ananas.models.FindroidMovie
|
||||
import com.nomadics9.ananas.models.FindroidShow
|
||||
import com.nomadics9.ananas.ui.components.Direction
|
||||
import com.nomadics9.ananas.ui.components.ItemCard
|
||||
import com.nomadics9.ananas.ui.dummy.dummyMovies
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import com.nomadics9.ananas.ui.theme.spacings
|
||||
import com.nomadics9.ananas.viewmodels.LibraryViewModel
|
||||
import dev.jdtech.jellyfin.destinations.LibraryScreenDestination
|
||||
import dev.jdtech.jellyfin.destinations.MovieScreenDestination
|
||||
import dev.jdtech.jellyfin.destinations.ShowScreenDestination
|
||||
import dev.jdtech.jellyfin.models.CollectionType
|
||||
import dev.jdtech.jellyfin.models.FindroidFolder
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||
import dev.jdtech.jellyfin.models.FindroidShow
|
||||
import dev.jdtech.jellyfin.ui.components.Direction
|
||||
import dev.jdtech.jellyfin.ui.components.ItemCard
|
||||
import dev.jdtech.jellyfin.ui.dummy.dummyMovies
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import dev.jdtech.jellyfin.viewmodels.LibraryViewModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import java.util.UUID
|
||||
|
@ -86,8 +86,8 @@ private fun LibraryScreenLayout(
|
|||
is LibraryViewModel.UiState.Loading -> Text(text = "LOADING")
|
||||
is LibraryViewModel.UiState.Normal -> {
|
||||
val items = uiState.items.collectAsLazyPagingItems()
|
||||
TvLazyVerticalGrid(
|
||||
columns = TvGridCells.Fixed(5),
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(5),
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacings.default),
|
||||
contentPadding = PaddingValues(horizontal = MaterialTheme.spacings.default * 2, vertical = MaterialTheme.spacings.large),
|
||||
|
@ -95,7 +95,7 @@ private fun LibraryScreenLayout(
|
|||
.fillMaxSize()
|
||||
.focusRequester(focusRequester),
|
||||
) {
|
||||
item(span = { TvGridItemSpan(this.maxLineSpan) }) {
|
||||
item(span = { GridItemSpan(this.maxLineSpan) }) {
|
||||
Text(
|
||||
text = libraryName,
|
||||
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.Column
|
||||
|
@ -41,15 +41,15 @@ import androidx.tv.material3.Text
|
|||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.ramcosta.composedestinations.navigation.popUpTo
|
||||
import com.nomadics9.ananas.NavGraphs
|
||||
import com.nomadics9.ananas.destinations.MainScreenDestination
|
||||
import com.nomadics9.ananas.models.UiText
|
||||
import com.nomadics9.ananas.ui.theme.FindroidTheme
|
||||
import com.nomadics9.ananas.ui.theme.spacings
|
||||
import com.nomadics9.ananas.utils.ObserveAsEvents
|
||||
import com.nomadics9.ananas.viewmodels.LoginEvent
|
||||
import com.nomadics9.ananas.viewmodels.LoginViewModel
|
||||
import com.nomadics9.ananas.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.NavGraphs
|
||||
import dev.jdtech.jellyfin.destinations.MainScreenDestination
|
||||
import dev.jdtech.jellyfin.models.UiText
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import dev.jdtech.jellyfin.utils.ObserveAsEvents
|
||||
import dev.jdtech.jellyfin.viewmodels.LoginEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.LoginViewModel
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
@Destination
|
||||
@Composable
|
||||
|
@ -152,7 +152,7 @@ private fun LoginScreenLayout(
|
|||
label = { Text(text = stringResource(id = CoreR.string.edit_text_username_hint)) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
autoCorrect = false,
|
||||
autoCorrectEnabled = false,
|
||||
keyboardType = KeyboardType.Text,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
|
@ -175,7 +175,7 @@ private fun LoginScreenLayout(
|
|||
label = { Text(text = stringResource(id = CoreR.string.edit_text_password_hint)) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
autoCorrect = false,
|
||||
autoCorrectEnabled = false,
|
||||
keyboardType = KeyboardType.Password,
|
||||
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