From 069588c5e05727f66ea22e952331eeeccd6a6359 Mon Sep 17 00:00:00 2001 From: NuvioTV Dev Date: Thu, 11 Jun 2026 17:50:02 +0300 Subject: [PATCH 1/3] fix: Restore FEATURE_PLUGINS_ENABLED, compileSdk=36, and sideload plugin dependencies --- app/build.gradle.kts | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1801aa64..2c4eaf44 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ plugins { android { namespace = "com.arflix.tv" - compileSdk = 35 + compileSdk = 36 flavorDimensions += "distribution" @@ -54,10 +54,12 @@ android { create("play") { dimension = "distribution" buildConfigField("Boolean", "SELF_UPDATE_ENABLED", "false") + buildConfigField("Boolean", "FEATURE_PLUGINS_ENABLED", "false") } create("sideload") { dimension = "distribution" buildConfigField("Boolean", "SELF_UPDATE_ENABLED", "true") + buildConfigField("Boolean", "FEATURE_PLUGINS_ENABLED", "true") } } @@ -439,3 +441,31 @@ detekt { } +kotlin { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) + freeCompilerArgs.add("-Xskip-metadata-version-check") + } +} + +dependencies { + ksp("org.jetbrains.kotlin:kotlin-metadata-jvm:2.3.0") + annotationProcessor("org.jetbrains.kotlin:kotlin-metadata-jvm:2.3.0") + + // Plugin system dependencies (Sideload flavor only) + add("sideloadImplementation", files("libs/quickjs-kt-android-1.0.5-nuvio.aar")) + add("sideloadImplementation", "com.fasterxml.jackson.core:jackson-databind:2.17.0") + add("sideloadImplementation", "com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0") + add("sideloadImplementation", "com.github.Blatzar:NiceHttp:0.4.11") + add("sideloadImplementation", "org.conscrypt:conscrypt-android:2.5.3") + add("sideloadImplementation", "com.github.recloudstream.cloudstream:library:v4.7.0") { + exclude(group = "org.mozilla", module = "rhino") + } + add("sideloadImplementation", "org.webjars.npm:crypto-js:4.2.0") + + // Runtime helpers used by the sideload plugin extractor stack. + add("sideloadImplementation", "org.mozilla:rhino:1.8.1") + add("sideloadImplementation", "com.google.re2j:re2j:1.8") +} + + From 685cb5ffaa2d8a83de7063629cab42531d0fd777 Mon Sep 17 00:00:00 2001 From: NuvioTV Dev Date: Thu, 11 Jun 2026 18:21:37 +0300 Subject: [PATCH 2/3] fix: Resolve CI build failures and sideload Kotlin compilation --- app/build.gradle.kts | 2 +- config/detekt/baseline.xml | 8 + config/detekt/detekt.yml | 479 +++++++++++++++++++++++++++++++++++++ 3 files changed, 488 insertions(+), 1 deletion(-) create mode 100644 config/detekt/baseline.xml create mode 100644 config/detekt/detekt.yml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2c4eaf44..c971c429 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -458,7 +458,7 @@ dependencies { add("sideloadImplementation", "com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0") add("sideloadImplementation", "com.github.Blatzar:NiceHttp:0.4.11") add("sideloadImplementation", "org.conscrypt:conscrypt-android:2.5.3") - add("sideloadImplementation", "com.github.recloudstream.cloudstream:library:v4.7.0") { + add("sideloadImplementation", "com.github.recloudstream.cloudstream:library-android:v4.7.0") { exclude(group = "org.mozilla", module = "rhino") } add("sideloadImplementation", "org.webjars.npm:crypto-js:4.2.0") diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml new file mode 100644 index 00000000..3860195d --- /dev/null +++ b/config/detekt/baseline.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml new file mode 100644 index 00000000..3d396fbf --- /dev/null +++ b/config/detekt/detekt.yml @@ -0,0 +1,479 @@ +# Detekt Configuration for Arflix TV +# https://detekt.dev/docs/rules/ + +build: + maxIssues: 0 + excludeCorrectable: false + +config: + validation: true + warningsAsErrors: false + +processors: + active: true + exclude: + - 'DetektProgressListener' + +console-reports: + active: true + exclude: + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' + +output-reports: + active: true + exclude: [] + +comments: + active: true + CommentOverPrivateProperty: + active: false + UndocumentedPublicClass: + active: false # Too strict for TV app + UndocumentedPublicFunction: + active: false # Too strict for TV app + UndocumentedPublicProperty: + active: false + +complexity: + active: true + ComplexCondition: + active: true + threshold: 6 + ComplexMethod: + active: true + threshold: 20 # Relaxed for complex UI methods + ignoreSingleWhenExpression: true + ignoreSimpleWhenEntries: true + LargeClass: + active: true + threshold: 600 + LongMethod: + active: true + threshold: 80 # Relaxed for Compose functions + LongParameterList: + active: true + functionThreshold: 8 + constructorThreshold: 10 + ignoreDefaultParameters: true + ignoreAnnotated: + - 'Composable' + NestedBlockDepth: + active: true + threshold: 5 + TooManyFunctions: + active: true + thresholdInFiles: 30 + thresholdInClasses: 25 + thresholdInInterfaces: 15 + thresholdInObjects: 15 + thresholdInEnums: 10 + ignoreDeprecated: true + ignorePrivate: true + ignoreOverridden: true + +coroutines: + active: true + GlobalCoroutineUsage: + active: true + RedundantSuspendModifier: + active: true + SleepInsteadOfDelay: + active: true + SuspendFunWithFlowReturnType: + active: true + +empty-blocks: + active: true + EmptyCatchBlock: + active: true + allowedExceptionNameRegex: '_|(ignore|expected).*' + EmptyClassBlock: + active: true + EmptyDefaultConstructor: + active: true + EmptyDoWhileBlock: + active: true + EmptyElseBlock: + active: true + EmptyFinallyBlock: + active: true + EmptyForBlock: + active: true + EmptyFunctionBlock: + active: true + ignoreOverridden: true + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyTryBlock: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: true + InstanceOfCheckForException: + active: true + NotImplementedDeclaration: + active: true + PrintStackTrace: + active: true + RethrowCaughtException: + active: true + ReturnFromFinally: + active: true + SwallowedException: + active: true + ignoredExceptionTypes: + - 'InterruptedException' + - 'MalformedURLException' + - 'NumberFormatException' + - 'ParseException' + allowedExceptionNameRegex: '_|(ignore|expected).*' + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: true + excludes: + - '**/test/**' + - '**/androidTest/**' + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: true + exceptionNames: + - 'ArrayIndexOutOfBoundsException' + - 'Error' + - 'IllegalMonitorStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + allowedExceptionNameRegex: '_|(ignore|expected).*' + TooGenericExceptionThrown: + active: true + exceptionNames: + - 'Error' + - 'Exception' + - 'RuntimeException' + - 'Throwable' + +naming: + active: true + BooleanPropertyNaming: + active: true + allowedPattern: '^(is|has|are|can|should|was|will|do)' + ClassNaming: + active: true + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + EnumNaming: + active: true + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + FunctionMaxLength: + active: false + FunctionMinLength: + active: false + FunctionNaming: + active: true + functionPattern: '[a-z][a-zA-Z0-9]*' + ignoreAnnotated: + - 'Composable' # Compose functions often start with uppercase + FunctionParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + InvalidPackageDeclaration: + active: true + MatchingDeclarationName: + active: true + mustBeFirst: true + MemberNameEqualsClassName: + active: true + NoNameShadowing: + active: true + NonBooleanPropertyPrefixedWithIs: + active: true + ObjectPropertyNaming: + active: true + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '[a-z][A-Za-z0-9]*' + PackageNaming: + active: true + packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' + TopLevelPropertyNaming: + active: true + constantPattern: '[A-Z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[a-z][A-Za-z0-9]*' + VariableMaxLength: + active: false + VariableMinLength: + active: false + VariableNaming: + active: true + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '_?[a-z][A-Za-z0-9]*' + +performance: + active: true + ArrayPrimitive: + active: true + CouldBeSequence: + active: true + threshold: 3 + ForEachOnRange: + active: true + SpreadOperator: + active: true + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + CastToNullableType: + active: true + Deprecation: + active: false # Too noisy with Android APIs + DontDowncastCollectionTypes: + active: true + DoubleMutabilityForCollection: + active: true + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExplicitGarbageCollectionCall: + active: true + HasPlatformType: + active: true + IgnoredReturnValue: + active: true + ImplicitDefaultLocale: + active: true + ImplicitUnitReturnType: + active: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false # Common in Android + MapGetWithNotNullAssertionOperator: + active: true + MissingPackageDeclaration: + active: true + NullableToStringCall: + active: true + UnconditionalJumpStatementInLoop: + active: true + UnnecessaryNotNullOperator: + active: true + UnnecessarySafeCall: + active: true + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + UnsafeCast: + active: true + UselessPostfixExpression: + active: true + WrongEqualsTypeParameter: + active: true + +style: + active: true + AlsoCouldBeApply: + active: false + CanBeNonNullable: + active: true + CascadingCallWrapping: + active: false + ClassOrdering: + active: false + CollapsibleIfStatements: + active: true + DataClassContainsFunctions: + active: false + DataClassShouldBeImmutable: + active: true + DestructuringDeclarationWithTooManyEntries: + active: true + maxDestructuringEntries: 5 + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: false + ExplicitCollectionElementAccessMethod: + active: false + ExplicitItLambdaParameter: + active: true + ExpressionBodySyntax: + active: false + ForbiddenComment: + active: true + values: + - 'FIXME' + - 'STOPSHIP' + - 'TODO:' # Catch TODOs that should be tracked + allowedPatterns: 'TODO\\(.*\\)' # Allow TODO(name) format + ForbiddenImport: + active: false + ForbiddenMethodCall: + active: false + ForbiddenVoid: + active: true + FunctionOnlyReturningConstant: + active: true + ignoreOverridableFunction: true + ignoreAnnotated: + - 'Composable' + LoopWithTooManyJumpStatements: + active: true + maxJumpCount: 2 + MagicNumber: + active: false # Too strict for UI code + MandatoryBracesIfStatements: + active: false + MandatoryBracesLoops: + active: false + MaxLineLength: + active: true + maxLineLength: 140 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: true + MayBeConst: + active: true + ModifierOrder: + active: true + MultilineLambdaItParameter: + active: false + NestedClassesVisibility: + active: true + NewLineAtEndOfFile: + active: true + NoTabs: + active: true + NullableBooleanCheck: + active: true + ObjectLiteralToLambda: + active: true + OptionalAbstractKeyword: + active: true + OptionalUnit: + active: false + OptionalWhenBraces: + active: false + PreferToOverPairSyntax: + active: true + ProtectedMemberInFinalClass: + active: true + RedundantExplicitType: + active: false + RedundantHigherOrderMapUsage: + active: true + RedundantVisibilityModifierRule: + active: false + ReturnCount: + active: true + max: 4 + excludeLabeled: true + excludeReturnFromLambda: true + excludeGuardClauses: true + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: false + SpacingBetweenPackageAndImports: + active: true + ThrowsCount: + active: true + max: 3 + TrailingWhitespace: + active: true + TrimMultilineRawString: + active: true + UnderscoresInNumericLiterals: + active: true + acceptableLength: 5 + UnnecessaryAbstractClass: + active: true + UnnecessaryAnnotationUseSiteTarget: + active: false + UnnecessaryApply: + active: true + UnnecessaryBackticks: + active: true + UnnecessaryFilter: + active: true + UnnecessaryInheritance: + active: true + UnnecessaryInnerClass: + active: true + UnnecessaryLet: + active: true + UnnecessaryParentheses: + active: false + UntilInsteadOfRangeTo: + active: true + UnusedImports: + active: true + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: '(_|ignored|expected|serialVersionUID)' + UseArrayLiteralsInAnnotations: + active: true + UseCheckNotNull: + active: true + UseCheckOrError: + active: true + UseDataClass: + active: false + UseEmptyCounterpart: + active: true + UseIfEmptyOrIfBlank: + active: true + UseIfInsteadOfWhen: + active: false + UseIsNullOrEmpty: + active: true + UseOrEmpty: + active: true + UseRequire: + active: true + UseRequireNotNull: + active: true + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: true + VarCouldBeVal: + active: true + WildcardImport: + active: true + excludeImports: + - 'java.util.*' + - 'kotlinx.android.synthetic.*' From 840a6794c988d5d9d4b461d73fe4cebd6235cc1e Mon Sep 17 00:00:00 2001 From: NuvioTV Dev Date: Thu, 11 Jun 2026 18:26:53 +0300 Subject: [PATCH 3/3] fix: Exclude conflicting MANIFEST.MF --- app/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c971c429..f9f3f92c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -153,6 +153,7 @@ android { packaging { resources { + excludes += "/META-INF/versions/9/OSGI-INF/MANIFEST.MF" excludes += setOf( "/META-INF/{AL2.0,LGPL2.1}", "/META-INF/LICENSE*",