Create FireTV specific app variant (#1230)

## Description
Adds a variant of Wholphin targeted for the Amazon Fire TV App store.

### Related issues
See #1192 for more details

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Ray 2026-04-11 19:30:23 -04:00 committed by GitHub
parent 97e10f57ca
commit 287a7b0c69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 73 additions and 47 deletions

View file

@ -36,7 +36,7 @@ jobs:
ORG_GRADLE_PROJECT_WholphinExtensionsUsername: "${{ secrets.EXTENSIONS_USERNAME }}"
ORG_GRADLE_PROJECT_WholphinExtensionsPassword: "${{ secrets.EXTENSIONS_PASSWORD }}"
run: |
./gradlew clean assembleDefaultRelease bundleAppstoreRelease --no-daemon
./gradlew clean assembleDefaultRelease bundleAppstoreRelease bundleFiretvRelease --no-daemon
- name: Verify signatures
run: |

View file

@ -1,3 +1,4 @@
import com.android.build.api.dsl.ProductFlavor
import com.google.protobuf.gradle.id
import com.mikepenz.aboutlibraries.plugin.DuplicateMode
import com.mikepenz.aboutlibraries.plugin.DuplicateRule
@ -112,16 +113,34 @@ android {
}
flavorDimensions += "version"
productFlavors {
val featureLeanback = "leanback"
val featureUpdate = "UPDATING_ENABLED"
val featureDiscover = "DISCOVER_ENABLED"
fun ProductFlavor.setFeatureFlag(
name: String,
enabled: Boolean,
) {
this.buildConfigField("boolean", name, "Boolean.parseBoolean(\"${enabled}\")")
}
create("default") {
dimension = "version"
isDefault = true
manifestPlaceholders += mapOf("leanback" to false)
buildConfigField("boolean", "UPDATING_ENABLED", "true")
manifestPlaceholders += mapOf(featureLeanback to false)
setFeatureFlag(featureUpdate, true)
setFeatureFlag(featureDiscover, true)
}
create("appstore") {
dimension = "version"
manifestPlaceholders += mapOf("leanback" to true)
buildConfigField("boolean", "UPDATING_ENABLED", "false")
manifestPlaceholders += mapOf(featureLeanback to true)
setFeatureFlag(featureUpdate, false)
setFeatureFlag(featureDiscover, true)
}
create("firetv") {
dimension = "version"
manifestPlaceholders += mapOf(featureLeanback to true)
setFeatureFlag(featureUpdate, false)
setFeatureFlag(featureDiscover, false)
}
}
compileOptions {

View file

@ -5,6 +5,7 @@ import androidx.annotation.ArrayRes
import androidx.annotation.StringRes
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.github.damontecres.wholphin.BuildConfig
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.WholphinApplication
import com.github.damontecres.wholphin.services.UpdateChecker
@ -1085,10 +1086,12 @@ val basicPreferences =
PreferenceGroup(
title = R.string.more,
preferences =
listOf(
AppPreference.SeerrIntegration,
AppPreference.AdvancedSettings,
),
buildList {
if (BuildConfig.DISCOVER_ENABLED) {
add(AppPreference.SeerrIntegration)
}
add(AppPreference.AdvancedSettings)
},
),
)

View file

@ -1,5 +1,6 @@
package com.github.damontecres.wholphin.services
import com.github.damontecres.wholphin.BuildConfig
import com.github.damontecres.wholphin.api.seerr.SeerrApiClient
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
import com.github.damontecres.wholphin.ui.setup.seerr.createSeerrApiUrl
@ -19,7 +20,7 @@ class SeerrApi(
)
private set
val active: Boolean get() = api.baseUrl.isNotNullOrBlank()
val active: Boolean get() = api.baseUrl.isNotNullOrBlank() && BuildConfig.DISCOVER_ENABLED
fun update(
baseUrl: String,

View file

@ -4,6 +4,7 @@ import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.asFlow
import androidx.lifecycle.lifecycleScope
import com.github.damontecres.wholphin.BuildConfig
import com.github.damontecres.wholphin.api.seerr.SeerrApiClient
import com.github.damontecres.wholphin.api.seerr.model.AuthJellyfinPostRequest
import com.github.damontecres.wholphin.api.seerr.model.AuthLocalPostRequest
@ -292,44 +293,46 @@ class UserSwitchListener
launchIO {
homeSettingsService.loadCurrentSettings(user.id)
}
// Check for seerr server
launchIO {
seerrServerDao
.getUsersByJellyfinUser(user.rowId)
.lastOrNull()
?.let { seerrUser ->
val server =
seerrServerDao.getServer(seerrUser.serverId)?.server
if (server != null) {
Timber.i("Found a seerr user & server")
try {
seerrApi.update(server.url, seerrUser.credential)
val userConfig =
if (seerrUser.authMethod != SeerrAuthMethod.API_KEY) {
login(
seerrApi.api,
seerrUser.authMethod,
seerrUser.username,
seerrUser.password,
)
} else {
seerrApi.api.usersApi.authMeGet()
}
seerrServerRepository.set(
server,
seerrUser,
userConfig,
)
} catch (ex: Exception) {
Timber.w(
ex,
"Error logging into %s",
server.url,
)
seerrServerRepository.error(server, seerrUser, ex)
if (BuildConfig.DISCOVER_ENABLED) {
// Check for seerr server
launchIO {
seerrServerDao
.getUsersByJellyfinUser(user.rowId)
.lastOrNull()
?.let { seerrUser ->
val server =
seerrServerDao.getServer(seerrUser.serverId)?.server
if (server != null) {
Timber.i("Found a seerr user & server")
try {
seerrApi.update(server.url, seerrUser.credential)
val userConfig =
if (seerrUser.authMethod != SeerrAuthMethod.API_KEY) {
login(
seerrApi.api,
seerrUser.authMethod,
seerrUser.username,
seerrUser.password,
)
} else {
seerrApi.api.usersApi.authMeGet()
}
seerrServerRepository.set(
server,
seerrUser,
userConfig,
)
} catch (ex: Exception) {
Timber.w(
ex,
"Error logging into %s",
server.url,
)
seerrServerRepository.error(server, seerrUser, ex)
}
}
}
}
}
}
}
}

View file

@ -65,7 +65,7 @@ class UpdateChecker
private val NOTE_REGEX = Regex("<!-- app-note:(.+) -->")
const val ACTIVE = BuildConfig.UPDATING_ENABLED
val ACTIVE = BuildConfig.UPDATING_ENABLED
}
/**