many changes and pacakges upgrades

This commit is contained in:
deniscerri 2026-01-19 22:25:02 +01:00
parent f51b7a84ef
commit af53794be2
No known key found for this signature in database
GPG key ID: 95C43D517D830350
75 changed files with 2148 additions and 494 deletions

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -0,0 +1,112 @@
kotlin version: 2.0.21
error message: java.lang.AbstractMethodError: Receiver class androidx.room.migration.bundle.FieldBundle$$serializer does not define or inherit an implementation of the resolved method 'abstract kotlinx.serialization.KSerializer[] typeParametersSerializers()' of interface kotlinx.serialization.internal.GeneratedSerializer.
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:40)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$typeParameterDescriptors$2.invoke(PluginGeneratedSerialDescriptor.kt:39)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.getTypeParameterDescriptors$kotlinx_serialization_core(PluginGeneratedSerialDescriptor.kt:39)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor$_hashCode$2.invoke(PluginGeneratedSerialDescriptor.kt:44)
at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.get_hashCode(PluginGeneratedSerialDescriptor.kt:44)
at kotlinx.serialization.internal.PluginGeneratedSerialDescriptor.hashCode(PluginGeneratedSerialDescriptor.kt:97)
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.get(SchemaCache.kt:37)
at kotlinx.serialization.json.internal.DescriptorSchemaCache.getOrPut(SchemaCache.kt:29)
at kotlinx.serialization.json.internal.JsonNamesMapKt.deserializationNamesMap(JsonNamesMap.kt:54)
at kotlinx.serialization.json.internal.JsonTreeDecoder.elementName(TreeJsonDecoder.kt:234)
at kotlinx.serialization.internal.NamedValueDecoder.getTag(Tagged.kt:328)
at kotlinx.serialization.json.internal.JsonTreeDecoder.decodeElementIndex(TreeJsonDecoder.kt:201)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at androidx.room.migration.bundle.FieldBundle$$serializer.deserialize(FieldBundle.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at androidx.room.migration.bundle.EntityBundle$$serializer.deserialize(EntityBundle.kt:25)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:77)
at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readPolymorphicJson(TreeJsonDecoder.kt:33)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:90)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:75)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at androidx.room.migration.bundle.DatabaseBundle$$serializer.deserialize(DatabaseBundle.kt:26)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at androidx.room.migration.bundle.SchemaBundle$$serializer.deserialize(SchemaBundle.jvm.kt:28)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at androidx.room.migration.bundle.SchemaBundle$Companion.deserialize(SchemaBundle.jvm.kt:56)
at androidx.room.vo.Database.exportSchema(Database.kt:110)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:129)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:134)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:320)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:318)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:430)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:318)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:75)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze$lambda$12(KotlinToJVMBytecodeCompiler.kt:373)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:364)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runFrontendAndGenerateIrUsingClassicFrontend(KotlinToJVMBytecodeCompiler.kt:195)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:106)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1555)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

View file

@ -3,9 +3,9 @@ plugins {
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
id 'com.google.devtools.ksp' id 'com.google.devtools.ksp'
id "org.jetbrains.kotlin.plugin.serialization" version "2.0.21" id "org.jetbrains.kotlin.plugin.serialization" version "2.3.0"
id "org.jetbrains.kotlin.plugin.parcelize" version "2.0.21" id "org.jetbrains.kotlin.plugin.parcelize" version "2.3.0"
id "org.jetbrains.kotlin.plugin.compose" version "2.0.21" id "org.jetbrains.kotlin.plugin.compose" version "2.3.0"
} }
def properties = new Properties() def properties = new Properties()
@ -25,7 +25,7 @@ if (isBeta) {
android { android {
namespace 'com.deniscerri.ytdl' namespace 'com.deniscerri.ytdl'
compileSdk 35 compileSdk = 36
try { try {
def propertiesFile = rootProject.file("keystore.properties") def propertiesFile = rootProject.file("keystore.properties")
@ -46,7 +46,7 @@ android {
defaultConfig { defaultConfig {
applicationId "com.deniscerri.ytdl" applicationId "com.deniscerri.ytdl"
minSdk 24 minSdk 24
targetSdk 35 targetSdk 36
versionCode versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild versionCode versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}${versionExt}" versionName "${versionMajor}.${versionMinor}.${versionPatch}${versionExt}"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -121,7 +121,7 @@ android {
} }
} }
composeOptions { composeOptions {
kotlinCompilerExtensionVersion composeVer kotlinCompilerExtensionVersion "1.10.1"
} }
dependenciesInfo { dependenciesInfo {
@ -158,72 +158,72 @@ dependencies {
implementation "io.github.junkfood02.youtubedl-android:ffmpeg:0.18.1" implementation "io.github.junkfood02.youtubedl-android:ffmpeg:0.18.1"
// implementation "io.github.junkfood02.youtubedl-android:aria2c:0.17.2" // implementation "io.github.junkfood02.youtubedl-android:aria2c:0.17.2"
implementation "androidx.appcompat:appcompat:$appCompatVer" implementation "androidx.appcompat:appcompat:1.7.1"
implementation "androidx.constraintlayout:constraintlayout:2.2.1" implementation "androidx.constraintlayout:constraintlayout:2.2.1"
implementation 'com.google.android.material:material:1.10.0' implementation 'com.google.android.material:material:1.10.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.4.0' implementation 'androidx.recyclerview:recyclerview:1.4.0'
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
implementation "androidx.navigation:navigation-fragment-ktx:$navVer" implementation "androidx.navigation:navigation-fragment-ktx:2.9.6"
implementation "androidx.navigation:navigation-ui-ktx:$navVer" implementation "androidx.navigation:navigation-ui-ktx:2.9.6"
implementation 'androidx.core:core-ktx:1.15.0' implementation 'androidx.core:core-ktx:1.17.0'
implementation 'androidx.test.ext:junit-ktx:1.2.1' implementation 'androidx.test.ext:junit-ktx:1.3.0'
implementation 'androidx.compose.ui:ui-android:1.7.8' implementation 'androidx.compose.ui:ui-android:1.10.1'
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
testImplementation "junit:junit:$junitVer" testImplementation "junit:junit:4.13.2"
androidTestImplementation "junit:junit:$junitVer" androidTestImplementation "junit:junit:4.13.2"
androidTestImplementation "androidx.test.ext:junit:$androidJunitVer" androidTestImplementation "androidx.test.ext:junit:1.3.0"
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer" androidTestImplementation "androidx.test.espresso:espresso-core:3.7.0"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.devbrackets.android:exomedia:5.1.0' implementation 'com.devbrackets.android:exomedia:5.2.0'
implementation("androidx.cardview:cardview:1.0.0") implementation("androidx.cardview:cardview:1.0.0")
implementation("com.squareup.picasso:picasso:2.71828") implementation("com.squareup.picasso:picasso:2.71828")
implementation("jp.wasabeef:picasso-transformations:2.4.0") implementation("jp.wasabeef:picasso-transformations:2.4.0")
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.2.0"
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.3.0' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.3.0'
implementation 'com.facebook.shimmer:shimmer:0.5.0' implementation 'com.facebook.shimmer:shimmer:0.5.0'
implementation "androidx.work:work-runtime-ktx:$workVer" implementation "androidx.work:work-runtime-ktx:2.11.0"
implementation "androidx.room:room-runtime:$roomVer" implementation "androidx.room:room-runtime:2.8.4"
implementation "androidx.room:room-ktx:$roomVer" implementation "androidx.room:room-ktx:2.8.4"
ksp "androidx.room:room-compiler:$roomVer" ksp "androidx.room:room-compiler:2.8.4"
implementation 'androidx.paging:paging-runtime-ktx:3.3.6' implementation 'androidx.paging:paging-runtime-ktx:3.3.6'
implementation "androidx.room:room-paging:$roomVer" implementation "androidx.room:room-paging:2.8.4"
androidTestImplementation "androidx.room:room-testing:$roomVer" androidTestImplementation "androidx.room:room-testing:2.8.4"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.7' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.10.0'
implementation "androidx.compose.runtime:runtime:$composeVer" implementation "androidx.compose.runtime:runtime:1.10.1"
androidTestImplementation 'com.google.truth:truth:1.1.5' androidTestImplementation 'com.google.truth:truth:1.4.5'
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVer" api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVer" api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2"
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.13.2'
implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.10" implementation "com.squareup.okhttp3:okhttp:5.3.2"
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0'
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4' implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.10.0"
implementation "com.neoutils.highlight:highlight-view:2.2.0" implementation "com.neoutils.highlight:highlight-view:2.3.0"
// For media playback using ExoPlayer // For media playback using ExoPlayer
implementation("androidx.media3:media3-exoplayer:$media3_version") implementation("androidx.media3:media3-exoplayer:1.9.0")
// For DASH playback support with ExoPlayer // For DASH playback support with ExoPlayer
implementation("androidx.media3:media3-exoplayer-dash:$media3_version") implementation("androidx.media3:media3-exoplayer-dash:1.9.0")
// For HLS playback support with ExoPlayer // For HLS playback support with ExoPlayer
implementation("androidx.media3:media3-exoplayer-hls:$media3_version") implementation("androidx.media3:media3-exoplayer-hls:1.9.0")
implementation("androidx.media3:media3-ui:$media3_version") implementation("androidx.media3:media3-ui:1.9.0")
// For RTSP playback support with ExoPlayer // For RTSP playback support with ExoPlayer
implementation("androidx.media3:media3-exoplayer-rtsp:$media3_version") implementation("androidx.media3:media3-exoplayer-rtsp:1.9.0")
implementation "com.anggrayudi:storage:1.5.5" implementation "com.anggrayudi:storage:1.5.5"
implementation 'me.zhanghai.android.fastscroll:library:1.3.0' implementation 'me.zhanghai.android.fastscroll:library:1.3.0'
implementation 'com.google.accompanist:accompanist-webview:0.30.1' implementation 'com.google.accompanist:accompanist-webview:0.36.0'
implementation 'androidx.compose.material3:material3-android:1.3.1' implementation 'androidx.compose.material3:material3-android:1.4.0'
implementation "io.noties.markwon:core:4.6.2" implementation "io.noties.markwon:core:4.6.2"
implementation("org.greenrobot:eventbus:3.3.1") implementation("org.greenrobot:eventbus:3.3.1")
implementation("com.github.teamnewpipe:newpipeextractor:0.24.8") implementation("com.github.teamnewpipe:newpipeextractor:v0.25.0")
} }

View file

@ -126,6 +126,8 @@
-dontwarn jdk.dynalink.linker.support.CompositeTypeBasedGuardingDynamicLinker -dontwarn jdk.dynalink.linker.support.CompositeTypeBasedGuardingDynamicLinker
-dontwarn jdk.dynalink.linker.support.Guards -dontwarn jdk.dynalink.linker.support.Guards
-dontwarn jdk.dynalink.support.ChainedCallSite -dontwarn jdk.dynalink.support.ChainedCallSite
-dontwarn com.google.re2j.Matcher
-dontwarn com.google.re2j.Pattern
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault -keepattributes RuntimeVisibleAnnotations,AnnotationDefault
-dontobfuscate -dontobfuscate

View file

@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 26, "version": 26,
"identityHash": "7b692ac1bf86bc716a36bc1c0bf9ff85", "identityHash": "02198e1008f0874d9f7367c178f2343e",
"entities": [ "entities": [
{ {
"tableName": "results", "tableName": "results",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `formats` TEXT NOT NULL, `urls` TEXT NOT NULL DEFAULT '', `chapters` TEXT, `playlistURL` TEXT DEFAULT '', `playlistIndex` INTEGER, `creationTime` INTEGER NOT NULL, `availableSubtitles` TEXT NOT NULL DEFAULT '[]')", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `formats` TEXT NOT NULL, `urls` TEXT NOT NULL DEFAULT '', `chapters` TEXT NOT NULL, `playlistURL` TEXT DEFAULT '', `playlistIndex` INTEGER, `creationTime` INTEGER NOT NULL, `availableSubtitles` TEXT NOT NULL DEFAULT '[]')",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -73,20 +73,18 @@
"fieldPath": "chapters", "fieldPath": "chapters",
"columnName": "chapters", "columnName": "chapters",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": true
}, },
{ {
"fieldPath": "playlistURL", "fieldPath": "playlistURL",
"columnName": "playlistURL", "columnName": "playlistURL",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false,
"defaultValue": "''" "defaultValue": "''"
}, },
{ {
"fieldPath": "playlistIndex", "fieldPath": "playlistIndex",
"columnName": "playlistIndex", "columnName": "playlistIndex",
"affinity": "INTEGER", "affinity": "INTEGER"
"notNull": false
}, },
{ {
"fieldPath": "creationTime", "fieldPath": "creationTime",
@ -107,9 +105,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "history", "tableName": "history",
@ -208,9 +204,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "downloads", "tableName": "downloads",
@ -356,21 +350,18 @@
{ {
"fieldPath": "logID", "fieldPath": "logID",
"columnName": "logID", "columnName": "logID",
"affinity": "INTEGER", "affinity": "INTEGER"
"notNull": false
}, },
{ {
"fieldPath": "playlistURL", "fieldPath": "playlistURL",
"columnName": "playlistURL", "columnName": "playlistURL",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false,
"defaultValue": "''" "defaultValue": "''"
}, },
{ {
"fieldPath": "playlistIndex", "fieldPath": "playlistIndex",
"columnName": "playlistIndex", "columnName": "playlistIndex",
"affinity": "INTEGER", "affinity": "INTEGER"
"notNull": false
}, },
{ {
"fieldPath": "incognito", "fieldPath": "incognito",
@ -398,9 +389,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "commandTemplates", "tableName": "commandTemplates",
@ -471,9 +460,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "searchHistory", "tableName": "searchHistory",
@ -497,9 +484,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "templateShortcuts", "tableName": "templateShortcuts",
@ -523,9 +508,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "cookies", "tableName": "cookies",
@ -567,9 +550,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "logs", "tableName": "logs",
@ -617,9 +598,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "terminalDownloads", "tableName": "terminalDownloads",
@ -641,7 +620,6 @@
"fieldPath": "log", "fieldPath": "log",
"columnName": "log", "columnName": "log",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false,
"defaultValue": "''" "defaultValue": "''"
} }
], ],
@ -650,9 +628,7 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
}, },
{ {
"tableName": "sources", "tableName": "sources",
@ -703,14 +679,12 @@
{ {
"fieldPath": "weeklyConfig", "fieldPath": "weeklyConfig",
"columnName": "weeklyConfig", "columnName": "weeklyConfig",
"affinity": "TEXT", "affinity": "TEXT"
"notNull": false
}, },
{ {
"fieldPath": "monthlyConfig", "fieldPath": "monthlyConfig",
"columnName": "monthlyConfig", "columnName": "monthlyConfig",
"affinity": "TEXT", "affinity": "TEXT"
"notNull": false
}, },
{ {
"fieldPath": "status", "fieldPath": "status",
@ -784,15 +758,12 @@
"columnNames": [ "columnNames": [
"id" "id"
] ]
}, }
"indices": [],
"foreignKeys": []
} }
], ],
"views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7b692ac1bf86bc716a36bc1c0bf9ff85')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '02198e1008f0874d9f7367c178f2343e')"
] ]
} }
} }

View file

@ -0,0 +1,768 @@
{
"formatVersion": 1,
"database": {
"version": 27,
"identityHash": "7b692ac1bf86bc716a36bc1c0bf9ff85",
"entities": [
{
"tableName": "results",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `formats` TEXT NOT NULL, `urls` TEXT NOT NULL DEFAULT '', `chapters` TEXT, `playlistURL` TEXT DEFAULT '', `playlistIndex` INTEGER, `creationTime` INTEGER NOT NULL, `availableSubtitles` TEXT NOT NULL DEFAULT '[]')",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumb",
"columnName": "thumb",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "website",
"columnName": "website",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "playlistTitle",
"columnName": "playlistTitle",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "formats",
"columnName": "formats",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "urls",
"columnName": "urls",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "chapters",
"columnName": "chapters",
"affinity": "TEXT"
},
{
"fieldPath": "playlistURL",
"columnName": "playlistURL",
"affinity": "TEXT",
"defaultValue": "''"
},
{
"fieldPath": "playlistIndex",
"columnName": "playlistIndex",
"affinity": "INTEGER"
},
{
"fieldPath": "creationTime",
"columnName": "creationTime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "availableSubtitles",
"columnName": "availableSubtitles",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "'[]'"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `time` INTEGER NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `format` TEXT NOT NULL, `filesize` INTEGER NOT NULL DEFAULT 0, `downloadId` INTEGER NOT NULL DEFAULT 0, `command` TEXT NOT NULL DEFAULT '')",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumb",
"columnName": "thumb",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "downloadPath",
"columnName": "downloadPath",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "website",
"columnName": "website",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "format",
"columnName": "format",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "filesize",
"columnName": "filesize",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "downloadId",
"columnName": "downloadId",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "command",
"columnName": "command",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "downloads",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `format` TEXT NOT NULL, `container` TEXT NOT NULL DEFAULT 'Default', `downloadSections` TEXT NOT NULL DEFAULT '', `allFormats` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `audioPreferences` TEXT NOT NULL, `videoPreferences` TEXT NOT NULL, `extraCommands` TEXT NOT NULL DEFAULT '', `customFileNameTemplate` TEXT NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `downloadStartTime` INTEGER NOT NULL DEFAULT 0, `logID` INTEGER, `playlistURL` TEXT DEFAULT '', `playlistIndex` INTEGER, `incognito` INTEGER NOT NULL DEFAULT 0, `availableSubtitles` TEXT NOT NULL DEFAULT '[]', `rowNumber` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumb",
"columnName": "thumb",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "format",
"columnName": "format",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "container",
"columnName": "container",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "'Default'"
},
{
"fieldPath": "downloadSections",
"columnName": "downloadSections",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "allFormats",
"columnName": "allFormats",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadPath",
"columnName": "downloadPath",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "website",
"columnName": "website",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadSize",
"columnName": "downloadSize",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "playlistTitle",
"columnName": "playlistTitle",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "audioPreferences",
"columnName": "audioPreferences",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "videoPreferences",
"columnName": "videoPreferences",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "extraCommands",
"columnName": "extraCommands",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "customFileNameTemplate",
"columnName": "customFileNameTemplate",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "SaveThumb",
"columnName": "SaveThumb",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "'Queued'"
},
{
"fieldPath": "downloadStartTime",
"columnName": "downloadStartTime",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "logID",
"columnName": "logID",
"affinity": "INTEGER"
},
{
"fieldPath": "playlistURL",
"columnName": "playlistURL",
"affinity": "TEXT",
"defaultValue": "''"
},
{
"fieldPath": "playlistIndex",
"columnName": "playlistIndex",
"affinity": "INTEGER"
},
{
"fieldPath": "incognito",
"columnName": "incognito",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "availableSubtitles",
"columnName": "availableSubtitles",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "'[]'"
},
{
"fieldPath": "rowNumber",
"columnName": "rowNumber",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "commandTemplates",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `useAsExtraCommand` INTEGER NOT NULL DEFAULT 0, `useAsExtraCommandAudio` INTEGER NOT NULL DEFAULT 1, `useAsExtraCommandVideo` INTEGER NOT NULL DEFAULT 1, `useAsExtraCommandDataFetching` INTEGER NOT NULL DEFAULT 0, `preferredCommandTemplate` INTEGER NOT NULL DEFAULT 0, `urlRegex` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "useAsExtraCommand",
"columnName": "useAsExtraCommand",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "useAsExtraCommandAudio",
"columnName": "useAsExtraCommandAudio",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "1"
},
{
"fieldPath": "useAsExtraCommandVideo",
"columnName": "useAsExtraCommandVideo",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "1"
},
{
"fieldPath": "useAsExtraCommandDataFetching",
"columnName": "useAsExtraCommandDataFetching",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "preferredCommandTemplate",
"columnName": "preferredCommandTemplate",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "urlRegex",
"columnName": "urlRegex",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "searchHistory",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `query` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "query",
"columnName": "query",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "templateShortcuts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `content` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "cookies",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `content` TEXT NOT NULL, `description` TEXT NOT NULL, `enabled` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "description",
"columnName": "description",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "enabled",
"columnName": "enabled",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "logs",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `format` TEXT NOT NULL, `downloadType` TEXT NOT NULL, `downloadTime` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "format",
"columnName": "format",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadType",
"columnName": "downloadType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadTime",
"columnName": "downloadTime",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "terminalDownloads",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `command` TEXT NOT NULL, `log` TEXT DEFAULT '')",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "command",
"columnName": "command",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "log",
"columnName": "log",
"affinity": "TEXT",
"defaultValue": "''"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "sources",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `downloadItemTemplate` TEXT NOT NULL, `everyNr` INTEGER NOT NULL, `everyCategory` TEXT NOT NULL, `everyTime` INTEGER NOT NULL, `weeklyConfig` TEXT, `monthlyConfig` TEXT, `status` TEXT NOT NULL, `startsTime` INTEGER NOT NULL, `endsDate` INTEGER NOT NULL DEFAULT 0, `endsAfterCount` INTEGER NOT NULL DEFAULT 0, `runCount` INTEGER NOT NULL DEFAULT 0, `getOnlyNewUploads` INTEGER NOT NULL DEFAULT 0, `retryMissingDownloads` INTEGER NOT NULL, `ignoredLinks` TEXT NOT NULL DEFAULT '[]', `alreadyProcessedLinks` TEXT NOT NULL, `syncWithSource` INTEGER NOT NULL DEFAULT 0)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadItemTemplate",
"columnName": "downloadItemTemplate",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "everyNr",
"columnName": "everyNr",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "everyCategory",
"columnName": "everyCategory",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "everyTime",
"columnName": "everyTime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "weeklyConfig",
"columnName": "weeklyConfig",
"affinity": "TEXT"
},
{
"fieldPath": "monthlyConfig",
"columnName": "monthlyConfig",
"affinity": "TEXT"
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "startsTime",
"columnName": "startsTime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "endsDate",
"columnName": "endsDate",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "endsAfterCount",
"columnName": "endsAfterCount",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "runCount",
"columnName": "runCount",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "getOnlyNewUploads",
"columnName": "getOnlyNewUploads",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "retryMissingDownloads",
"columnName": "retryMissingDownloads",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ignoredLinks",
"columnName": "ignoredLinks",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "'[]'"
},
{
"fieldPath": "alreadyProcessedLinks",
"columnName": "alreadyProcessedLinks",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "syncWithSource",
"columnName": "syncWithSource",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7b692ac1bf86bc716a36bc1c0bf9ff85')"
]
}
}

View file

@ -33,6 +33,7 @@ import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.anggrayudi.storage.file.getAbsolutePath import com.anggrayudi.storage.file.getAbsolutePath
import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.DBManager
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.CookieViewModel import com.deniscerri.ytdl.database.viewmodel.CookieViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -400,13 +401,13 @@ class MainActivity : BaseActivity() {
intent.getParcelableExtra(Intent.EXTRA_STREAM) intent.getParcelableExtra(Intent.EXTRA_STREAM)
} }
var downloadType = DownloadViewModel.Type.valueOf(preferences.getString("preferred_download_type", "video")!!) var downloadType = DownloadType.valueOf(preferences.getString("preferred_download_type", "video")!!)
if (preferences.getBoolean("quick_download", false) || downloadType == DownloadViewModel.Type.command) { if (preferences.getBoolean("quick_download", false) || downloadType == DownloadType.command) {
val docFile = DocumentFile.fromSingleUri(this, uri!!) val docFile = DocumentFile.fromSingleUri(this, uri!!)
if (docFile?.exists() == true){ if (docFile?.exists() == true){
val bundle = Bundle() val bundle = Bundle()
val path = docFile.getAbsolutePath(this) val path = docFile.getAbsolutePath(this)
if (downloadType == DownloadViewModel.Type.auto) { if (downloadType == DownloadType.auto) {
downloadType = downloadViewModel.getDownloadType(null, path) downloadType = downloadViewModel.getDownloadType(null, path)
} }

View file

@ -1,6 +1,8 @@
package com.deniscerri.ytdl.database package com.deniscerri.ytdl.database
import androidx.room.ProvidedTypeConverter
import androidx.room.TypeConverter import androidx.room.TypeConverter
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.AudioPreferences import com.deniscerri.ytdl.database.models.AudioPreferences
import com.deniscerri.ytdl.database.models.ChapterItem import com.deniscerri.ytdl.database.models.ChapterItem
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
@ -12,48 +14,52 @@ import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.google.gson.Gson import com.google.gson.Gson
@ProvidedTypeConverter
class Converters { class Converters {
@TypeConverter
fun stringToListOfFormats(value: String) = Gson().fromJson(value, Array<Format>::class.java).toMutableList() private val gson = Gson()
@TypeConverter
fun listOfFormatsToString(list: List<Format?>?) = Gson().toJson(list).toString()
@TypeConverter @TypeConverter
fun stringToListOfStrings(value: String) = Gson().fromJson(value, Array<String>::class.java).toList() fun stringToListOfFormats(value: String) = gson.fromJson(value, Array<Format>::class.java).toMutableList()
@TypeConverter
fun listOfFormatsToString(list: List<Format?>?) = gson.toJson(list).toString()
@TypeConverter @TypeConverter
fun listOfStringsToString(list: List<String>) = Gson().toJson(list).toString() fun stringToListOfStrings(value: String) = gson.fromJson(value, Array<String>::class.java).toList()
@TypeConverter @TypeConverter
fun formatToString(format: Format): String = Gson().toJson(format) fun listOfStringsToString(list: List<String>) = gson.toJson(list).toString()
@TypeConverter @TypeConverter
fun stringToFormat(string: String): Format = Gson().fromJson(string, Format::class.java) fun formatToString(format: Format): String = gson.toJson(format)
@TypeConverter
fun stringToFormat(string: String): Format = gson.fromJson(string, Format::class.java)
@TypeConverter @TypeConverter
fun typeToString(type: DownloadViewModel.Type) : String = type.toString() fun typeToString(type: DownloadType) : String = type.toString()
@TypeConverter @TypeConverter
fun stringToType(string: String) : DownloadViewModel.Type { fun stringToType(string: String) : DownloadType {
return when(string){ return when(string){
"audio" -> DownloadViewModel.Type.audio "audio" -> DownloadType.audio
"video" -> DownloadViewModel.Type.video "video" -> DownloadType.video
else -> DownloadViewModel.Type.command else -> DownloadType.command
} }
} }
@TypeConverter @TypeConverter
fun audioPreferencesToString(audioPreferences: AudioPreferences): String = Gson().toJson(audioPreferences) fun audioPreferencesToString(audioPreferences: AudioPreferences): String = gson.toJson(audioPreferences)
@TypeConverter @TypeConverter
fun stringToAudioPreferences(string: String): AudioPreferences = Gson().fromJson(string, AudioPreferences::class.java) fun stringToAudioPreferences(string: String): AudioPreferences = gson.fromJson(string, AudioPreferences::class.java)
@TypeConverter @TypeConverter
fun videoPreferencesToString(videoPreferences: VideoPreferences): String = Gson().toJson(videoPreferences) fun videoPreferencesToString(videoPreferences: VideoPreferences): String = gson.toJson(videoPreferences)
@TypeConverter @TypeConverter
fun stringToVideoPreferences(string: String): VideoPreferences = Gson().fromJson(string, VideoPreferences::class.java) fun stringToVideoPreferences(string: String): VideoPreferences = gson.fromJson(string, VideoPreferences::class.java)
@TypeConverter @TypeConverter
fun stringToListOfChapters(value: String?) = Gson().fromJson(value, Array<ChapterItem>::class.java).toMutableList() fun stringToListOfChapters(value: String?) = gson.fromJson(value, Array<ChapterItem>::class.java).toMutableList()
@TypeConverter @TypeConverter
fun listOfChaptersToString(list: List<ChapterItem?>?): String { fun listOfChaptersToString(list: List<ChapterItem?>?): String {
@ -68,24 +74,24 @@ class Converters {
} }
@TypeConverter @TypeConverter
fun stringToDownloadItem(s: String) = Gson().fromJson(s, DownloadItem::class.java) fun stringToDownloadItem(s: String) = gson.fromJson(s, DownloadItem::class.java)
@TypeConverter @TypeConverter
fun mutableListOfStringsToString(s: MutableList<String>) = Gson().toJson(s) fun mutableListOfStringsToString(s: MutableList<String>) = gson.toJson(s)
@TypeConverter @TypeConverter
fun stringtoMutableListofStrings(s: String) = Gson().fromJson(s, Array<String>::class.java).toMutableList() fun stringtoMutableListofStrings(s: String?) = gson.fromJson(s, Array<String>::class.java).toMutableList()
@TypeConverter @TypeConverter
fun observeSourcesWeeklyConfigToString(c: ObserveSourcesWeeklyConfig) = Gson().toJson(c) fun observeSourcesWeeklyConfigToString(c: ObserveSourcesWeeklyConfig) = gson.toJson(c)
@TypeConverter @TypeConverter
fun stringToObserveSourcesWeeklyConfig(s: String) = Gson().fromJson(s, ObserveSourcesWeeklyConfig::class.java) fun stringToObserveSourcesWeeklyConfig(s: String) = gson.fromJson(s, ObserveSourcesWeeklyConfig::class.java)
@TypeConverter @TypeConverter
fun observeSourcesMonthlyConfigToString(c: ObserveSourcesMonthlyConfig) = Gson().toJson(c) fun observeSourcesMonthlyConfigToString(c: ObserveSourcesMonthlyConfig) = gson.toJson(c)
@TypeConverter @TypeConverter
fun stringToObserveSourcesMonthlyConfig(s: String) = Gson().fromJson(s, ObserveSourcesMonthlyConfig::class.java) fun stringToObserveSourcesMonthlyConfig(s: String) = gson.fromJson(s, ObserveSourcesMonthlyConfig::class.java)
} }

View file

@ -41,7 +41,7 @@ import com.deniscerri.ytdl.database.models.TerminalItem
TerminalItem::class, TerminalItem::class,
ObserveSourcesItem::class ObserveSourcesItem::class
], ],
version = 26, version = 27,
autoMigrations = [ autoMigrations = [
AutoMigration (from = 1, to = 2), AutoMigration (from = 1, to = 2),
AutoMigration (from = 2, to = 3), AutoMigration (from = 2, to = 3),
@ -68,6 +68,7 @@ import com.deniscerri.ytdl.database.models.TerminalItem
//AutoMigration(from = 23, to = 24) MANUALLY HANDLED //AutoMigration(from = 23, to = 24) MANUALLY HANDLED
//AutoMigration(from = 24, to = 25) MANUALLY HANDLED //AutoMigration(from = 24, to = 25) MANUALLY HANDLED
//AutoMigration(from = 25, to = 26) MANUALLY HANDLED //AutoMigration(from = 25, to = 26) MANUALLY HANDLED
AutoMigration(from = 26, to = 27)
] ]
) )
abstract class DBManager : RoomDatabase(){ abstract class DBManager : RoomDatabase(){
@ -98,6 +99,7 @@ abstract class DBManager : RoomDatabase(){
DBManager::class.java, DBManager::class.java,
"YTDLnisDatabase" "YTDLnisDatabase"
) )
.addTypeConverter(Converters())
.addMigrations(*Migrations.migrationList) .addMigrations(*Migrations.migrationList)
.build() .build()
instance = dbInstance instance = dbInstance

View file

@ -6,6 +6,7 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Update import androidx.room.Update
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.HistoryItem import com.deniscerri.ytdl.database.models.HistoryItem
import com.deniscerri.ytdl.database.repository.HistoryRepository import com.deniscerri.ytdl.database.repository.HistoryRepository
@ -85,7 +86,7 @@ interface HistoryDao {
fun getAllHistoryByURL(url: String) : List<HistoryItem> fun getAllHistoryByURL(url: String) : List<HistoryItem>
@Query("SELECT * FROM history WHERE url=:url and type=:type") @Query("SELECT * FROM history WHERE url=:url and type=:type")
fun getAllHistoryByURLAndType(url: String, type: DownloadViewModel.Type) : List<HistoryItem> fun getAllHistoryByURLAndType(url: String, type: DownloadType) : List<HistoryItem>
@Query("SELECT * FROM history WHERE id in (:ids)") @Query("SELECT * FROM history WHERE id in (:ids)")
fun getAllHistoryByIDs(ids: List<Long>) : List<HistoryItem> fun getAllHistoryByIDs(ids: List<Long>) : List<HistoryItem>

View file

@ -33,7 +33,7 @@ interface ResultDao {
suspend fun insert(item: ResultItem) : Long suspend fun insert(item: ResultItem) : Long
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMultiple(items: List<ResultItem?>) : List<Long> suspend fun insertMultiple(items: List<ResultItem>) : List<Long>
@Transaction @Transaction
suspend fun insertMultipleNoDuplicates(items: List<ResultItem>) : List<Long> { suspend fun insertMultipleNoDuplicates(items: List<ResultItem>) : List<Long> {

View file

@ -0,0 +1,5 @@
package com.deniscerri.ytdl.database.enums
enum class DownloadType {
auto, audio, video, command
}

View file

@ -4,6 +4,7 @@ import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -17,7 +18,7 @@ data class DownloadItem(
var author: String, var author: String,
var thumb: String, var thumb: String,
var duration: String, var duration: String,
var type: DownloadViewModel.Type, var type: DownloadType,
var format: Format, var format: Format,
@ColumnInfo(defaultValue = "Default") @ColumnInfo(defaultValue = "Default")
var container: String, var container: String,

View file

@ -3,6 +3,7 @@ package com.deniscerri.ytdl.database.models
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@Entity(tableName = "downloads") @Entity(tableName = "downloads")
@ -20,6 +21,6 @@ data class DownloadItemConfigureMultiple(
var videoPreferences: VideoPreferences, var videoPreferences: VideoPreferences,
@ColumnInfo(defaultValue = "Queued") @ColumnInfo(defaultValue = "Queued")
var status: String, var status: String,
var type: DownloadViewModel.Type, var type: DownloadType,
var incognito: Boolean = false var incognito: Boolean = false
) )

View file

@ -3,6 +3,7 @@ package com.deniscerri.ytdl.database.models
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@Entity(tableName = "downloads") @Entity(tableName = "downloads")
@ -19,7 +20,7 @@ data class DownloadItemSimple(
@ColumnInfo(defaultValue = "Queued") @ColumnInfo(defaultValue = "Queued")
var status: String, var status: String,
var logID: Long?, var logID: Long?,
var type: DownloadViewModel.Type, var type: DownloadType,
@ColumnInfo(defaultValue = "0") @ColumnInfo(defaultValue = "0")
var downloadStartTime: Long, var downloadStartTime: Long,
var incognito: Boolean = false var incognito: Boolean = false

View file

@ -3,6 +3,7 @@ package com.deniscerri.ytdl.database.models
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@Entity(tableName = "history") @Entity(tableName = "history")
@ -14,7 +15,7 @@ data class HistoryItem(
val author: String, val author: String,
val duration: String, val duration: String,
val thumb: String, val thumb: String,
val type: DownloadViewModel.Type, val type: DownloadType,
val time: Long, val time: Long,
val downloadPath: List<String>, val downloadPath: List<String>,
val website: String, val website: String,

View file

@ -2,6 +2,7 @@ package com.deniscerri.ytdl.database.models
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@Entity(tableName = "logs") @Entity(tableName = "logs")
@ -11,6 +12,6 @@ data class LogItem(
var title: String, var title: String,
var content: String, var content: String,
var format: Format, var format: Format,
var downloadType: DownloadViewModel.Type, var downloadType: DownloadType,
var downloadTime: Long, var downloadTime: Long,
) )

View file

@ -18,10 +18,10 @@ data class ResultItem(
val thumb: String, val thumb: String,
val website: String, val website: String,
var playlistTitle: String, var playlistTitle: String,
var formats: MutableList<Format>, var formats: List<Format> = emptyList(),
@ColumnInfo(defaultValue = "") @ColumnInfo(defaultValue = "")
var urls: String, var urls: String,
var chapters: MutableList<ChapterItem>?, var chapters: List<ChapterItem>?,
@ColumnInfo(defaultValue = "") @ColumnInfo(defaultValue = "")
var playlistURL: String? = "", var playlistURL: String? = "",
@ColumnInfo(defaultValue = "") @ColumnInfo(defaultValue = "")

View file

@ -8,6 +8,7 @@ import androidx.paging.PagingSource
import androidx.paging.filter import androidx.paging.filter
import com.deniscerri.ytdl.database.DBManager.SORTING import com.deniscerri.ytdl.database.DBManager.SORTING
import com.deniscerri.ytdl.database.dao.HistoryDao import com.deniscerri.ytdl.database.dao.HistoryDao
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.HistoryItem import com.deniscerri.ytdl.database.models.HistoryItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel
@ -38,7 +39,7 @@ class HistoryRepository(private val historyDao: HistoryDao) {
return historyDao.getAllHistoryByURL(url) return historyDao.getAllHistoryByURL(url)
} }
fun getAllByURLAndType(url: String, type: DownloadViewModel.Type) : List<HistoryItem> { fun getAllByURLAndType(url: String, type: DownloadType) : List<HistoryItem> {
return historyDao.getAllHistoryByURLAndType(url, type) return historyDao.getAllHistoryByURLAndType(url, type)
} }

View file

@ -23,6 +23,7 @@ import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.DBManager
import com.deniscerri.ytdl.database.dao.CommandTemplateDao import com.deniscerri.ytdl.database.dao.CommandTemplateDao
import com.deniscerri.ytdl.database.dao.DownloadDao import com.deniscerri.ytdl.database.dao.DownloadDao
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.AudioPreferences import com.deniscerri.ytdl.database.models.AudioPreferences
import com.deniscerri.ytdl.database.models.CommandTemplate import com.deniscerri.ytdl.database.models.CommandTemplate
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
@ -115,10 +116,6 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
private val historyRepository: HistoryRepository private val historyRepository: HistoryRepository
private val resultRepository: ResultRepository private val resultRepository: ResultRepository
enum class Type {
auto, audio, video, command
}
private val urlsForAudioType = listOf( private val urlsForAudioType = listOf(
"music", "music",
"audio", "audio",
@ -234,25 +231,25 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
return historyRepository.getItem(id) return historyRepository.getItem(id)
} }
fun getDownloadType(t: Type? = null, url: String) : Type { fun getDownloadType(t: DownloadType? = null, url: String) : DownloadType {
var type = t var type = t
if (type == null){ if (type == null){
val preferredDownloadType = sharedPreferences.getString("preferred_download_type", Type.auto.toString()) val preferredDownloadType = sharedPreferences.getString("preferred_download_type", DownloadType.auto.toString())
type = if (sharedPreferences.getBoolean("remember_download_type", false)){ type = if (sharedPreferences.getBoolean("remember_download_type", false)){
Type.valueOf(sharedPreferences.getString("last_used_download_type", DownloadType.valueOf(sharedPreferences.getString("last_used_download_type",
preferredDownloadType)!!) preferredDownloadType)!!)
}else{ }else{
Type.valueOf(preferredDownloadType!!) DownloadType.valueOf(preferredDownloadType!!)
} }
} }
return when(type){ return when(type){
Type.auto -> { DownloadType.auto -> {
if (urlsForAudioType.any { url.contains(it) }){ if (urlsForAudioType.any { url.contains(it) }){
Type.audio DownloadType.audio
}else{ }else{
Type.video DownloadType.video
} }
} }
@ -260,7 +257,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
} }
} }
fun createDownloadItemFromResult(result: ResultItem?, url: String = "", givenType: Type) : DownloadItem { fun createDownloadItemFromResult(result: ResultItem?, url: String = "", givenType: DownloadType) : DownloadItem {
val resultItem = result ?: createEmptyResultItem(url) val resultItem = result ?: createEmptyResultItem(url)
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false) val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
@ -274,22 +271,22 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
val cropThumb = sharedPreferences.getBoolean("crop_thumbnail", false) val cropThumb = sharedPreferences.getBoolean("crop_thumbnail", false)
var type = getDownloadType(givenType, resultItem.url) var type = getDownloadType(givenType, resultItem.url)
if(type == Type.command && commandTemplateDao.getTotalNumber() == 0) type = Type.video if(type == DownloadType.command && commandTemplateDao.getTotalNumber() == 0) type = DownloadType.video
val customFileNameTemplate = when(type) { val customFileNameTemplate = when(type) {
Type.audio -> sharedPreferences.getString("file_name_template_audio", "%(uploader).30B - %(title).170B") DownloadType.audio -> sharedPreferences.getString("file_name_template_audio", "%(uploader).30B - %(title).170B")
Type.video -> sharedPreferences.getString("file_name_template", "%(uploader).30B - %(title).170B") DownloadType.video -> sharedPreferences.getString("file_name_template", "%(uploader).30B - %(title).170B")
else -> "" else -> ""
} }
val downloadPath = when(type){ val downloadPath = when(type){
Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath()) DownloadType.audio -> sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())
Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath()) DownloadType.video -> sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())
else -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath()) else -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())
} }
val container = when(type){ val container = when(type){
Type.audio -> sharedPreferences.getString("audio_format", "") DownloadType.audio -> sharedPreferences.getString("audio_format", "")
else -> sharedPreferences.getString("video_format", "") else -> sharedPreferences.getString("video_format", "")
} }
@ -316,8 +313,8 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
) )
val extraCommands = when(type){ val extraCommands = when(type){
Type.audio -> extraCommandsForAudio DownloadType.audio -> extraCommandsForAudio
Type.video -> extraCommandsForVideo DownloadType.video -> extraCommandsForVideo
else -> listOf() else -> listOf()
}.filter { }.filter {
it.urlRegex.isEmpty() || it.urlRegex.any { u -> it.urlRegex.isEmpty() || it.urlRegex.any { u ->
@ -335,7 +332,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
getFormat(resultItem.formats, type, resultItem.url), getFormat(resultItem.formats, type, resultItem.url),
container!!, container!!,
"", "",
resultItem.formats, resultItem.formats.toMutableList(),
downloadPath!!, resultItem.website, downloadPath!!, resultItem.website,
"", "",
if (resultItem.playlistTitle == resultRepository.YTDLNIS_SEARCH) "" else resultItem.playlistTitle, if (resultItem.playlistTitle == resultRepository.YTDLNIS_SEARCH) "" else resultItem.playlistTitle,
@ -412,7 +409,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
) )
} }
fun switchDownloadType(list: List<DownloadItem>, type: Type) : List<DownloadItem>{ fun switchDownloadType(list: List<DownloadItem>, type: DownloadType) : List<DownloadItem>{
list.forEach { list.forEach {
val format = getFormat(it.allFormats, type, it.url) val format = getFormat(it.allFormats, type, it.url)
@ -422,15 +419,15 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
var container = "" var container = ""
when(type){ when(type){
Type.audio -> { DownloadType.audio -> {
updatedDownloadPath = sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())!! updatedDownloadPath = sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())!!
container = sharedPreferences.getString("audio_format", "")!! container = sharedPreferences.getString("audio_format", "")!!
} }
Type.video -> { DownloadType.video -> {
updatedDownloadPath = sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())!! updatedDownloadPath = sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())!!
container = sharedPreferences.getString("video_format", "")!! container = sharedPreferences.getString("video_format", "")!!
} }
Type.command -> { DownloadType.command -> {
updatedDownloadPath = sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!! updatedDownloadPath = sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!!
container = "" container = ""
} }
@ -458,21 +455,21 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
val subsLanguages = sharedPreferences.getString("subs_lang", "en.*,.*-orig")!! val subsLanguages = sharedPreferences.getString("subs_lang", "en.*,.*-orig")!!
val customFileNameTemplate = when(historyItem.type) { val customFileNameTemplate = when(historyItem.type) {
Type.audio -> sharedPreferences.getString("file_name_template_audio", "%(uploader).30B - %(title).170B") DownloadType.audio -> sharedPreferences.getString("file_name_template_audio", "%(uploader).30B - %(title).170B")
Type.video -> sharedPreferences.getString("file_name_template", "%(uploader).30B - %(title).170B") DownloadType.video -> sharedPreferences.getString("file_name_template", "%(uploader).30B - %(title).170B")
else -> "" else -> ""
} }
val container = when(historyItem.type){ val container = when(historyItem.type){
Type.audio -> sharedPreferences.getString("audio_format", "Default")!! DownloadType.audio -> sharedPreferences.getString("audio_format", "Default")!!
Type.video -> sharedPreferences.getString("video_format", "Default")!! DownloadType.video -> sharedPreferences.getString("video_format", "Default")!!
else -> "" else -> ""
} }
val defaultPath = when(historyItem.type) { val defaultPath = when(historyItem.type) {
Type.audio -> FileUtil.getDefaultAudioPath() DownloadType.audio -> FileUtil.getDefaultAudioPath()
Type.video -> FileUtil.getDefaultVideoPath() DownloadType.video -> FileUtil.getDefaultVideoPath()
Type.command -> FileUtil.getDefaultCommandPath() DownloadType.command -> FileUtil.getDefaultCommandPath()
else -> "" else -> ""
} }
@ -480,8 +477,8 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
val audioBitrate = sharedPreferences.getString("audio_bitrate", "") val audioBitrate = sharedPreferences.getString("audio_bitrate", "")
val extraCommands = when (historyItem.type) { val extraCommands = when (historyItem.type) {
Type.audio -> extraCommandsForAudio DownloadType.audio -> extraCommandsForAudio
Type.video -> extraCommandsForVideo DownloadType.video -> extraCommandsForVideo
else -> listOf() else -> listOf()
}.filter { }.filter {
it.urlRegex.isEmpty() || it.urlRegex.any { u -> it.urlRegex.isEmpty() || it.urlRegex.any { u ->
@ -529,9 +526,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
} }
fun getFormat(formats: List<Format>, type: Type, url: String? = null) : Format { fun getFormat(formats: List<Format>, type: DownloadType, url: String? = null) : Format {
when(type) { when(type) {
Type.audio -> { DownloadType.audio -> {
return cloneFormat ( return cloneFormat (
try { try {
val theFormats = formats.filter { it.vcodec.isBlank() || it.vcodec == "none" }.ifEmpty { val theFormats = formats.filter { it.vcodec.isBlank() || it.vcodec == "none" }.ifEmpty {
@ -544,7 +541,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
) )
} }
Type.video -> { DownloadType.video -> {
return cloneFormat( return cloneFormat(
try { try {
val theFormats = formats.filter { it.vcodec.isNotBlank() && it.vcodec != "none" }.ifEmpty { val theFormats = formats.filter { it.vcodec.isNotBlank() && it.vcodec != "none" }.ifEmpty {
@ -602,7 +599,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
} }
} }
if (preferredAudioFormats.isEmpty()){ if (preferredAudioFormats.isEmpty()){
val audioF = getFormat(formats, Type.audio) val audioF = getFormat(formats, DownloadType.audio)
if (!formatUtil.getGenericAudioFormats(resources).contains(audioF)){ if (!formatUtil.getGenericAudioFormats(resources).contains(audioF)){
preferredAudioFormats.add(audioF.format_id) preferredAudioFormats.add(audioF.format_id)
} }
@ -697,7 +694,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
itemIDs.forEach { id -> itemIDs.forEach { id ->
val item = resultRepository.getItemByID(id) ?: return@forEach val item = resultRepository.getItemByID(id) ?: return@forEach
val preferredType = getDownloadType(url = item.url).toString() val preferredType = getDownloadType(url = item.url).toString()
val downloadItem = createDownloadItemFromResult(result = item, givenType = Type.valueOf( val downloadItem = createDownloadItemFromResult(result = item, givenType = DownloadType.valueOf(
preferredType preferredType
)) ))
downloadItem.status = DownloadRepository.Status.Processing.toString() downloadItem.status = DownloadRepository.Status.Processing.toString()
@ -1123,7 +1120,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
it.format = this it.format = this
} }
if (it.type == Type.video) { if (it.type == DownloadType.video) {
it.videoPreferences.audioFormatIDs.clear() it.videoPreferences.audioFormatIDs.clear()
ft.audioFormats?.map { a -> a.format_id }?.let { list -> ft.audioFormats?.map { a -> a.format_id }?.let { list ->
it.videoPreferences.audioFormatIDs.addAll(list) it.videoPreferences.audioFormatIDs.addAll(list)
@ -1187,8 +1184,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
runCatching { runCatching {
resultRepository.getAllByURL(item.url).forEach { resultRepository.getAllByURL(item.url).forEach {
it.formats.clear() it.formats = list
it.formats.addAll(list)
resultRepository.update(it) resultRepository.update(it)
} }
} }
@ -1205,8 +1201,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
kotlin.runCatching { kotlin.runCatching {
resultRepository.getAllByURL(url).forEach { resultRepository.getAllByURL(url).forEach {
it.formats.clear() it.formats = list
it.formats.addAll(list)
resultRepository.update(it) resultRepository.update(it)
} }
} }
@ -1264,7 +1259,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
} }
suspend fun updateProcessingType(selectedItems: List<Long>?, newType: Type) { suspend fun updateProcessingType(selectedItems: List<Long>?, newType: DownloadType) {
val processing = if (selectedItems.isNullOrEmpty()) { val processing = if (selectedItems.isNullOrEmpty()) {
repository.getAllProcessingDownloads() repository.getAllProcessingDownloads()
}else{ }else{
@ -1288,7 +1283,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
return queueDownloads(processing, ignoreDuplicates) return queueDownloads(processing, ignoreDuplicates)
} }
fun checkIfAllProcessingItemsHaveSameType(selectedItems: List<Long>?) : Pair<Boolean, Type> { fun checkIfAllProcessingItemsHaveSameType(selectedItems: List<Long>?) : Pair<Boolean, DownloadType> {
val types = if (!selectedItems.isNullOrEmpty()) { val types = if (!selectedItems.isNullOrEmpty()) {
dao.getProcessingDownloadTypesByIDs(selectedItems) dao.getProcessingDownloadTypesByIDs(selectedItems)
}else { }else {
@ -1296,10 +1291,10 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
} }
if (types.isEmpty()) { if (types.isEmpty()) {
return Pair(false, Type.command) return Pair(false, DownloadType.command)
} }
return Pair(types.size == 1, Type.valueOf(types.first())) return Pair(types.size == 1, DownloadType.valueOf(types.first()))
} }
fun checkIfAllProcessingItemsHaveSameContainer(checkedItems: List<Long>?) : Pair<Boolean, String> { fun checkIfAllProcessingItemsHaveSameContainer(checkedItems: List<Long>?) : Pair<Boolean, String> {

View file

@ -9,14 +9,13 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.DBManager
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.FormatRecyclerView import com.deniscerri.ytdl.database.models.FormatRecyclerView
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.ui.downloadcard.FormatSelectionBottomSheetDialog.FormatCategory import com.deniscerri.ytdl.ui.downloadcard.FormatSelectionBottomSheetDialog.FormatCategory
import com.deniscerri.ytdl.ui.downloadcard.FormatSelectionBottomSheetDialog.FormatSorting import com.deniscerri.ytdl.ui.downloadcard.FormatSelectionBottomSheetDialog.FormatSorting
import com.deniscerri.ytdl.ui.downloadcard.FormatTuple import com.deniscerri.ytdl.ui.downloadcard.FormatTuple
@ -94,7 +93,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
if (!isMissingFormats.value) { if (!isMissingFormats.value) {
chosenFormats = formats.mapTo(mutableListOf()) {it.copy()} chosenFormats = formats.mapTo(mutableListOf()) {it.copy()}
chosenFormats = when(items.first().type){ chosenFormats = when(items.first().type){
Type.audio -> chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) } DownloadType.audio -> chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) }
else -> chosenFormats else -> chosenFormats
} }
chosenFormats.forEach { chosenFormats.forEach {
@ -106,7 +105,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
}else{ }else{
chosenFormats = formats chosenFormats = formats
if(!isMissingFormats.value){ if(!isMissingFormats.value){
if(items.first().type == Type.audio){ if(items.first().type == DownloadType.audio){
chosenFormats = chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) } chosenFormats = chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) }
} }
} }
@ -126,7 +125,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
FormatSorting.container -> chosenFormats.groupBy { it.container }.flatMap { it.value } FormatSorting.container -> chosenFormats.groupBy { it.container }.flatMap { it.value }
FormatSorting.id -> chosenFormats.sortedBy { it.format_id } FormatSorting.id -> chosenFormats.sortedBy { it.format_id }
FormatSorting.codec -> { FormatSorting.codec -> {
val codecOrder = application.getStringArray(R.array.video_codec_values).toMutableList() val codecOrder = application.resources.getStringArray(R.array.video_codec_values).toMutableList()
codecOrder.removeAt(0) codecOrder.removeAt(0)
chosenFormats.groupBy { format -> codecOrder.indexOfFirst { format.vcodec.matches("^(${it})(.+)?$".toRegex()) } } chosenFormats.groupBy { format -> codecOrder.indexOfFirst { format.vcodec.matches("^(${it})(.+)?$".toRegex()) } }
@ -141,7 +140,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
when(filterBy.value){ when(filterBy.value){
FormatCategory.ALL -> {} FormatCategory.ALL -> {}
FormatCategory.SUGGESTED -> { FormatCategory.SUGGESTED -> {
finalFormats = if (items.first().type == Type.audio){ finalFormats = if (items.first().type == DownloadType.audio){
formatUtil.sortAudioFormats(finalFormats) formatUtil.sortAudioFormats(finalFormats)
}else{ }else{
val audioFormats = finalFormats.filter { it.vcodec.isBlank() || it.vcodec == "none" } val audioFormats = finalFormats.filter { it.vcodec.isBlank() || it.vcodec == "none" }
@ -182,13 +181,13 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
} }
canMultiSelectAudio.apply { canMultiSelectAudio.apply {
val vl = items.first().type == Type.video && finalFormats.find { it.vcodec.isBlank() || it.vcodec == "none" } != null val vl = items.first().type == DownloadType.video && finalFormats.find { it.vcodec.isBlank() || it.vcodec == "none" } != null
value = vl value = vl
emit(vl) emit(vl)
} }
if (finalFormats.isEmpty()) { if (finalFormats.isEmpty()) {
finalFormats = if (items.first().type == Type.audio){ finalFormats = if (items.first().type == DownloadType.audio){
genericAudioFormats genericAudioFormats
}else{ }else{
genericVideoFormats genericVideoFormats

View file

@ -34,6 +34,7 @@ import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.viewmodel.CookieViewModel import com.deniscerri.ytdl.database.viewmodel.CookieViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -193,7 +194,7 @@ class ShareActivity : BaseActivity() {
result = existingResults.first() result = existingResults.first()
} }
val downloadType = DownloadViewModel.Type.valueOf(type ?: downloadViewModel.getDownloadType(url = result.url).toString()) val downloadType = DownloadType.valueOf(type ?: downloadViewModel.getDownloadType(url = result.url).toString())
if (sharedPreferences.getBoolean("download_card", true) && !background){ if (sharedPreferences.getBoolean("download_card", true) && !background){
val bundle = Bundle() val bundle = Bundle()
bundle.putParcelable("result", result) bundle.putParcelable("result", result)

View file

@ -34,6 +34,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.models.SearchSuggestionItem import com.deniscerri.ytdl.database.models.SearchSuggestionItem
import com.deniscerri.ytdl.database.models.SearchSuggestionType import com.deniscerri.ytdl.database.models.SearchSuggestionType
@ -202,7 +203,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, SearchSuggesti
if(it.size == 1 && quickLaunchSheet && parentFragmentManager.findFragmentByTag("downloadSingleSheet") == null){ if(it.size == 1 && quickLaunchSheet && parentFragmentManager.findFragmentByTag("downloadSingleSheet") == null){
showSingleDownloadSheet( showSingleDownloadSheet(
it[0], it[0],
DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!) DownloadType.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
) )
} }
} }
@ -277,14 +278,14 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, SearchSuggesti
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
showSingleDownloadSheet( showSingleDownloadSheet(
resultItem = downloadViewModel.createEmptyResultItem(queryList.first()), resultItem = downloadViewModel.createEmptyResultItem(queryList.first()),
type = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!), type = DownloadType.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!),
disableUpdateData = true disableUpdateData = true
) )
} }
} else { } else {
val downloadItem = downloadViewModel.createDownloadItemFromResult( val downloadItem = downloadViewModel.createDownloadItemFromResult(
result = downloadViewModel.createEmptyResultItem(queryList.first()), result = downloadViewModel.createEmptyResultItem(queryList.first()),
givenType = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!) givenType = DownloadType.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
) )
downloadViewModel.queueDownloads(listOf(downloadItem)) downloadViewModel.queueDownloads(listOf(downloadItem))
} }
@ -691,13 +692,13 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, SearchSuggesti
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
showSingleDownloadSheet( showSingleDownloadSheet(
resultItem = downloadViewModel.createEmptyResultItem(queryList.first()), resultItem = downloadViewModel.createEmptyResultItem(queryList.first()),
type = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!) type = DownloadType.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
) )
} }
} else { } else {
val downloadItem = downloadViewModel.createDownloadItemFromResult( val downloadItem = downloadViewModel.createDownloadItemFromResult(
result = downloadViewModel.createEmptyResultItem(queryList.first()), result = downloadViewModel.createEmptyResultItem(queryList.first()),
givenType = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!) givenType = DownloadType.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
) )
downloadViewModel.queueDownloads(listOf(downloadItem)) downloadViewModel.queueDownloads(listOf(downloadItem))
} }
@ -717,7 +718,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, SearchSuggesti
} }
@SuppressLint("ResourceType") @SuppressLint("ResourceType")
override fun onButtonClick(videoURL: String, type: DownloadViewModel.Type?) { override fun onButtonClick(videoURL: String, type: DownloadType?) {
Log.e(TAG, type.toString() + " " + videoURL) Log.e(TAG, type.toString() + " " + videoURL)
val item = resultsList!!.find { it?.url == videoURL } val item = resultsList!!.find { it?.url == videoURL }
Log.e(TAG, resultsList!![0].toString() + " " + videoURL) Log.e(TAG, resultsList!![0].toString() + " " + videoURL)
@ -736,7 +737,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, SearchSuggesti
} }
} }
override fun onLongButtonClick(videoURL: String, type: DownloadViewModel.Type?) { override fun onLongButtonClick(videoURL: String, type: DownloadType?) {
Log.e(TAG, type.toString() + " " + videoURL) Log.e(TAG, type.toString() + " " + videoURL)
val item = resultsList!!.find { it?.url == videoURL } val item = resultsList!!.find { it?.url == videoURL }
showSingleDownloadSheet(item!!, type!!) showSingleDownloadSheet(item!!, type!!)
@ -745,7 +746,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, SearchSuggesti
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
private fun showSingleDownloadSheet( private fun showSingleDownloadSheet(
resultItem: ResultItem, resultItem: ResultItem,
type: DownloadViewModel.Type, type: DownloadType,
disableUpdateData : Boolean = false disableUpdateData : Boolean = false
){ ){
if(findNavController().currentBackStack.value.firstOrNull {it.destination.id == R.id.downloadBottomSheetDialog} == null && if(findNavController().currentBackStack.value.firstOrNull {it.destination.id == R.id.downloadBottomSheetDialog} == null &&

View file

@ -18,6 +18,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -92,9 +93,9 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
val type = card.findViewById<MaterialButton>(R.id.download_type) val type = card.findViewById<MaterialButton>(R.id.download_type)
when(item.type){ when(item.type){
DownloadViewModel.Type.audio -> type.setIconResource(R.drawable.ic_music) DownloadType.audio -> type.setIconResource(R.drawable.ic_music)
DownloadViewModel.Type.video -> type.setIconResource(R.drawable.ic_video) DownloadType.video -> type.setIconResource(R.drawable.ic_video)
DownloadViewModel.Type.command -> type.setIconResource(R.drawable.ic_terminal) DownloadType.command -> type.setIconResource(R.drawable.ic_terminal)
else -> {} else -> {}
} }

View file

@ -21,6 +21,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -91,10 +92,10 @@ class ActiveDownloadMinifiedAdapter(onItemClickListener: OnItemClickListener, ac
//DOWNLOAD TYPE ----------------------------- //DOWNLOAD TYPE -----------------------------
val type = card.findViewById<TextView>(R.id.download_type) val type = card.findViewById<TextView>(R.id.download_type)
when(item.type){ when(item.type){
DownloadViewModel.Type.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_music_formatcard, 0, 0, 0 R.drawable.ic_music_formatcard, 0, 0, 0
) )
DownloadViewModel.Type.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_video_formatcard, 0, 0, 0 R.drawable.ic_video_formatcard, 0, 0, 0
) )
else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(

View file

@ -20,6 +20,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.AlreadyExistsItem import com.deniscerri.ytdl.database.models.AlreadyExistsItem
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -83,10 +84,10 @@ class AlreadyExistsAdapter(onItemClickListener: OnItemClickListener, activity: A
//DOWNLOAD TYPE ----------------------------- //DOWNLOAD TYPE -----------------------------
val type = card.findViewById<TextView>(R.id.download_type) val type = card.findViewById<TextView>(R.id.download_type)
when(item.type){ when(item.type){
DownloadViewModel.Type.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_music_formatcard, 0,0,0 R.drawable.ic_music_formatcard, 0,0,0
) )
DownloadViewModel.Type.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_video_formatcard, 0,0,0 R.drawable.ic_video_formatcard, 0,0,0
) )
else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(

View file

@ -19,6 +19,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItemConfigureMultiple import com.deniscerri.ytdl.database.models.DownloadItemConfigureMultiple
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.util.Extensions.loadThumbnail import com.deniscerri.ytdl.util.Extensions.loadThumbnail
@ -185,7 +186,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
container.text = item.container.uppercase() container.text = item.container.uppercase()
val fileSize = card.findViewById<TextView>(R.id.file_size) val fileSize = card.findViewById<TextView>(R.id.file_size)
val fileSizeReadable = if(item.type != DownloadViewModel.Type.video){ val fileSizeReadable = if(item.type != DownloadType.video){
FileUtil.convertFileSize(item.format.filesize) FileUtil.convertFileSize(item.format.filesize)
}else{ }else{
if (item.format.filesize < 10L) { if (item.format.filesize < 10L) {
@ -219,11 +220,11 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
} }
when(item.type) { when(item.type) {
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
btn.setIconResource(R.drawable.ic_music) btn.setIconResource(R.drawable.ic_music)
btn.contentDescription = activity.getString(R.string.audio) btn.contentDescription = activity.getString(R.string.audio)
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
btn.setIconResource(R.drawable.ic_video) btn.setIconResource(R.drawable.ic_video)
btn.contentDescription = activity.getString(R.string.video) btn.contentDescription = activity.getString(R.string.video)
} }

View file

@ -12,6 +12,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.LogItem import com.deniscerri.ytdl.database.models.LogItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.util.Extensions.popup import com.deniscerri.ytdl.util.Extensions.popup
@ -63,15 +64,15 @@ class DownloadLogsAdapter(onItemClickListener: OnItemClickListener, activity: Ac
val downloadTypeIcon = card.findViewById<MaterialButton>(R.id.download_type) val downloadTypeIcon = card.findViewById<MaterialButton>(R.id.download_type)
when(item.downloadType){ when(item.downloadType){
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
downloadTypeIcon.setIconResource(R.drawable.ic_music) downloadTypeIcon.setIconResource(R.drawable.ic_music)
downloadTypeIcon.contentDescription = activity.getString(R.string.audio) downloadTypeIcon.contentDescription = activity.getString(R.string.audio)
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
downloadTypeIcon.setIconResource(R.drawable.ic_video) downloadTypeIcon.setIconResource(R.drawable.ic_video)
downloadTypeIcon.contentDescription = activity.getString(R.string.video) downloadTypeIcon.contentDescription = activity.getString(R.string.video)
} }
DownloadViewModel.Type.command -> { DownloadType.command -> {
downloadTypeIcon.setIconResource(R.drawable.ic_terminal) downloadTypeIcon.setIconResource(R.drawable.ic_terminal)
downloadTypeIcon.contentDescription = activity.getString(R.string.command) downloadTypeIcon.contentDescription = activity.getString(R.string.command)
} }

View file

@ -16,6 +16,7 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItemSimple import com.deniscerri.ytdl.database.models.DownloadItemSimple
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -85,10 +86,10 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
//DOWNLOAD TYPE ----------------------------- //DOWNLOAD TYPE -----------------------------
val type = card.findViewById<TextView>(R.id.download_type) val type = card.findViewById<TextView>(R.id.download_type)
when(item.type){ when(item.type){
DownloadViewModel.Type.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_music_formatcard, 0,0,0 R.drawable.ic_music_formatcard, 0,0,0
) )
DownloadViewModel.Type.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_video_formatcard, 0,0,0 R.drawable.ic_video_formatcard, 0,0,0
) )
else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(

View file

@ -20,6 +20,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.HistoryItem import com.deniscerri.ytdl.database.models.HistoryItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.util.Extensions.loadThumbnail import com.deniscerri.ytdl.util.Extensions.loadThumbnail
@ -81,7 +82,7 @@ class HistoryPaginatedAdapter(onItemClickListener: OnItemClickListener, activity
return 0 return 0
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
val item = getItem(position) ?: return val item = getItem(position) ?: return
val card = holder.cardView val card = holder.cardView
holder.itemView.tag = item.id.toString() holder.itemView.tag = item.id.toString()
@ -136,11 +137,11 @@ class HistoryPaginatedAdapter(onItemClickListener: OnItemClickListener, activity
btn.backgroundTintList = MaterialColors.getColorStateList(activity, R.attr.colorPrimaryContainer, ContextCompat.getColorStateList(activity, android.R.color.transparent)!!) btn.backgroundTintList = MaterialColors.getColorStateList(activity, R.attr.colorPrimaryContainer, ContextCompat.getColorStateList(activity, android.R.color.transparent)!!)
} }
if (item.type == DownloadViewModel.Type.audio) { if (item.type == DownloadType.audio) {
if (filesPresent) btn.setImageResource(R.drawable.ic_music_downloaded) else { if (filesPresent) btn.setImageResource(R.drawable.ic_music_downloaded) else {
btn.setImageResource(R.drawable.ic_music) btn.setImageResource(R.drawable.ic_music)
} }
} else if (item.type == DownloadViewModel.Type.video) { } else if (item.type == DownloadType.video) {
if (filesPresent) btn.setImageResource(R.drawable.ic_video_downloaded) else btn.setImageResource(R.drawable.ic_video) if (filesPresent) btn.setImageResource(R.drawable.ic_video_downloaded) else btn.setImageResource(R.drawable.ic_video)
}else{ }else{
if (filesPresent) btn.setImageResource(R.drawable.ic_terminal) else btn.setImageResource(R.drawable.baseline_code_off_24) if (filesPresent) btn.setImageResource(R.drawable.ic_terminal) else btn.setImageResource(R.drawable.baseline_code_off_24)

View file

@ -16,6 +16,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.util.Extensions.loadThumbnail import com.deniscerri.ytdl.util.Extensions.loadThumbnail
@ -87,13 +88,13 @@ class HomeAdapter(onItemClickListener: OnItemClickListener, activity: Activity)
val musicBtn = card.findViewById<MaterialButton>(R.id.download_music) val musicBtn = card.findViewById<MaterialButton>(R.id.download_music)
musicBtn.tag = "$videoURL##audio" musicBtn.tag = "$videoURL##audio"
musicBtn.setTag(R.id.cancelDownload, "false") musicBtn.setTag(R.id.cancelDownload, "false")
musicBtn.setOnClickListener { onItemClickListener.onButtonClick(videoURL, DownloadViewModel.Type.audio) } musicBtn.setOnClickListener { onItemClickListener.onButtonClick(videoURL, DownloadType.audio) }
musicBtn.setOnLongClickListener{ onItemClickListener.onLongButtonClick(videoURL, DownloadViewModel.Type.audio); true} musicBtn.setOnLongClickListener{ onItemClickListener.onLongButtonClick(videoURL, DownloadType.audio); true}
val videoBtn = card.findViewById<MaterialButton>(R.id.download_video) val videoBtn = card.findViewById<MaterialButton>(R.id.download_video)
videoBtn.tag = "$videoURL##video" videoBtn.tag = "$videoURL##video"
videoBtn.setTag(R.id.cancelDownload, "false") videoBtn.setTag(R.id.cancelDownload, "false")
videoBtn.setOnClickListener { onItemClickListener.onButtonClick(videoURL, DownloadViewModel.Type.video) } videoBtn.setOnClickListener { onItemClickListener.onButtonClick(videoURL, DownloadType.video) }
videoBtn.setOnLongClickListener{ onItemClickListener.onLongButtonClick(videoURL, DownloadViewModel.Type.video); true} videoBtn.setOnLongClickListener{ onItemClickListener.onLongButtonClick(videoURL, DownloadType.video); true}
// PROGRESS BAR ---------------------------------------------------- // PROGRESS BAR ----------------------------------------------------
@ -166,8 +167,8 @@ class HomeAdapter(onItemClickListener: OnItemClickListener, activity: Activity)
} }
interface OnItemClickListener { interface OnItemClickListener {
fun onButtonClick(videoURL: String, type: DownloadViewModel.Type?) fun onButtonClick(videoURL: String, type: DownloadType?)
fun onLongButtonClick(videoURL: String, type: DownloadViewModel.Type?) fun onLongButtonClick(videoURL: String, type: DownloadType?)
fun onCardClick(videoURL: String, add: Boolean) fun onCardClick(videoURL: String, add: Boolean)
fun onCardDetailsClick(videoURL: String) fun onCardDetailsClick(videoURL: String)
} }

View file

@ -21,6 +21,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItemSimple import com.deniscerri.ytdl.database.models.DownloadItemSimple
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.util.Extensions.loadThumbnail import com.deniscerri.ytdl.util.Extensions.loadThumbnail
@ -101,10 +102,10 @@ class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
//DOWNLOAD TYPE ----------------------------- //DOWNLOAD TYPE -----------------------------
val type = card.findViewById<TextView>(R.id.download_type) val type = card.findViewById<TextView>(R.id.download_type)
when(item.type){ when(item.type){
DownloadViewModel.Type.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_music_formatcard, 0,0,0 R.drawable.ic_music_formatcard, 0,0,0
) )
DownloadViewModel.Type.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_video_formatcard, 0,0,0 R.drawable.ic_video_formatcard, 0,0,0
) )
else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(

View file

@ -18,6 +18,7 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItemSimple import com.deniscerri.ytdl.database.models.DownloadItemSimple
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -97,10 +98,10 @@ class ScheduledDownloadAdapter(onItemClickListener: OnItemClickListener, activit
//DOWNLOAD TYPE ----------------------------- //DOWNLOAD TYPE -----------------------------
val type = card.findViewById<TextView>(R.id.download_type) val type = card.findViewById<TextView>(R.id.download_type)
when(item.type){ when(item.type){
DownloadViewModel.Type.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.audio -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_music_formatcard, 0,0,0 R.drawable.ic_music_formatcard, 0,0,0
) )
DownloadViewModel.Type.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( DownloadType.video -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_video_formatcard, 0,0,0 R.drawable.ic_video_formatcard, 0,0,0
) )
else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds( else -> type.setCompoundDrawablesRelativeWithIntrinsicBounds(

View file

@ -20,10 +20,10 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdl.util.UiUtil import com.deniscerri.ytdl.util.UiUtil
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -118,11 +118,11 @@ class ConfigureDownloadBottomSheetDialog(private val currentDownloadItem: Downlo
view.post { view.post {
when(currentDownloadItem.type) { when(currentDownloadItem.type) {
Type.audio -> { DownloadType.audio -> {
tabLayout.selectTab(tabLayout.getTabAt(0)) tabLayout.selectTab(tabLayout.getTabAt(0))
viewPager2.setCurrentItem(0, false) viewPager2.setCurrentItem(0, false)
} }
Type.video -> { DownloadType.video -> {
if (isAudioOnly){ if (isAudioOnly){
tabLayout.getTabAt(0)!!.select() tabLayout.getTabAt(0)!!.select()
viewPager2.setCurrentItem(0, false) viewPager2.setCurrentItem(0, false)
@ -183,7 +183,7 @@ class ConfigureDownloadBottomSheetDialog(private val currentDownloadItem: Downlo
runCatching { runCatching {
sharedPreferences.edit(commit = true) { sharedPreferences.edit(commit = true) {
putString("last_used_download_type", putString("last_used_download_type",
listOf(Type.audio, Type.video, Type.command)[position].toString()) listOf(DownloadType.audio, DownloadType.video, DownloadType.command)[position].toString())
} }
fragmentAdapter.updateWhenSwitching(viewPager2.currentItem) fragmentAdapter.updateWhenSwitching(viewPager2.currentItem)
} }

View file

@ -23,13 +23,12 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdl.database.viewmodel.FormatViewModel import com.deniscerri.ytdl.database.viewmodel.FormatViewModel
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
import com.deniscerri.ytdl.database.viewmodel.YTDLPViewModel import com.deniscerri.ytdl.database.viewmodel.YTDLPViewModel
@ -86,7 +85,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
formatViewModel = ViewModelProvider(requireActivity())[FormatViewModel::class.java] formatViewModel = ViewModelProvider(requireActivity())[FormatViewModel::class.java]
genericAudioFormats = FormatUtil(requireContext()).getGenericAudioFormats(requireContext().resources) genericAudioFormats = FormatUtil(requireContext()).getGenericAudioFormats(requireContext().resources)
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
shownFields = preferences.getStringSet("modify_download_card", requireContext().getStringArray(R.array.modify_download_card_values).toSet())!!.toList() shownFields = preferences.getStringSet("modify_download_card", requireContext().resources.getStringArray(R.array.modify_download_card_values).toSet())!!.toList()
return fragmentView return fragmentView
} }
@ -97,8 +96,8 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
downloadItem.apply { downloadItem.apply {
title = resultItem!!.title title = resultItem!!.title
author = resultItem!!.author author = resultItem!!.author
allFormats = resultItem!!.formats allFormats = resultItem!!.formats.toMutableList()
format = downloadViewModel.getFormat(allFormats, Type.audio) format = downloadViewModel.getFormat(allFormats, DownloadType.audio)
duration = resultItem!!.duration duration = resultItem!!.duration
playlistIndex = resultItem!!.playlistIndex playlistIndex = resultItem!!.playlistIndex
playlistURL = resultItem!!.playlistURL playlistURL = resultItem!!.playlistURL
@ -112,7 +111,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java) val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java) Gson().fromJson(string, DownloadItem::class.java)
}else{ }else{
downloadViewModel.createDownloadItemFromResult(resultItem, url, Type.audio) downloadViewModel.createDownloadItemFromResult(resultItem, url, DownloadType.audio)
} }
} }
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
@ -200,10 +199,10 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
formats.addAll(resultItem?.formats?.filter { it.format_note.contains("audio", ignoreCase = true) } ?: listOf()) formats.addAll(resultItem?.formats?.filter { it.format_note.contains("audio", ignoreCase = true) } ?: listOf())
}else{ }else{
//if its updating a present downloaditem and its the wrong category //if its updating a present downloaditem and its the wrong category
if (currentDownloadItem!!.type != Type.audio){ if (currentDownloadItem!!.type != DownloadType.audio){
downloadItem.type = Type.audio downloadItem.type = DownloadType.audio
runCatching { runCatching {
downloadItem.format = downloadViewModel.getFormat(downloadItem.allFormats, Type.audio) downloadItem.format = downloadViewModel.getFormat(downloadItem.allFormats, DownloadType.audio)
}.onFailure { }.onFailure {
downloadItem.format = genericAudioFormats.last() downloadItem.format = genericAudioFormats.last()
} }
@ -246,8 +245,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
override fun onFormatsUpdated(allFormats: List<Format>) { override fun onFormatsUpdated(allFormats: List<Format>) {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
resultItem?.apply { resultItem?.apply {
this.formats.removeAll(formats.toSet()) this.formats = allFormats.filter { !genericAudioFormats.contains(it) }
this.formats.addAll(allFormats.filter { !genericAudioFormats.contains(it) })
resultViewModel.update(this) resultViewModel.update(this)
} }
@ -257,7 +255,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
} }
formats = allFormats.filter { !genericAudioFormats.contains(it) }.toMutableList() formats = allFormats.filter { !genericAudioFormats.contains(it) }.toMutableList()
formats.removeAll(genericAudioFormats) formats.removeAll(genericAudioFormats)
val preferredFormat = downloadViewModel.getFormat(formats, Type.audio) val preferredFormat = downloadViewModel.getFormat(formats, DownloadType.audio)
downloadItem.format = preferredFormat downloadItem.format = preferredFormat
downloadItem.allFormats = formats downloadItem.allFormats = formats
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, null, showSize = downloadItem.downloadSections.isEmpty()) val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, null, showSize = downloadItem.downloadSections.isEmpty())

View file

@ -30,14 +30,13 @@ import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
import com.deniscerri.ytdl.receiver.ShareActivity import com.deniscerri.ytdl.receiver.ShareActivity
@ -84,7 +83,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
private lateinit var result: ResultItem private lateinit var result: ResultItem
private lateinit var type: Type private lateinit var type: DownloadType
private var ignoreDuplicates: Boolean = false private var ignoreDuplicates: Boolean = false
private var disableUpdateData : Boolean = false private var disableUpdateData : Boolean = false
private var currentDownloadItem: DownloadItem? = null private var currentDownloadItem: DownloadItem? = null
@ -107,7 +106,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
res = arguments?.getParcelable<ResultItem>("result") res = arguments?.getParcelable<ResultItem>("result")
dwl = arguments?.getParcelable<DownloadItem>("downloadItem") dwl = arguments?.getParcelable<DownloadItem>("downloadItem")
} }
type = arguments?.getSerializable("type") as Type type = arguments?.getSerializable("type") as DownloadType
disableUpdateData = arguments?.getBoolean("disableUpdateData") == true disableUpdateData = arguments?.getBoolean("disableUpdateData") == true
ignoreDuplicates = arguments?.getBoolean("ignore_duplicates") == true ignoreDuplicates = arguments?.getBoolean("ignore_duplicates") == true
@ -208,11 +207,11 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
view.post { view.post {
when(type) { when(type) {
Type.audio -> { DownloadType.audio -> {
tabLayout.getTabAt(0)!!.select() tabLayout.getTabAt(0)!!.select()
viewPager2.setCurrentItem(0, false) viewPager2.setCurrentItem(0, false)
} }
Type.video -> { DownloadType.video -> {
if (isAudioOnly){ if (isAudioOnly){
tabLayout.getTabAt(0)!!.select() tabLayout.getTabAt(0)!!.select()
viewPager2.setCurrentItem(0, false) viewPager2.setCurrentItem(0, false)
@ -231,7 +230,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
} }
//check if the item is coming from a text file //check if the item is coming from a text file
val isCommandOnly = (type == Type.command && !Patterns.WEB_URL.matcher(result.url).matches()) val isCommandOnly = (type == DownloadType.command && !Patterns.WEB_URL.matcher(result.url).matches())
if (isCommandOnly){ if (isCommandOnly){
(tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(0)?.isClickable = false (tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(0)?.isClickable = false
(tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(0)?.alpha = 0.3f (tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(0)?.alpha = 0.3f
@ -294,7 +293,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
runCatching { runCatching {
sharedPreferences.edit(commit = true) { sharedPreferences.edit(commit = true) {
putString("last_used_download_type", putString("last_used_download_type",
listOf(Type.audio, Type.video, Type.command)[position].toString()) listOf(DownloadType.audio, DownloadType.video, DownloadType.command)[position].toString())
} }
fragmentAdapter.updateWhenSwitching(viewPager2.currentItem) fragmentAdapter.updateWhenSwitching(viewPager2.currentItem)
} }
@ -303,7 +302,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
viewPager2.setPageTransformer(BackgroundToForegroundPageTransformer()) viewPager2.setPageTransformer(BackgroundToForegroundPageTransformer())
val shownFields = sharedPreferences.getStringSet("modify_download_card", requireContext().getStringArray(R.array.modify_download_card_values).toSet())!!.toList() val shownFields = sharedPreferences.getStringSet("modify_download_card", requireContext().resources.getStringArray(R.array.modify_download_card_values).toSet())!!.toList()
val scheduleBtn = view.findViewById<MaterialButton>(R.id.bottomsheet_schedule_button) val scheduleBtn = view.findViewById<MaterialButton>(R.id.bottomsheet_schedule_button)
scheduleBtn.visibility = if(shownFields.contains("schedule")){ scheduleBtn.visibility = if(shownFields.contains("schedule")){
@ -464,7 +463,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
//update in the background if there is no data //update in the background if there is no data
if (!disableUpdateData) { if (!disableUpdateData) {
if(result.title.isEmpty() && currentDownloadItem == null && !sharedPreferences.getBoolean("quick_download", false) && type != Type.command){ if(result.title.isEmpty() && currentDownloadItem == null && !sharedPreferences.getBoolean("quick_download", false) && type != DownloadType.command){
initUpdateData() initUpdateData()
}else { }else {
val usingGenericFormatsOrEmpty = result.formats.isEmpty() || result.formats.any { it.format_note.contains("ytdlnisgeneric") } val usingGenericFormatsOrEmpty = result.formats.isEmpty() || result.formats.any { it.format_note.contains("ytdlnisgeneric") }

View file

@ -22,8 +22,8 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.CommandTemplate import com.deniscerri.ytdl.database.models.CommandTemplate
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
@ -66,7 +66,7 @@ class DownloadCommandFragment(private val resultItem: ResultItem? = null, privat
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java] commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
shownFields = preferences.getStringSet("modify_download_card", requireContext().getStringArray(R.array.modify_download_card_values).toSet())!!.toList() shownFields = preferences.getStringSet("modify_download_card", requireContext().resources.getStringArray(R.array.modify_download_card_values).toSet())!!.toList()
return fragmentView return fragmentView
} }
@ -78,15 +78,15 @@ class DownloadCommandFragment(private val resultItem: ResultItem? = null, privat
downloadItem = withContext(Dispatchers.IO){ downloadItem = withContext(Dispatchers.IO){
if (currentDownloadItem != null){ if (currentDownloadItem != null){
currentDownloadItem?.apply { currentDownloadItem?.apply {
if (type != DownloadViewModel.Type.command){ if (type != DownloadType.command){
type = DownloadViewModel.Type.command type = DownloadType.command
} }
} }
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java) val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java) Gson().fromJson(string, DownloadItem::class.java)
}else{ }else{
downloadViewModel.createDownloadItemFromResult(resultItem, url, DownloadViewModel.Type.command) downloadViewModel.createDownloadItemFromResult(resultItem, url, DownloadType.command)
} }
} }

View file

@ -38,9 +38,9 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.DBManager.SORTING import com.deniscerri.ytdl.database.DBManager.SORTING
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.CommandTemplate import com.deniscerri.ytdl.database.models.CommandTemplate
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.DownloadItemConfigureMultiple import com.deniscerri.ytdl.database.models.DownloadItemConfigureMultiple
@ -171,7 +171,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
} }
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("multipledownloadcard")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("multipledownloadcard")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView) itemTouchHelper.attachToRecyclerView(recyclerView)
} }
@ -230,13 +230,13 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
updateBottomAppBarMenuItemsVisibility(firstItem) updateBottomAppBarMenuItemsVisibility(firstItem)
val type = items.first().type val type = items.first().type
when(type){ when(type){
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24) preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24)
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
preferredDownloadType.setIcon(R.drawable.baseline_video_file_24) preferredDownloadType.setIcon(R.drawable.baseline_video_file_24)
} }
DownloadViewModel.Type.command -> { DownloadType.command -> {
preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24) preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24)
setContainerText("") setContainerText("")
} }
@ -403,7 +403,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
audio!!.setOnClickListener { audio!!.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
downloadViewModel.updateProcessingType(listAdapter.getCheckedItemsOrNull(), DownloadViewModel.Type.audio) downloadViewModel.updateProcessingType(listAdapter.getCheckedItemsOrNull(), DownloadType.audio)
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
bottomSheet.cancel() bottomSheet.cancel()
} }
@ -412,7 +412,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
video!!.setOnClickListener { video!!.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch{ CoroutineScope(Dispatchers.IO).launch{
downloadViewModel.updateProcessingType(listAdapter.getCheckedItemsOrNull(), DownloadViewModel.Type.video) downloadViewModel.updateProcessingType(listAdapter.getCheckedItemsOrNull(), DownloadType.video)
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
bottomSheet.cancel() bottomSheet.cancel()
} }
@ -421,7 +421,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
command!!.setOnClickListener { command!!.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch{ CoroutineScope(Dispatchers.IO).launch{
downloadViewModel.updateProcessingType(listAdapter.getCheckedItemsOrNull(), DownloadViewModel.Type.command) downloadViewModel.updateProcessingType(listAdapter.getCheckedItemsOrNull(), DownloadType.command)
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
bottomSheet.cancel() bottomSheet.cancel()
} }
@ -449,7 +449,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
Toast.makeText(requireContext(), getString(R.string.format_filtering_hint), Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), getString(R.string.format_filtering_hint), Toast.LENGTH_SHORT).show()
}else{ }else{
if (res.second == DownloadViewModel.Type.command){ if (res.second == DownloadType.command){
UiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel) { UiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel) {
val format = Format( val format = Format(
it.first().title, it.first().title,
@ -528,7 +528,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
val padding = (40*scale*0.5f).toInt() val padding = (40*scale*0.5f).toInt()
when(res.second){ when(res.second){
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
val bottomSheet = BottomSheetDialog(requireContext()) val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE) bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.adjust_audio) bottomSheet.setContentView(R.layout.adjust_audio)
@ -621,7 +621,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
) )
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
val bottomSheet = BottomSheetDialog(requireContext()) val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE) bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.adjust_video) bottomSheet.setContentView(R.layout.adjust_video)
@ -732,7 +732,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
ViewGroup.LayoutParams.MATCH_PARENT ViewGroup.LayoutParams.MATCH_PARENT
) )
} }
DownloadViewModel.Type.command -> { DownloadType.command -> {
val bottomSheet = BottomSheetDialog(requireContext()) val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE) bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.adjust_command) bottomSheet.setContentView(R.layout.adjust_command)
@ -834,7 +834,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
}else{ }else{
val popup = PopupMenu(activity, containerTextView) val popup = PopupMenu(activity, containerTextView)
when(res.second) { when(res.second) {
DownloadViewModel.Type.audio -> resources.getStringArray(R.array.audio_containers) DownloadType.audio -> resources.getStringArray(R.array.audio_containers)
//video //video
else -> resources.getStringArray(R.array.video_containers) else -> resources.getStringArray(R.array.video_containers)
}.forEach { }.forEach {
@ -1015,7 +1015,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
private fun updateFileSize(items: List<DownloadItemConfigureMultiple>){ private fun updateFileSize(items: List<DownloadItemConfigureMultiple>){
val fileSizes = mutableListOf<Long>() val fileSizes = mutableListOf<Long>()
items.forEach { items.forEach {
if (it.type == DownloadViewModel.Type.video){ if (it.type == DownloadType.video){
println(it.format.filesize) println(it.format.filesize)
if (it.format.filesize <= 5L) { if (it.format.filesize <= 5L) {
fileSizes.add(0) fileSizes.add(0)
@ -1030,7 +1030,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
} }
fileSizes.add(it.format.filesize + audioFormatSize) fileSizes.add(it.format.filesize + audioFormatSize)
} }
}else if (it.type == DownloadViewModel.Type.audio){ }else if (it.type == DownloadType.audio){
fileSizes.add(it.format.filesize) fileSizes.add(it.format.filesize)
} }
} }
@ -1095,7 +1095,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
audio!!.setOnClickListener { audio!!.setOnClickListener {
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO){ withContext(Dispatchers.IO){
item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.audio).first() item = downloadViewModel.switchDownloadType(listOf(item), DownloadType.audio).first()
downloadViewModel.updateDownload(item) downloadViewModel.updateDownload(item)
} }
bottomSheet.cancel() bottomSheet.cancel()
@ -1105,7 +1105,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
video!!.setOnClickListener { video!!.setOnClickListener {
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO){ withContext(Dispatchers.IO){
item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.video).first() item = downloadViewModel.switchDownloadType(listOf(item), DownloadType.video).first()
downloadViewModel.updateDownload(item) downloadViewModel.updateDownload(item)
} }
bottomSheet.cancel() bottomSheet.cancel()
@ -1115,7 +1115,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
command!!.setOnClickListener { command!!.setOnClickListener {
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO){ withContext(Dispatchers.IO){
item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.command).first() item = downloadViewModel.switchDownloadType(listOf(item), DownloadType.command).first()
downloadViewModel.updateDownload(item) downloadViewModel.updateDownload(item)
} }
bottomSheet.cancel() bottomSheet.cancel()
@ -1339,7 +1339,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
}else { }else {
setContainerText("") setContainerText("")
} }
containerBtn.isVisible = haveSameContainer.first && haveSameType.first && haveSameType.second != DownloadViewModel.Type.command containerBtn.isVisible = haveSameContainer.first && haveSameType.first && haveSameType.second != DownloadType.command
} }
} }
} }

View file

@ -23,13 +23,12 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdl.database.viewmodel.FormatViewModel import com.deniscerri.ytdl.database.viewmodel.FormatViewModel
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
import com.deniscerri.ytdl.database.viewmodel.YTDLPViewModel import com.deniscerri.ytdl.database.viewmodel.YTDLPViewModel
@ -92,7 +91,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
genericVideoFormats = formatUtil.getGenericVideoFormats(requireContext().resources) genericVideoFormats = formatUtil.getGenericVideoFormats(requireContext().resources)
genericAudioFormats = formatUtil.getGenericAudioFormats(requireContext().resources) genericAudioFormats = formatUtil.getGenericAudioFormats(requireContext().resources)
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
shownFields = preferences.getStringSet("modify_download_card", requireContext().getStringArray(R.array.modify_download_card_values).toSet())!!.toList() shownFields = preferences.getStringSet("modify_download_card", requireContext().resources.getStringArray(R.array.modify_download_card_values).toSet())!!.toList()
return fragmentView return fragmentView
} }
@ -106,8 +105,8 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
downloadItem.apply { downloadItem.apply {
title = resultItem!!.title title = resultItem!!.title
author = resultItem!!.author author = resultItem!!.author
allFormats = resultItem!!.formats allFormats = resultItem!!.formats.toMutableList()
format = downloadViewModel.getFormat(allFormats, Type.video) format = downloadViewModel.getFormat(allFormats, DownloadType.video)
duration = resultItem!!.duration duration = resultItem!!.duration
playlistIndex = resultItem!!.playlistIndex playlistIndex = resultItem!!.playlistIndex
playlistURL = resultItem!!.playlistURL playlistURL = resultItem!!.playlistURL
@ -123,7 +122,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java) val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java) Gson().fromJson(string, DownloadItem::class.java)
}else{ }else{
downloadViewModel.createDownloadItemFromResult(resultItem, url, Type.video) downloadViewModel.createDownloadItemFromResult(resultItem, url, DownloadType.video)
} }
} }
@ -211,13 +210,13 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
formats.addAll(resultItem?.formats ?: listOf()) formats.addAll(resultItem?.formats ?: listOf())
}else{ }else{
//if its updating a present downloaditem and its the wrong category //if its updating a present downloaditem and its the wrong category
if (currentDownloadItem!!.type != Type.video){ if (currentDownloadItem!!.type != DownloadType.video){
downloadItem.type = Type.video downloadItem.type = DownloadType.video
runCatching { runCatching {
downloadItem.format = downloadViewModel.getFormat(downloadItem.allFormats, Type.video) downloadItem.format = downloadViewModel.getFormat(downloadItem.allFormats, DownloadType.video)
if (downloadItem.videoPreferences.audioFormatIDs.isEmpty()){ if (downloadItem.videoPreferences.audioFormatIDs.isEmpty()){
downloadItem.videoPreferences.audioFormatIDs.add( downloadItem.videoPreferences.audioFormatIDs.add(
downloadViewModel.getFormat(downloadItem.allFormats, Type.audio).format_id downloadViewModel.getFormat(downloadItem.allFormats, DownloadType.audio).format_id
) )
} }
}.onFailure { }.onFailure {
@ -279,8 +278,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO){ withContext(Dispatchers.IO){
resultItem?.apply { resultItem?.apply {
this.formats.removeAll(formats) this.formats = allFormats.filter { !genericVideoFormats.contains(it) }
this.formats.addAll(allFormats.filter { !genericVideoFormats.contains(it) })
resultViewModel.update(this) resultViewModel.update(this)
} }
@ -290,7 +288,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
} }
} }
formats = allFormats.filter { !genericVideoFormats.contains(it) }.toMutableList() formats = allFormats.filter { !genericVideoFormats.contains(it) }.toMutableList()
val preferredFormat = downloadViewModel.getFormat(formats, Type.video) val preferredFormat = downloadViewModel.getFormat(formats, DownloadType.video)
val preferredAudioFormats = downloadViewModel.getPreferredAudioFormats(formats) val preferredAudioFormats = downloadViewModel.getPreferredAudioFormats(formats)
downloadItem.format = preferredFormat downloadItem.format = preferredFormat
downloadItem.allFormats = formats downloadItem.allFormats = formats

View file

@ -23,11 +23,11 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.FormatRecyclerView import com.deniscerri.ytdl.database.models.FormatRecyclerView
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdl.database.viewmodel.FormatViewModel import com.deniscerri.ytdl.database.viewmodel.FormatViewModel
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
import com.deniscerri.ytdl.ui.adapter.FormatAdapter import com.deniscerri.ytdl.ui.adapter.FormatAdapter
@ -214,7 +214,7 @@ class FormatSelectionBottomSheetDialog(
val res = resultViewModel.getFormats(items.first().url, currentFormatSource) val res = resultViewModel.getFormats(items.first().url, currentFormatSource)
if (!isActive) return@launch if (!isActive) return@launch
res.filter { it.format_note != "storyboard" } res.filter { it.format_note != "storyboard" }
val chosenFormats = if (items.first().type == Type.audio) { val chosenFormats = if (items.first().type == DownloadType.audio) {
res.filter { it.format_note.contains("audio", ignoreCase = true) } res.filter { it.format_note.contains("audio", ignoreCase = true) }
} else { } else {
res res
@ -408,7 +408,7 @@ class FormatSelectionBottomSheetDialog(
if (_listener != null){ if (_listener != null){
//simple video format selection //simple video format selection
listener.onFormatClick(FormatTuple(adapter.selectedVideoFormat, adapter.selectedAudioFormats.ifEmpty { listener.onFormatClick(FormatTuple(adapter.selectedVideoFormat, adapter.selectedAudioFormats.ifEmpty {
listOf(downloadViewModel.getFormat(formats.filter { it.label == null }.map { it.format!! }, Type.audio)) listOf(downloadViewModel.getFormat(formats.filter { it.label == null }.map { it.format!! }, DownloadType.audio))
})) }))
}else{ }else{
val res = formatViewModel.getFormatsForItemsBasedOnFormat(adapter.selectedVideoFormat!!, adapter.selectedAudioFormats) val res = formatViewModel.getFormatsForItemsBasedOnFormat(adapter.selectedVideoFormat!!, adapter.selectedAudioFormats)

View file

@ -29,6 +29,7 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
@ -37,7 +38,6 @@ import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesWeeklyCo
import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository
import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel
import com.deniscerri.ytdl.database.viewmodel.ObserveSourcesViewModel import com.deniscerri.ytdl.database.viewmodel.ObserveSourcesViewModel
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
@ -74,7 +74,7 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
private lateinit var sharedPreferences : SharedPreferences private lateinit var sharedPreferences : SharedPreferences
private lateinit var view: View private lateinit var view: View
private lateinit var type: Type private lateinit var type: DownloadType
private var currentItem: ObserveSourcesItem? = null private var currentItem: ObserveSourcesItem? = null
@ -115,7 +115,7 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
arguments?.getParcelable<ObserveSourcesItem>("item") arguments?.getParcelable<ObserveSourcesItem>("item")
} }
type = currentItem?.downloadItemTemplate?.type ?: arguments?.getSerializable("type") as Type type = currentItem?.downloadItemTemplate?.type ?: arguments?.getSerializable("type") as DownloadType
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
@ -164,7 +164,7 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
fragmentAdapter = DownloadFragmentAdapter( fragmentAdapter = DownloadFragmentAdapter(
fragmentManager, fragmentManager,
lifecycle, lifecycle,
ResultItem(0, "", "", "", "", "", "", "", mutableListOf(), "", null, null, null, 0), ResultItem(0, "", "", "", "", "", "", "", mutableListOf(), "", listOf(), null, null, 0),
currentItem?.downloadItemTemplate, currentItem?.downloadItemTemplate,
true true
) )
@ -173,11 +173,11 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
viewPager2.isSaveFromParentEnabled = false viewPager2.isSaveFromParentEnabled = false
when(type) { when(type) {
Type.audio -> { DownloadType.audio -> {
tabLayout.getTabAt(0)!!.select() tabLayout.getTabAt(0)!!.select()
viewPager2.setCurrentItem(0, false) viewPager2.setCurrentItem(0, false)
} }
Type.video -> { DownloadType.video -> {
tabLayout.getTabAt(1)!!.select() tabLayout.getTabAt(1)!!.select()
viewPager2.setCurrentItem(1, false) viewPager2.setCurrentItem(1, false)
} }
@ -235,7 +235,7 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() {
runCatching { runCatching {
sharedPreferences.edit(commit = true) { sharedPreferences.edit(commit = true) {
putString("last_used_download_type", putString("last_used_download_type",
listOf(Type.audio, Type.video, Type.command)[position].toString()) listOf(DownloadType.audio, DownloadType.video, DownloadType.command)[position].toString())
} }
} }
} }

View file

@ -37,6 +37,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.work.WorkManager import androidx.work.WorkManager
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
@ -251,18 +252,18 @@ class ResultCardDetailsDialog : BottomSheetDialogFragment(), GenericDownloadAdap
bottomInfo.text = item.author bottomInfo.text = item.author
downloadMusic.setOnClickListener { downloadMusic.setOnClickListener {
onButtonClick(DownloadViewModel.Type.audio) onButtonClick(DownloadType.audio)
} }
downloadMusic.setOnLongClickListener { downloadMusic.setOnLongClickListener {
onButtonClick(DownloadViewModel.Type.audio) onButtonClick(DownloadType.audio)
true true
} }
downloadVideo.setOnClickListener { downloadVideo.setOnClickListener {
onButtonClick(DownloadViewModel.Type.video) onButtonClick(DownloadType.video)
} }
downloadVideo.setOnLongClickListener { downloadVideo.setOnLongClickListener {
onButtonClick(DownloadViewModel.Type.video) onButtonClick(DownloadType.video)
true true
} }
@ -308,7 +309,7 @@ class ResultCardDetailsDialog : BottomSheetDialogFragment(), GenericDownloadAdap
} }
} }
private fun onButtonClick(type: DownloadViewModel.Type){ private fun onButtonClick(type: DownloadType){
if (sharedPreferences.getBoolean("download_card", true)) { if (sharedPreferences.getBoolean("download_card", true)) {
val bundle = Bundle() val bundle = Bundle()
bundle.putParcelable("result", item) bundle.putParcelable("result", item)

View file

@ -31,7 +31,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
@ -101,7 +100,7 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
cancelledRecyclerView.forceFastScrollMode() cancelledRecyclerView.forceFastScrollMode()
cancelledRecyclerView.adapter = adapter cancelledRecyclerView.adapter = adapter
cancelledRecyclerView.enableFastScroll() cancelledRecyclerView.enableFastScroll()
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("cancelled")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("cancelled")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(cancelledRecyclerView) itemTouchHelper.attachToRecyclerView(cancelledRecyclerView)
} }

View file

@ -30,7 +30,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
@ -100,7 +99,7 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
erroredRecyclerView.adapter = adapter erroredRecyclerView.adapter = adapter
erroredRecyclerView.enableFastScroll() erroredRecyclerView.enableFastScroll()
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("errored")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("errored")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(erroredRecyclerView) itemTouchHelper.attachToRecyclerView(erroredRecyclerView)
} }

View file

@ -38,10 +38,10 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.DBManager.SORTING import com.deniscerri.ytdl.database.DBManager.SORTING
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.HistoryItem import com.deniscerri.ytdl.database.models.HistoryItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.repository.HistoryRepository import com.deniscerri.ytdl.database.repository.HistoryRepository
@ -127,7 +127,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
recyclerView.enableFastScroll() recyclerView.enableFastScroll()
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("history")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("history")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView) itemTouchHelper.attachToRecyclerView(recyclerView)
} }
@ -468,7 +468,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
val audio = fragmentView.findViewById<Chip>(R.id.audio_chip) val audio = fragmentView.findViewById<Chip>(R.id.audio_chip)
audio.setOnClickListener { audio.setOnClickListener {
if (audio.isChecked) { if (audio.isChecked) {
historyViewModel.setTypeFilter(DownloadViewModel.Type.audio.toString()) historyViewModel.setTypeFilter(DownloadType.audio.toString())
audio.isChecked = true audio.isChecked = true
} else { } else {
historyViewModel.setTypeFilter("") historyViewModel.setTypeFilter("")
@ -478,7 +478,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
val video = fragmentView.findViewById<Chip>(R.id.video_chip) val video = fragmentView.findViewById<Chip>(R.id.video_chip)
video.setOnClickListener { video.setOnClickListener {
if (video.isChecked) { if (video.isChecked) {
historyViewModel.setTypeFilter(DownloadViewModel.Type.video.toString()) historyViewModel.setTypeFilter(DownloadType.video.toString())
video.isChecked = true video.isChecked = true
} else { } else {
historyViewModel.setTypeFilter("") historyViewModel.setTypeFilter("")
@ -488,7 +488,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
val command = fragmentView.findViewById<Chip>(R.id.command_chip) val command = fragmentView.findViewById<Chip>(R.id.command_chip)
command.setOnClickListener { command.setOnClickListener {
if (command.isChecked) { if (command.isChecked) {
historyViewModel.setTypeFilter(DownloadViewModel.Type.command.toString()) historyViewModel.setTypeFilter(DownloadType.command.toString())
command.isChecked = true command.isChecked = true
} else { } else {
historyViewModel.setTypeFilter("") historyViewModel.setTypeFilter("")

View file

@ -29,7 +29,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
@ -100,7 +99,7 @@ class QueuedDownloadsFragment : Fragment(), QueuedDownloadAdapter.OnItemClickLis
itemTouchHelper.attachToRecyclerView(queuedRecyclerView) itemTouchHelper.attachToRecyclerView(queuedRecyclerView)
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("queued")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("queued")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(queuedRecyclerView) itemTouchHelper.attachToRecyclerView(queuedRecyclerView)
} }

View file

@ -29,7 +29,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
@ -99,7 +98,7 @@ class SavedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLis
savedRecyclerView.enableFastScroll() savedRecyclerView.enableFastScroll()
savedRecyclerView.adapter = adapter savedRecyclerView.adapter = adapter
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("saved")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("saved")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(savedRecyclerView) itemTouchHelper.attachToRecyclerView(savedRecyclerView)
} }

View file

@ -30,7 +30,6 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.work.WorkManager import androidx.work.WorkManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.repository.DownloadRepository
@ -99,7 +98,7 @@ class ScheduledDownloadsFragment : Fragment(), ScheduledDownloadAdapter.OnItemCl
scheduledRecyclerView.forceFastScrollMode() scheduledRecyclerView.forceFastScrollMode()
scheduledRecyclerView.adapter = adapter scheduledRecyclerView.adapter = adapter
scheduledRecyclerView.enableFastScroll() scheduledRecyclerView.enableFastScroll()
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("scheduled")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("scheduled")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(scheduledRecyclerView) itemTouchHelper.attachToRecyclerView(scheduledRecyclerView)
} }

View file

@ -32,7 +32,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.DBManager.SORTING import com.deniscerri.ytdl.database.DBManager.SORTING
@ -100,7 +99,7 @@ class CommandTemplatesFragment : Fragment(), TemplatesAdapter.OnItemClickListene
recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = templatesAdapter recyclerView.adapter = templatesAdapter
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("templates")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("templates")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView) itemTouchHelper.attachToRecyclerView(recyclerView)
} }

View file

@ -23,6 +23,7 @@ import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem
import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -113,7 +114,7 @@ class ObserveSourcesFragment : Fragment(), ObserveSourcesAdapter.OnItemClickList
lifecycleScope.launch { lifecycleScope.launch {
val bundle = Bundle() val bundle = Bundle()
bundle.putSerializable("type", downloadViewModel.getDownloadType( bundle.putSerializable("type", downloadViewModel.getDownloadType(
DownloadViewModel.Type.valueOf(preferences.getString("download_type", "auto")!!), "") DownloadType.valueOf(preferences.getString("download_type", "auto")!!), "")
) )
if (url != null){ if (url != null){

View file

@ -26,7 +26,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.CookieItem import com.deniscerri.ytdl.database.models.CookieItem
@ -91,7 +90,7 @@ class CookiesFragment : Fragment(), CookieAdapter.OnItemClickListener {
recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = listAdapter recyclerView.adapter = listAdapter
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getStringSet("swipe_gesture", requireContext().getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("cookies")){ if (preferences.getStringSet("swipe_gesture", requireContext().resources.getStringArray(R.array.swipe_gestures_values).toSet())!!.toList().contains("cookies")){
val itemTouchHelper = ItemTouchHelper(simpleCallback) val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView) itemTouchHelper.attachToRecyclerView(recyclerView)
} }

View file

@ -6,17 +6,22 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import android.webkit.CookieManager import android.webkit.CookieManager
import android.webkit.WebChromeClient
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebStorage import android.webkit.WebStorage
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.children import androidx.core.view.children
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -45,7 +50,7 @@ class WebViewActivity : BaseActivity() {
private lateinit var url: String private lateinit var url: String
private lateinit var description: String private lateinit var description: String
private lateinit var cookies: String private lateinit var cookies: String
private lateinit var webViewClient: AccompanistWebViewClient private lateinit var webViewClient: WebViewClient
private lateinit var preferences: SharedPreferences private lateinit var preferences: SharedPreferences
private var incognito: Boolean = false private var incognito: Boolean = false
@ -97,7 +102,7 @@ class WebViewActivity : BaseActivity() {
preferences = PreferenceManager.getDefaultSharedPreferences(this@WebViewActivity) preferences = PreferenceManager.getDefaultSharedPreferences(this@WebViewActivity)
webViewClient = object : AccompanistWebViewClient() { webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) { override fun onPageFinished(view: WebView?, url: String?) {
webView = view webView = view
super.onPageFinished(view, url) super.onPageFinished(view, url)
@ -153,7 +158,7 @@ class WebViewActivity : BaseActivity() {
} }
webViewCompose.apply { webViewCompose.apply {
setContent { WebViewView() } setContent { WebViewView(incognito, webViewClient) }
} }
} }
@ -176,57 +181,58 @@ class WebViewActivity : BaseActivity() {
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
@Composable @Composable
fun WebViewView() { fun WebViewView(
val webViewChromeClient = remember { incognito: Boolean,
object : AccompanistWebChromeClient() { webViewClient: WebViewClient,
) {
val context = LocalContext.current
val cookieManager = remember { CookieManager.getInstance() }
val webView = remember {
WebView(context).apply {
settings.run {
javaScriptEnabled = true
javaScriptCanOpenWindowsAutomatically = true
if (!incognito) {
cacheMode = WebSettings.LOAD_DEFAULT
domStorageEnabled = true
setGeolocationEnabled(true)
} else {
cacheMode = WebSettings.LOAD_NO_CACHE
domStorageEnabled = false
setGeolocationEnabled(false)
WebStorage.getInstance().deleteAllData()
clearHistory()
clearCache(true)
clearFormData()
}
if (Build.VERSION.SDK_INT >= 26) {
safeBrowsingEnabled = true
}
}
cookieManager.setAcceptCookie(true)
cookieManager.setAcceptThirdPartyCookies(this, true)
this.webViewClient = webViewClient
this.webChromeClient = object : WebChromeClient() {}
} }
} }
Scaffold(modifier = Modifier.Companion.fillMaxSize()) { paddingValues -> Scaffold(modifier = Modifier.fillMaxSize()) { padding ->
com.google.accompanist.web.WebView( AndroidView(
state = rememberWebViewState(url), modifier = Modifier
client = webViewClient, .padding(padding)
chromeClient = webViewChromeClient,
modifier = Modifier.Companion
.padding(paddingValues)
.fillMaxSize(), .fillMaxSize(),
captureBackPresses = false, factory = { webView },
factory = { context ->
WebView(context).apply {
settings.run {
if (!incognito) {
cacheMode = WebSettings.LOAD_DEFAULT
domStorageEnabled = true
setGeolocationEnabled(true)
} else {
cacheMode = WebSettings.LOAD_NO_CACHE
domStorageEnabled = false
setGeolocationEnabled(false)
WebStorage.getInstance().deleteAllData()
this@apply.clearHistory()
this@apply.clearCache(true)
this@apply.clearFormData()
}
javaScriptEnabled = true
javaScriptCanOpenWindowsAutomatically = true
if (Build.VERSION.SDK_INT >= 26) {
safeBrowsingEnabled = true
}
preferences.edit().putString("useragent_header", userAgentString)
.apply()
}
cookieManager.setAcceptCookie(true)
cookieManager.setAcceptThirdPartyCookies(this, true)
}
}
) )
} }
} }
companion object { companion object {
const val TAG = "WebViewActivity" const val TAG = "WebViewActivity"
} }

View file

@ -7,7 +7,6 @@ import androidx.preference.EditTextPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.preference.SwitchPreferenceCompat import androidx.preference.SwitchPreferenceCompat
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.util.UiUtil import com.deniscerri.ytdl.util.UiUtil
@ -78,8 +77,8 @@ class ProcessingSettingsFragment : BaseSettingsFragment() {
findPreference<Preference>("audio_bitrate")?.apply { findPreference<Preference>("audio_bitrate")?.apply {
var currentValue = prefs.getString("audio_bitrate", "")!! var currentValue = prefs.getString("audio_bitrate", "")!!
val entries = context.getStringArray(R.array.audio_bitrate) val entries = context.resources.getStringArray(R.array.audio_bitrate)
val entryValues = context.getStringArray(R.array.audio_bitrate_values) val entryValues = context.resources.getStringArray(R.array.audio_bitrate_values)
summary = if (currentValue.isNotBlank()) { summary = if (currentValue.isNotBlank()) {
entries[entryValues.indexOf(currentValue)] entries[entryValues.indexOf(currentValue)]

View file

@ -12,7 +12,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.ui.adapter.SortableTextItemAdapter import com.deniscerri.ytdl.ui.adapter.SortableTextItemAdapter
import com.deniscerri.ytdl.ui.more.settings.BaseSettingsFragment import com.deniscerri.ytdl.ui.more.settings.BaseSettingsFragment
@ -43,8 +42,8 @@ class AdvancedSettingsFragment : BaseSettingsFragment() {
formatImportanceAudio?.apply { formatImportanceAudio?.apply {
title = "${getString(R.string.format_importance)} [${getString(R.string.audio)}]" title = "${getString(R.string.format_importance)} [${getString(R.string.audio)}]"
val items = requireContext().getStringArray(R.array.format_importance_audio) val items = requireContext().resources.getStringArray(R.array.format_importance_audio)
val itemValues = requireContext().getStringArray(R.array.format_importance_audio_values).toSet() val itemValues = requireContext().resources.getStringArray(R.array.format_importance_audio_values).toSet()
val prefVideo = prefs.getString("format_importance_audio", itemValues.joinToString(","))!! val prefVideo = prefs.getString("format_importance_audio", itemValues.joinToString(","))!!
summary = prefVideo.split(",").mapIndexed { index, s -> "${index + 1}. ${items[itemValues.indexOf(s)]}" }.joinToString("\n") summary = prefVideo.split(",").mapIndexed { index, s -> "${index + 1}. ${items[itemValues.indexOf(s)]}" }.joinToString("\n")
@ -65,8 +64,8 @@ class AdvancedSettingsFragment : BaseSettingsFragment() {
formatImportanceVideo?.apply { formatImportanceVideo?.apply {
title = "${getString(R.string.format_importance)} [${getString(R.string.video)}]" title = "${getString(R.string.format_importance)} [${getString(R.string.video)}]"
val items = requireContext().getStringArray(R.array.format_importance_video) val items = requireContext().resources.getStringArray(R.array.format_importance_video)
val itemValues = requireContext().getStringArray(R.array.format_importance_video_values).toSet() val itemValues = requireContext().resources.getStringArray(R.array.format_importance_video_values).toSet()
val prefVideo = prefs.getString("format_importance_video", itemValues.joinToString(","))!! val prefVideo = prefs.getString("format_importance_video", itemValues.joinToString(","))!!
summary = prefVideo.split(",").mapIndexed { index, s -> "${index + 1}. ${items[itemValues.indexOf(s)]}" }.joinToString("\n") summary = prefVideo.split(",").mapIndexed { index, s -> "${index + 1}. ${items[itemValues.indexOf(s)]}" }.joinToString("\n")

View file

@ -27,7 +27,6 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.YoutubePlayerClientItem import com.deniscerri.ytdl.database.models.YoutubePlayerClientItem
import com.deniscerri.ytdl.database.models.YoutubePoTokenItem import com.deniscerri.ytdl.database.models.YoutubePoTokenItem
@ -134,7 +133,7 @@ class YoutubePlayerClientFragment : Fragment(), YoutubePlayerClientAdapter.OnIte
val contentLinear : LinearLayout = bottomSheet.findViewById(R.id.contentLinear)!! val contentLinear : LinearLayout = bottomSheet.findViewById(R.id.contentLinear)!!
val defaultChips = requireContext().getStringArray(R.array.youtube_player_clients).toMutableSet() val defaultChips = requireContext().resources.getStringArray(R.array.youtube_player_clients).toMutableSet()
title.isEndIconVisible = false title.isEndIconVisible = false
title.editText!!.addTextChangedListener(object : TextWatcher { title.editText!!.addTextChangedListener(object : TextWatcher {

View file

@ -22,7 +22,6 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.work.WorkManager import androidx.work.WorkManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.models.CookieItem import com.deniscerri.ytdl.database.models.CookieItem
import com.deniscerri.ytdl.database.models.YoutubeGeneratePoTokenItem import com.deniscerri.ytdl.database.models.YoutubeGeneratePoTokenItem
@ -117,7 +116,7 @@ class GenerateYoutubePoTokensFragment : Fragment() {
visitorData.setOnClickListener(clicker) visitorData.setOnClickListener(clicker)
playerClientDiv.setOnClickListener { playerClientDiv.setOnClickListener {
val webClients = requireContext().getStringArray(R.array.web_player_clients) val webClients = requireContext().resources.getStringArray(R.array.web_player_clients)
val selectedItems = webClients.map { val selectedItems = webClients.map {
conf.clients.contains(it) conf.clients.contains(it)

View file

@ -9,9 +9,11 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import android.view.MenuItem import android.view.MenuItem
import android.webkit.CookieManager import android.webkit.CookieManager
import android.webkit.WebChromeClient
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebStorage import android.webkit.WebStorage
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -20,6 +22,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.forEach import androidx.core.view.forEach
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -49,7 +53,7 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
private lateinit var toolbar: MaterialToolbar private lateinit var toolbar: MaterialToolbar
private lateinit var generateBtn: MaterialButton private lateinit var generateBtn: MaterialButton
private lateinit var cookieManager: CookieManager private lateinit var cookieManager: CookieManager
private lateinit var webViewClient: AccompanistWebViewClient private lateinit var webViewClient: WebViewClient
private lateinit var cookiesViewModel: CookieViewModel private lateinit var cookiesViewModel: CookieViewModel
private lateinit var preferences: SharedPreferences private lateinit var preferences: SharedPreferences
@ -95,7 +99,7 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
preferences = PreferenceManager.getDefaultSharedPreferences(this@PoTokenWebViewLoginActivity) preferences = PreferenceManager.getDefaultSharedPreferences(this@PoTokenWebViewLoginActivity)
preferences.edit().putString("genenerate_youtube_po_token_preferred_url", url).apply() preferences.edit().putString("genenerate_youtube_po_token_preferred_url", url).apply()
webViewClient = object : AccompanistWebViewClient() { webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) { override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url) super.onPageFinished(view, url)
kotlin.runCatching { kotlin.runCatching {
@ -184,7 +188,7 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
} }
webViewCompose.apply { webViewCompose.apply {
setContent { WebViewView(url) } setContent { WebViewView(url, webViewClient) }
} }
} }
@ -208,38 +212,36 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
@SuppressLint("SetJavaScriptEnabled", "JavascriptInterface") @SuppressLint("SetJavaScriptEnabled", "JavascriptInterface")
@Composable @Composable
fun WebViewView(url: String) { fun WebViewView(url: String, webViewClient: WebViewClient) {
val webViewChromeClient = remember { val context = LocalContext.current
object : AccompanistWebChromeClient() { val cookieManager = remember { CookieManager.getInstance() }
val webView = remember {
WebView(context).apply {
webView = this
clearHistory()
clearCache(true)
clearFormData()
settings.run {
cacheMode = WebSettings.LOAD_NO_CACHE
domStorageEnabled = false
setGeolocationEnabled(false)
javaScriptEnabled = true
javaScriptCanOpenWindowsAutomatically = true
if (Build.VERSION.SDK_INT >= 26) {
safeBrowsingEnabled = true
}
}
cookieManager.setAcceptThirdPartyCookies(this, true)
} }
} }
Scaffold(modifier = Modifier.fillMaxSize()) { paddingValues -> Scaffold(modifier = Modifier.fillMaxSize()) { padding ->
WebView( AndroidView(
state = rememberWebViewState(url), client = webViewClient, chromeClient = webViewChromeClient,
modifier = Modifier modifier = Modifier
.padding(paddingValues) .padding(padding)
.fillMaxSize(), .fillMaxSize(),
captureBackPresses = false, factory = { context -> factory = { webView },
WebStorage.getInstance().deleteAllData()
WebView(context).apply {
webView = this
clearHistory()
clearCache(true)
clearFormData()
settings.run {
cacheMode = WebSettings.LOAD_NO_CACHE
domStorageEnabled = false
setGeolocationEnabled(false)
javaScriptEnabled = true
javaScriptCanOpenWindowsAutomatically = true
if (Build.VERSION.SDK_INT >= 26) {
safeBrowsingEnabled = true
}
}
cookieManager.setAcceptThirdPartyCookies(this, true)
}
}
) )
} }
} }

View file

@ -3,6 +3,7 @@ package com.deniscerri.ytdl.util
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.DBManager
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.LogItem import com.deniscerri.ytdl.database.models.LogItem
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
@ -29,7 +30,7 @@ class CrashListener(private val context: Context) : Thread.UncaughtExceptionHand
title = "APP CRASH", title = "APP CRASH",
content = message, content = message,
format = Format("", "", "", "", "", 0, "", "", "", "", "", ""), format = Format("", "", "", "", "", 0, "", "", "", "", "", ""),
downloadType = DownloadViewModel.Type.command, downloadType = DownloadType.command,
downloadTime = System.currentTimeMillis() downloadTime = System.currentTimeMillis()
)) ))
} }

View file

@ -55,7 +55,6 @@ import com.google.android.material.chip.Chip
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.neoutils.highlight.core.Highlight import com.neoutils.highlight.core.Highlight
import com.neoutils.highlight.core.scheme.TextColorScheme import com.neoutils.highlight.core.scheme.TextColorScheme
import com.neoutils.highlight.core.util.Match
import com.neoutils.highlight.core.util.UiColor import com.neoutils.highlight.core.util.UiColor
import com.neoutils.highlight.view.extension.applyTo import com.neoutils.highlight.view.extension.applyTo
import com.neoutils.highlight.view.extension.removeAllSpans import com.neoutils.highlight.view.extension.removeAllSpans
@ -73,6 +72,7 @@ import java.io.File
import java.net.HttpCookie import java.net.HttpCookie
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.math.abs import kotlin.math.abs
import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.hours
@ -88,10 +88,18 @@ object Extensions {
} }
private var textHighlightSchemes = listOf( private var textHighlightSchemes = listOf(
TextColorScheme(regex = "([\"'])(?:\\\\1|.)*?\\1".toRegex(), match = Match.fully(UiColor.Hex("#FC8500"))), TextColorScheme(
TextColorScheme(regex = "yt-dlp".toRegex(), match = Match.fully(UiColor.Hex("#77eb09"))), regex = "([\"'])(?:\\\\1|.)*?\\1".toRegex(),
TextColorScheme(regex = "(https?://(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?://(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})".toRegex(), match = Match.fully(UiColor.Hex("#b5942f"))), matcher = com.neoutils.highlight.core.util.Matcher.fully(UiColor.Hex("#FC8500"))),
TextColorScheme(regex = "\\d+(\\.\\d)?%".toRegex(), match = Match.fully(UiColor.Hex("#43a564"))), TextColorScheme(
regex = "yt-dlp".toRegex(),
matcher = com.neoutils.highlight.core.util.Matcher.fully(UiColor.Hex("#77eb09"))),
TextColorScheme(
regex = "(https?://(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?://(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})".toRegex(),
matcher = com.neoutils.highlight.core.util.Matcher.fully(UiColor.Hex("#b5942f"))),
TextColorScheme(
regex = "\\d+(\\.\\d)?%".toRegex(),
matcher = com.neoutils.highlight.core.util.Matcher.fully(UiColor.Hex("#43a564"))),
) )
fun View.enableTextHighlight(){ fun View.enableTextHighlight(){
@ -304,6 +312,7 @@ object Extensions {
if (nr > 0) { if (nr > 0) {
val badge = BadgeDrawable.create(context).apply { val badge = BadgeDrawable.create(context).apply {
number = nr number = nr
badgeTextColor = context.getColor(R.color.black)
backgroundColor = context.getColor(R.color.white) backgroundColor = context.getColor(R.color.white)
verticalOffset = dpToPx(context.resources, 20f) verticalOffset = dpToPx(context.resources, 20f)
horizontalOffset = horizontalOffset =
@ -347,12 +356,14 @@ object Extensions {
return lines.distinct().filterNot { return lines.distinct().filterNot {
it.contains("[download") && !finishingProgressLinesRegex.matcher(it).find() (it.contains("[download") && !finishingProgressLinesRegex.matcher(it).find())
|| it.contains("does not pass filter (id")
}.joinToString("\n") + newline }.joinToString("\n") + newline
} }
return lines.filterNot { return lines.filterNot {
it.contains("[download") && !finishingProgressLinesRegex.matcher(it).find() (it.contains("[download") && !finishingProgressLinesRegex.matcher(it).find())
|| it.contains("does not pass filter (id")
}.joinToString("\n") }.joinToString("\n")
} }

View file

@ -6,8 +6,6 @@ import android.media.MediaScannerConnection
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
import android.os.UserHandle
import android.os.UserManager
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
@ -28,7 +26,6 @@ import com.yausername.youtubedl_android.YoutubeDLRequest
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.internal.closeQuietly import okhttp3.internal.closeQuietly
import okhttp3.internal.lowercase
import java.io.File import java.io.File
import java.net.URLDecoder import java.net.URLDecoder
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets

View file

@ -21,6 +21,7 @@ import androidx.documentfile.provider.DocumentFile
import androidx.navigation.NavDeepLinkBuilder import androidx.navigation.NavDeepLinkBuilder
import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.MainActivity
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.receiver.CancelDownloadNotificationReceiver import com.deniscerri.ytdl.receiver.CancelDownloadNotificationReceiver
import com.deniscerri.ytdl.receiver.CancelWorkReceiver import com.deniscerri.ytdl.receiver.CancelWorkReceiver
@ -230,20 +231,20 @@ class NotificationUtil(var context: Context) {
fun createDownloadFinished( fun createDownloadFinished(
id: Long, id: Long,
title: String?, title: String?,
downloadType: DownloadViewModel.Type, downloadType: DownloadType,
filepath: List<String>?, filepath: List<String>?,
res: Resources res: Resources
) { ) {
val notificationBuilder = getBuilder(DOWNLOAD_FINISHED_CHANNEL_ID) val notificationBuilder = getBuilder(DOWNLOAD_FINISHED_CHANNEL_ID)
val iconType = when(downloadType){ val iconType = when(downloadType){
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
R.drawable.ic_music R.drawable.ic_music
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
R.drawable.ic_video R.drawable.ic_video
} }
DownloadViewModel.Type.command -> { DownloadType.command -> {
R.drawable.ic_terminal R.drawable.ic_terminal
} }

View file

@ -56,6 +56,7 @@ import androidx.preference.PreferenceManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.afollestad.materialdialogs.utils.MDUtil.textChanged import com.afollestad.materialdialogs.utils.MDUtil.textChanged
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.CommandTemplate import com.deniscerri.ytdl.database.models.CommandTemplate
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
@ -376,7 +377,7 @@ object UiUtil {
val chip = context.layoutInflater.inflate(R.layout.suggestion_chip, shortcutsChipGroup, false) as Chip val chip = context.layoutInflater.inflate(R.layout.suggestion_chip, shortcutsChipGroup, false) as Chip
chip.text = shortcut.content chip.text = shortcut.content
chip.setOnClickListener { chip.setOnClickListener {
content.editText!!.text.insert(content.editText!!.selectionStart, shortcut.content + " ") content.editText!!.text.insert(content.editText!!.selectionStart, shortcut.content)
} }
shortcutsChipGroup.addView(chip) shortcutsChipGroup.addView(chip)
} }
@ -590,10 +591,10 @@ object UiUtil {
val btn = bottomSheet.findViewById<FloatingActionButton>(R.id.download_button_type) val btn = bottomSheet.findViewById<FloatingActionButton>(R.id.download_button_type)
val typeImageResource: Int = val typeImageResource: Int =
when (item.type) { when (item.type) {
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
R.drawable.ic_music R.drawable.ic_music
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
R.drawable.ic_video R.drawable.ic_video
} }
else -> { else -> {
@ -637,7 +638,7 @@ object UiUtil {
} }
} }
if (item.type != DownloadViewModel.Type.command){ if (item.type != DownloadType.command){
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility = if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
View.GONE View.GONE
else formatNote!!.text = item.format.format_note else formatNote!!.text = item.format.format_note
@ -731,7 +732,7 @@ object UiUtil {
bottomSheet.cancel() bottomSheet.cancel()
} }
download?.setOnLongClickListener { download?.setOnLongClickListener {
longClickDownloadButton(item) downloadItem(item)
bottomSheet.cancel() bottomSheet.cancel()
true true
} }
@ -794,13 +795,13 @@ object UiUtil {
val btn = bottomSheet.findViewById<FloatingActionButton>(R.id.download_button_type) val btn = bottomSheet.findViewById<FloatingActionButton>(R.id.download_button_type)
val typeImageResource: Int = val typeImageResource: Int =
if (item!!.type == DownloadViewModel.Type.audio) { if (item!!.type == DownloadType.audio) {
if (isPresent) { if (isPresent) {
R.drawable.ic_music_downloaded R.drawable.ic_music_downloaded
} else { } else {
R.drawable.ic_music R.drawable.ic_music
} }
} else if (item.type == DownloadViewModel.Type.video) { } else if (item.type == DownloadType.video) {
if (isPresent) { if (isPresent) {
R.drawable.ic_video_downloaded R.drawable.ic_video_downloaded
} else { } else {
@ -857,7 +858,7 @@ object UiUtil {
} }
} }
if (item.type != DownloadViewModel.Type.command){ if (item.type != DownloadType.command){
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility = if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
View.GONE View.GONE
else formatNote!!.text = item.format.format_note else formatNote!!.text = item.format.format_note

View file

@ -71,7 +71,7 @@ class NewPipeUtil(context: Context) {
val streamInfo = StreamInfo.getInfo(url) val streamInfo = StreamInfo.getInfo(url)
createVideoFromStream(streamInfo, url, true).apply { createVideoFromStream(streamInfo, url, true).apply {
if (this!!.formats.isEmpty()) return Result.failure(Throwable()) if (this!!.formats.isEmpty()) return Result.failure(Throwable())
formatCollection.add(this.formats) formatCollection.add(this.formats.toMutableList())
progress(ResultViewModel.MultipleFormatProgress(url, this.formats)) progress(ResultViewModel.MultipleFormatProgress(url, this.formats))
} }
} }

View file

@ -13,6 +13,7 @@ import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.anggrayudi.storage.extension.count import com.anggrayudi.storage.extension.count
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.dao.CommandTemplateDao import com.deniscerri.ytdl.database.dao.CommandTemplateDao
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.ChapterItem import com.deniscerri.ytdl.database.models.ChapterItem
import com.deniscerri.ytdl.database.models.DownloadItem import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
@ -46,6 +47,7 @@ import java.util.Base64
import java.util.Locale import java.util.Locale
import java.util.StringJoiner import java.util.StringJoiner
import java.util.UUID import java.util.UUID
import java.util.zip.CRC32
class YTDLPUtil(private val context: Context, private val commandTemplateDao: CommandTemplateDao) { class YTDLPUtil(private val context: Context, private val commandTemplateDao: CommandTemplateDao) {
private var sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) private var sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
@ -605,10 +607,16 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
id = url.getIDFromYoutubeURL() ?: url id = url.getIDFromYoutubeURL() ?: url
} }
val infoJsonName = MessageDigest.getInstance("MD5").digest(id.toByteArray()).toHexString() val infoJsonName = hash(id)
//yt-dlp doesnt overwrite info json, so delete manually //yt-dlp doesnt overwrite info json, so delete manually
File("${cachePath}/${infoJsonName}video.info.json").delete() File("${cachePath}/${infoJsonName}video.info.json").delete()
this.addCommands(listOf("--print-to-file", "video:%()j", "${cachePath}/${infoJsonName}video.info.json")) this.addCommands(listOf("--print-to-file", "video:%()j", "${cachePath}/${infoJsonName}${System.currentTimeMillis()}video.info.json"))
}
fun hash(text: String): String {
val crc = CRC32()
crc.update(text.toByteArray())
return crc.value.toString(16) // 8 hex chars max
} }
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
@ -620,18 +628,14 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
id = url.getIDFromYoutubeURL() ?: url id = url.getIDFromYoutubeURL() ?: url
} }
val infoJsonName = MessageDigest.getInstance("MD5").digest(id.toByteArray()).toHexString() val infoJsonName = hash(id)
var infoJsonFile : File? = null val infoJsonFile : File? =
File(cachePath).walkBottomUp().filter { it.name.startsWith(infoJsonName) }.forEach { File(cachePath)
if (it.name == "${infoJsonName}playlist.info.json") { .walkBottomUp()
infoJsonFile = it .sortedByDescending { it.lastModified() }
return@forEach .filter { it.name.startsWith(infoJsonName) }
} .firstOrNull()
if (it.name == "${infoJsonName}video.info.json") {
infoJsonFile = it
}
}
return infoJsonFile return infoJsonFile
} }
@ -853,7 +857,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
val downDir : File val downDir : File
val canWrite = File(FileUtil.formatPath(downloadItem.downloadPath)).canWrite() val canWrite = File(FileUtil.formatPath(downloadItem.downloadPath)).canWrite()
val writtenPath = type == DownloadViewModel.Type.command && downloadItem.format.format_note.contains("-P ") val writtenPath = type == DownloadType.command && downloadItem.format.format_note.contains("-P ")
if (writtenPath || (!sharedPreferences.getBoolean("cache_downloads", true) && canWrite)){ if (writtenPath || (!sharedPreferences.getBoolean("cache_downloads", true) && canWrite)){
downDir = File(FileUtil.formatPath(downloadItem.downloadPath)) downDir = File(FileUtil.formatPath(downloadItem.downloadPath))
@ -926,7 +930,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
val thumbnailFormat = sharedPreferences.getString("thumbnail_format", "jpg") val thumbnailFormat = sharedPreferences.getString("thumbnail_format", "jpg")
var filenameTemplate = downloadItem.customFileNameTemplate var filenameTemplate = downloadItem.customFileNameTemplate
if(downloadItem.type != DownloadViewModel.Type.command){ if(downloadItem.type != DownloadType.command){
if (sharedPreferences.getBoolean("no_part", false)){ if (sharedPreferences.getBoolean("no_part", false)){
request.addOption("--no-part") request.addOption("--no-part")
} }
@ -944,7 +948,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
} }
val sponsorBlockFilters : ArrayList<String> = when(downloadItem.type) { val sponsorBlockFilters : ArrayList<String> = when(downloadItem.type) {
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
downloadItem.audioPreferences.sponsorBlockFilters downloadItem.audioPreferences.sponsorBlockFilters
} }
//video //video
@ -971,6 +975,8 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
metadataCommands.addOption("--parse-metadata", "%(title)s:%(meta_title)s") metadataCommands.addOption("--parse-metadata", "%(title)s:%(meta_title)s")
} }
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist,creators," else ""
metadataCommands.addOption("--parse-metadata", """%(${useArtistTags}uploader,channel,creator|)l:^(?P<uploader>.*?)(?:(?= - Topic)|$)""")
if (downloadItem.author.isNotBlank()){ if (downloadItem.author.isNotBlank()){
metadataCommands.addOption("--replace-in-metadata", "uploader", """^.*$""", downloadItem.author.replace("""\""", """\\""")) metadataCommands.addOption("--replace-in-metadata", "uploader", """^.*$""", downloadItem.author.replace("""\""", """\\"""))
@ -1029,9 +1035,11 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
var aCodecPref = runCatching { context.getStringArray(R.array.audio_codec_values_ytdlp)[aCodecPrefIndex] }.getOrElse { "" } var aCodecPref = runCatching { context.getStringArray(R.array.audio_codec_values_ytdlp)[aCodecPrefIndex] }.getOrElse { "" }
when(type){ when(type){
DownloadViewModel.Type.audio -> { DownloadType.audio -> {
val supportedContainers = context.resources.getStringArray(R.array.audio_containers) val supportedContainers = context.resources.getStringArray(R.array.audio_containers)
val preferredLanguage = sharedPreferences.getString("audio_language","")!! val preferredLanguage = sharedPreferences.getString("audio_language","")!!
val formatImportance = formatUtil.getAudioFormatImportance()
var abrSort = "" var abrSort = ""
var audioQualityId : String = downloadItem.format.format_id var audioQualityId : String = downloadItem.format.format_id
@ -1046,7 +1054,11 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
} }
if ((audioQualityId.isBlank() || audioQualityId == "ba/b") && preferredLanguage.isNotBlank()) { if ((audioQualityId.isBlank() || audioQualityId == "ba/b") && preferredLanguage.isNotBlank()) {
audioQualityId = "ba[language^=$preferredLanguage]/ba/b" audioQualityId = "ba[language^=$preferredLanguage]/${audioQualityId.ifEmpty { "ba/b" }}"
}
if ((audioQualityId.isBlank() || audioQualityId == "ba/b") && formatImportance.contains("prefer_drc")) {
audioQualityId = "ba[format_id$=-drc]/${audioQualityId.ifEmpty { "ba/b" }}"
} }
if (audioQualityId.isNotBlank()) { if (audioQualityId.isNotBlank()) {
@ -1065,7 +1077,6 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
val ext = downloadItem.container val ext = downloadItem.container
val formatSorting = mutableListOf<String>() val formatSorting = mutableListOf<String>()
val formatImportance = formatUtil.getAudioFormatImportance()
val useCustomFormatSorting = sharedPreferences.getBoolean("use_format_sorting", false) val useCustomFormatSorting = sharedPreferences.getBoolean("use_format_sorting", false)
if (useCustomFormatSorting) { if (useCustomFormatSorting) {
formatSorting.add("hasaud") formatSorting.add("hasaud")
@ -1120,12 +1131,6 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
request.addOption("-P", downDir.absolutePath) request.addOption("-P", downDir.absolutePath)
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
if (downloadItem.author.isBlank()) {
metadataCommands.addOption("--parse-metadata", """%(${useArtistTags}uploader,channel,creator|)l:^(?P<uploader>.*?)(?:(?= - Topic)|$)""")
}
if (downloadItem.audioPreferences.splitByChapters && downloadItem.downloadSections.isBlank()){ if (downloadItem.audioPreferences.splitByChapters && downloadItem.downloadSections.isBlank()){
request.addOption("--split-chapters") request.addOption("--split-chapters")
request.addOption("-o", "chapter:%(section_title)s.%(ext)s") request.addOption("-o", "chapter:%(section_title)s.%(ext)s")
@ -1196,12 +1201,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
} }
} }
DownloadViewModel.Type.video -> { DownloadType.video -> {
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
if (downloadItem.author.isBlank()) {
metadataCommands.addOption("--parse-metadata", """%(${useArtistTags}uploader,channel,creator|null)l:^(?P<uploader>.*?)(?:(?= - Topic)|$)""")
}
val supportedContainers = context.resources.getStringArray(R.array.video_containers) val supportedContainers = context.resources.getStringArray(R.array.video_containers)
if (downloadItem.videoPreferences.addChapters) { if (downloadItem.videoPreferences.addChapters) {
@ -1486,7 +1486,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
} }
} }
DownloadViewModel.Type.command -> { DownloadType.command -> {
if (!writtenPath) { if (!writtenPath) {
request.addOption("-P", downDir.absolutePath) request.addOption("-P", downDir.absolutePath)
} }
@ -1499,15 +1499,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
request.merge(metadataCommands) request.merge(metadataCommands)
if (downloadItem.extraCommands.isNotBlank() && downloadItem.type != DownloadViewModel.Type.command){ if (downloadItem.extraCommands.isNotBlank() && downloadItem.type != DownloadType.command){
// check for cache dir as extra command and add it as an actual option to prevent --no-cache-dir in youtubedl_android
val cacheDirArg = """--cache-dir\s+(?:"([^"]+)"|(\S+))""".toRegex().find(downloadItem.extraCommands)
if (cacheDirArg != null) {
ytDlRequest.addOption("--cache-dir", cacheDirArg.groupValues.last().replace("\"", ""))
runCatching {
downloadItem.extraCommands = downloadItem.extraCommands.replace(cacheDirArg.value, "")
}
}
request.addOption(downloadItem.extraCommands) request.addOption(downloadItem.extraCommands)
} }
@ -1518,13 +1510,14 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
val cache = File(FileUtil.getCachePath(context)) val cache = File(FileUtil.getCachePath(context))
cache.mkdirs() cache.mkdirs()
val conf = val conf = File(cache.absolutePath + "/${System.currentTimeMillis()}${UUID.randomUUID()}.txt")
File(cache.absolutePath + "/${System.currentTimeMillis()}${UUID.randomUUID()}.txt")
conf.createNewFile() conf.createNewFile()
conf.writeText(request.toString()) conf.writeText(request.toString())
val tmp = mutableListOf<String>() val tmp = mutableListOf<String>()
tmp.addOption("--config-locations", conf.absolutePath) tmp.addOption("--config-locations", conf.absolutePath)
ytDlRequest.addCommands(tmp) ytDlRequest.addCommands(tmp)
ytDlRequest.addOption("--cache-dir", cache.absolutePath)
return ytDlRequest return ytDlRequest
} }
} }

View file

@ -15,6 +15,7 @@ import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.deniscerri.ytdl.R import com.deniscerri.ytdl.R
import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.DBManager
import com.deniscerri.ytdl.database.enums.DownloadType
import com.deniscerri.ytdl.database.models.Format import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.LogItem import com.deniscerri.ytdl.database.models.LogItem
import com.deniscerri.ytdl.database.repository.LogRepository import com.deniscerri.ytdl.database.repository.LogRepository
@ -107,7 +108,7 @@ class TerminalDownloadWorker(
"Terminal Task", "Terminal Task",
initialLogDetails, initialLogDetails,
Format(), Format(),
DownloadViewModel.Type.command, DownloadType.command,
System.currentTimeMillis(), System.currentTimeMillis(),
) )

View file

@ -57,8 +57,7 @@ class UpdateMultipleDownloadsFormatsWorker(
d.allFormats.addAll(resultRepo.getFormats(d.url)) d.allFormats.addAll(resultRepo.getFormats(d.url))
d.format = vm.getFormat(d.allFormats,d.type) d.format = vm.getFormat(d.allFormats,d.type)
r?.formats?.clear() r?.formats = d.allFormats
r?.formats?.addAll(d.allFormats)
runBlocking { runBlocking {
r?.apply { resDao.update(this) } r?.apply { resDao.update(this) }

View file

@ -8,6 +8,7 @@
<item>flac</item> <item>flac</item>
<item>opus</item> <item>opus</item>
<item>wav</item> <item>wav</item>
<item>vorbis</item>
</string-array> </string-array>
<string-array name="audio_containers_values"> <string-array name="audio_containers_values">
@ -19,6 +20,7 @@
<item>flac</item> <item>flac</item>
<item>opus</item> <item>opus</item>
<item>wav</item> <item>wav</item>
<item>vorbis</item>
</string-array> </string-array>
<string-array name="video_containers"> <string-array name="video_containers">

View file

@ -5,9 +5,6 @@ buildscript {
ext { ext {
abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'x86_64': 3, 'arm64-v8a': 4] abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'x86_64': 3, 'arm64-v8a': 4]
// dependency versions // dependency versions
appCompatVer = '1.7.0'
junitVer = '4.13.2'
androidJunitVer = '1.1.5'
espressoVer = '3.6.1' espressoVer = '3.6.1'
jacksonVer = '2.9.8' jacksonVer = '2.9.8'
// supports java 1.6 // supports java 1.6
@ -18,17 +15,10 @@ buildscript {
youtubedlAndroidVerNoPyCrypto = "97bee6c0e8" youtubedlAndroidVerNoPyCrypto = "97bee6c0e8"
youtubedlAndroidVerMine = "8831745ea3" youtubedlAndroidVerMine = "8831745ea3"
oldytdlAndroidVer = "0.14.0" oldytdlAndroidVer = "0.14.0"
workVer = "2.10.0"
composeVer = '1.4.2'
kotlinVer = "1.7.21"
coroutineVer = '1.7.3'
retrofitVer = "2.9.0" retrofitVer = "2.9.0"
kodeinVer = "7.16.0" kodeinVer = "7.16.0"
navVer = "2.8.9"
media3_version = "1.6.0"
agp_version = '8.1.0' agp_version = '8.1.0'
agp_version1 = '7.4.2' agp_version1 = '7.4.2'
roomVer = '2.5.2'
} }
repositories { repositories {
mavenCentral() mavenCentral()
@ -39,13 +29,13 @@ buildscript {
} }
plugins { plugins {
id 'com.android.application' version '8.5.2' apply false id 'com.android.application' version '8.13.2' apply false
id 'com.android.library' version '8.5.2' apply false id 'com.android.library' version '8.13.2' apply false
id 'org.jetbrains.kotlin.android' version '2.0.21' apply false id 'org.jetbrains.kotlin.android' version '2.3.0' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "2.0.21" apply false id "org.jetbrains.kotlin.plugin.serialization" version "2.3.0" apply false
id "org.jetbrains.kotlin.plugin.parcelize" version "2.0.21" apply false id "org.jetbrains.kotlin.plugin.parcelize" version "2.3.0" apply false
id 'com.android.test' version '8.5.2' apply false id 'com.android.test' version '8.13.2' apply false
id 'com.google.devtools.ksp' version '2.0.21-1.0.28' apply false id 'com.google.devtools.ksp' version '2.3.4' apply false
} }
tasks.register('clean', Delete) { tasks.register('clean', Delete) {

View file

@ -1,6 +1,6 @@
#Sun Mar 16 16:17:38 CET 2025 #Sun Mar 16 16:17:38 CET 2025
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists