From e2a5fd09d16768a7458b3e90220fd90958032b8a Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Wed, 2 Oct 2024 17:12:26 +0200 Subject: [PATCH 01/31] feat: add detekt setup --- build.gradle | 2 + config/detekt/detekt.yml | 682 ++++++++++++++++++++++++++++++++++++++ gradle/libs.versions.toml | 2 + 3 files changed, 686 insertions(+) create mode 100644 config/detekt/detekt.yml diff --git a/build.gradle b/build.gradle index 6fc0ba10acc..86ee228dcee 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,7 @@ buildscript { plugins { alias libs.plugins.sonarqube alias libs.plugins.ksp apply false + alias libs.plugins.detekt } allprojects { @@ -37,6 +38,7 @@ subprojects { apply plugin: "com.google.devtools.ksp" apply plugin: "org.jlleitschuh.gradle.ktlint" apply plugin: "org.sonarqube" + apply plugin: "io.gitlab.arturbosch.detekt" } sonarqube { diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml new file mode 100644 index 00000000000..9879910ba86 --- /dev/null +++ b/config/detekt/detekt.yml @@ -0,0 +1,682 @@ +build: + maxIssues: 0 + excludeCorrectable: false + weights: + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +config: + validation: true + warningsAsErrors: false + # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' + excludes: '' + +processors: + active: true + exclude: + - 'DetektProgressListener' + # - 'KtFileCountProcessor' + # - 'PackageCountProcessor' + # - 'ClassCountProcessor' + # - 'FunctionCountProcessor' + # - 'PropertyCountProcessor' + # - 'ProjectComplexityProcessor' + # - 'ProjectCognitiveComplexityProcessor' + # - 'ProjectLLOCProcessor' + # - 'ProjectCLOCProcessor' + # - 'ProjectLOCProcessor' + # - 'ProjectSLOCProcessor' + # - 'LicenseHeaderLoaderExtension' + +console-reports: + active: true + exclude: + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' + - 'FindingsReport' + - 'FileBasedFindingsReport' + # - 'LiteFindingsReport' + +output-reports: + active: true + exclude: + # - 'TxtOutputReport' + # - 'XmlOutputReport' + # - 'HtmlOutputReport' + +comments: + active: true + AbsentOrWrongFileLicense: + active: false + licenseTemplateFile: 'license.template' + licenseTemplateIsRegex: false + CommentOverPrivateFunction: + active: false + CommentOverPrivateProperty: + active: false + DeprecatedBlockTag: + active: false + EndOfSentenceFormat: + active: false + endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' + OutdatedDocumentation: + active: false + matchTypeParameters: true + matchDeclarationsOrder: true + allowParamOnConstructorProperties: false + UndocumentedPublicClass: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + UndocumentedPublicFunction: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UndocumentedPublicProperty: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + +complexity: + active: true + ComplexCondition: + active: true + threshold: 4 + ComplexInterface: + active: false + threshold: 10 + includeStaticDeclarations: false + includePrivateDeclarations: false + ComplexMethod: + active: true + threshold: 15 + ignoreSingleWhenExpression: false + ignoreSimpleWhenEntries: false + ignoreNestingFunctions: false + nestingFunctions: + - 'also' + - 'apply' + - 'forEach' + - 'isNotNull' + - 'ifNull' + - 'let' + - 'run' + - 'use' + - 'with' + LabeledExpression: + active: false + ignoredLabels: [] + LargeClass: + active: true + threshold: 600 + LongMethod: + active: true + threshold: 60 + LongParameterList: + active: true + functionThreshold: 6 + constructorThreshold: 7 + ignoreDefaultParameters: false + ignoreDataClasses: true + ignoreAnnotatedParameter: [] + MethodOverloading: + active: false + threshold: 6 + NamedArguments: + active: false + threshold: 3 + ignoreArgumentsMatchingNames: false + NestedBlockDepth: + active: true + threshold: 4 + ReplaceSafeCallChainWithRun: + active: false + StringLiteralDuplication: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + threshold: 3 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false + +coroutines: + active: true + GlobalCoroutineUsage: + active: false + InjectDispatcher: + active: false + dispatcherNames: + - 'IO' + - 'Default' + - 'Unconfined' + RedundantSuspendModifier: + active: false + SleepInsteadOfDelay: + active: false + SuspendFunWithCoroutineScopeReceiver: + active: false + SuspendFunWithFlowReturnType: + active: false + +empty-blocks: + active: true + EmptyCatchBlock: + active: true + allowedExceptionNameRegex: '_|(ignore|expected).*' + EmptyClassBlock: + active: true + EmptyDefaultConstructor: + active: true + EmptyDoWhileBlock: + active: true + EmptyElseBlock: + active: true + EmptyFinallyBlock: + active: true + EmptyForBlock: + active: true + EmptyFunctionBlock: + active: true + ignoreOverridden: false + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyTryBlock: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: true + methodNames: + - 'equals' + - 'finalize' + - 'hashCode' + - 'toString' + InstanceOfCheckForException: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + NotImplementedDeclaration: + active: false + ObjectExtendsThrowable: + active: false + PrintStackTrace: + active: true + RethrowCaughtException: + active: true + ReturnFromFinally: + active: true + ignoreLabeled: false + SwallowedException: + active: true + ignoredExceptionTypes: + - 'InterruptedException' + - 'MalformedURLException' + - 'NumberFormatException' + - 'ParseException' + allowedExceptionNameRegex: '_|(ignore|expected).*' + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptions: + - 'ArrayIndexOutOfBoundsException' + - 'Exception' + - 'IllegalArgumentException' + - 'IllegalMonitorStateException' + - 'IllegalStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + - 'Throwable' + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptionNames: + - 'ArrayIndexOutOfBoundsException' + - 'Error' + - 'Exception' + - 'IllegalMonitorStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + - 'Throwable' + allowedExceptionNameRegex: '_|(ignore|expected).*' + TooGenericExceptionThrown: + active: true + exceptionNames: + - 'Error' + - 'Exception' + - 'RuntimeException' + - 'Throwable' + +naming: + active: true + BooleanPropertyNaming: + active: false + allowedPattern: '^(is|has|are)' + ignoreOverridden: true + ClassNaming: + active: true + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + EnumNaming: + active: true + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + forbiddenName: [] + FunctionMaxLength: + active: false + maximumFunctionNameLength: 30 + FunctionMinLength: + active: false + minimumFunctionNameLength: 3 + FunctionNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + functionPattern: '[a-z][a-zA-Z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + FunctionParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + InvalidPackageDeclaration: + active: false + rootPackage: '' + requireRootInDeclaration: false + LambdaParameterNaming: + active: false + parameterPattern: '[a-z][A-Za-z0-9]*|_' + MatchingDeclarationName: + active: true + mustBeFirst: true + MemberNameEqualsClassName: + active: true + ignoreOverridden: true + NoNameShadowing: + active: false + NonBooleanPropertyPrefixedWithIs: + active: false + ObjectPropertyNaming: + active: true + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: true + packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' + TopLevelPropertyNaming: + active: true + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' + VariableMaxLength: + active: false + maximumVariableNameLength: 64 + VariableMinLength: + active: false + minimumVariableNameLength: 1 + VariableNaming: + active: true + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + +performance: + active: true + ArrayPrimitive: + active: true + ForEachOnRange: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + SpreadOperator: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + AvoidReferentialEquality: + active: false + forbiddenTypePatterns: + - 'kotlin.String' + CastToNullableType: + active: false + Deprecation: + active: false + DontDowncastCollectionTypes: + active: false + DoubleMutabilityForCollection: + active: false + mutableTypes: + - 'kotlin.collections.MutableList' + - 'kotlin.collections.MutableMap' + - 'kotlin.collections.MutableSet' + - 'java.util.ArrayList' + - 'java.util.LinkedHashSet' + - 'java.util.HashSet' + - 'java.util.LinkedHashMap' + - 'java.util.HashMap' + DuplicateCaseInWhenExpression: + active: true + ElseCaseInsteadOfExhaustiveWhen: + active: false + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExitOutsideMain: + active: false + ExplicitGarbageCollectionCall: + active: true + HasPlatformType: + active: false + IgnoredReturnValue: + active: false + restrictToAnnotatedMethods: true + returnValueAnnotations: + - '*.CheckResult' + - '*.CheckReturnValue' + ignoreReturnValueAnnotations: + - '*.CanIgnoreReturnValue' + ignoreFunctionCall: [] + ImplicitDefaultLocale: + active: true + ImplicitUnitReturnType: + active: false + allowExplicitReturnType: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreOnClassesPattern: '' + MapGetWithNotNullAssertionOperator: + active: false + MissingPackageDeclaration: + active: false + excludes: ['**/*.kts'] + MissingWhenCase: + active: true + allowElseExpression: true + NullCheckOnMutableProperty: + active: false + NullableToStringCall: + active: false + RedundantElseInWhen: + active: true + UnconditionalJumpStatementInLoop: + active: false + UnnecessaryNotNullOperator: + active: true + UnnecessarySafeCall: + active: true + UnreachableCatchBlock: + active: false + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnsafeCast: + active: true + UnusedUnaryOperator: + active: false + UselessPostfixExpression: + active: false + WrongEqualsTypeParameter: + active: true + +style: + active: true + CanBeNonNullable: + active: false + ClassOrdering: + active: false + CollapsibleIfStatements: + active: false + DataClassContainsFunctions: + active: false + conversionFunctionPrefix: 'to' + DataClassShouldBeImmutable: + active: false + DestructuringDeclarationWithTooManyEntries: + active: false + maxDestructuringEntries: 3 + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: false + ExplicitCollectionElementAccessMethod: + active: false + ExplicitItLambdaParameter: + active: false + ExpressionBodySyntax: + active: false + includeLineWrapping: false + ForbiddenComment: + active: true + values: + - 'FIXME:' + - 'STOPSHIP:' + - 'TODO:' + allowedPatterns: '' + customMessage: '' + ForbiddenImport: + active: false + imports: [] + forbiddenPatterns: '' + ForbiddenMethodCall: + active: false + methods: + - 'kotlin.io.print' + - 'kotlin.io.println' + ForbiddenPublicDataClass: + active: true + excludes: ['**'] + ignorePackages: + - '*.internal' + - '*.internal.*' + ForbiddenVoid: + active: false + ignoreOverridden: false + ignoreUsageInGenerics: false + FunctionOnlyReturningConstant: + active: true + ignoreOverridableFunction: true + ignoreActualFunction: true + excludedFunctions: '' + LibraryCodeMustSpecifyReturnType: + active: true + excludes: ['**'] + LibraryEntitiesShouldNotBePublic: + active: true + excludes: ['**'] + LoopWithTooManyJumpStatements: + active: true + maxJumpCount: 1 + MagicNumber: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreNumbers: + - '-1' + - '0' + - '1' + - '2' + ignoreHashCodeFunction: true + ignorePropertyDeclaration: false + ignoreLocalVariableDeclaration: false + ignoreConstantDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotation: false + ignoreNamedArgument: true + ignoreEnums: false + ignoreRanges: false + ignoreExtensionFunctions: true + MandatoryBracesIfStatements: + active: false + MandatoryBracesLoops: + active: false + MaxLineLength: + active: true + maxLineLength: 120 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + MayBeConst: + active: true + ModifierOrder: + active: true + MultilineLambdaItParameter: + active: false + NestedClassesVisibility: + active: true + NewLineAtEndOfFile: + active: true + NoTabs: + active: false + ObjectLiteralToLambda: + active: false + OptionalAbstractKeyword: + active: true + OptionalUnit: + active: false + OptionalWhenBraces: + active: false + PreferToOverPairSyntax: + active: false + ProtectedMemberInFinalClass: + active: true + RedundantExplicitType: + active: false + RedundantHigherOrderMapUsage: + active: false + RedundantVisibilityModifierRule: + active: false + ReturnCount: + active: true + max: 2 + excludedFunctions: 'equals' + excludeLabeled: false + excludeReturnFromLambda: true + excludeGuardClauses: false + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: true + SpacingBetweenPackageAndImports: + active: false + ThrowsCount: + active: true + max: 2 + excludeGuardClauses: false + TrailingWhitespace: + active: false + UnderscoresInNumericLiterals: + active: false + acceptableLength: 4 + allowNonStandardGrouping: false + UnnecessaryAbstractClass: + active: true + UnnecessaryAnnotationUseSiteTarget: + active: false + UnnecessaryApply: + active: true + UnnecessaryFilter: + active: false + UnnecessaryInheritance: + active: true + UnnecessaryInnerClass: + active: false + UnnecessaryLet: + active: false + UnnecessaryParentheses: + active: false + UntilInsteadOfRangeTo: + active: false + UnusedImports: + active: false + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: '(_|ignored|expected|serialVersionUID)' + UseAnyOrNoneInsteadOfFind: + active: false + UseArrayLiteralsInAnnotations: + active: false + UseCheckNotNull: + active: false + UseCheckOrError: + active: false + UseDataClass: + active: false + allowVars: false + UseEmptyCounterpart: + active: false + UseIfEmptyOrIfBlank: + active: false + UseIfInsteadOfWhen: + active: false + UseIsNullOrEmpty: + active: false + UseOrEmpty: + active: false + UseRequire: + active: false + UseRequireNotNull: + active: false + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: true + VarCouldBeVal: + active: true + WildcardImport: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + excludeImports: + - 'java.util.*' diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 841312da68b..0611eb9cb03 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,6 +22,7 @@ androidxTestMonitor = "1.6.1" androidxTestUiAutomator ="2.2.0" androidxWork = "2.8.1" coil = "2.2.2" +detekt="1.20.0" dexopener = "2.0.5" disklrucache = "2.0.2" media3 ="1.1.1" @@ -124,3 +125,4 @@ markwon = ["markwon-core", "markwon-ext-tables", "markwon-ext-strikethrough", "m kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } sonarqube = { id = "org.sonarqube", version.ref = "sonarqube" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } From eb34b48532c105f9d85d2575f138813cee158834 Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Fri, 4 Oct 2024 14:03:07 +0200 Subject: [PATCH 02/31] feat: add yml setup to execute in github actions --- .github/workflows/detekt.yml | 62 ++++++++++++++++++++++++++++++++++++ config/detekt/detekt.yml | 57 ++++++++++++++++----------------- 2 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/detekt.yml diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml new file mode 100644 index 00000000000..eb1d6b19ec9 --- /dev/null +++ b/.github/workflows/detekt.yml @@ -0,0 +1,62 @@ +# This is a basic workflow that is manually triggered + +name: Detekt + +# Controls when the action will run. Workflow runs when manually triggered using the UI +# or API. +on: + workflow_dispatch: + # Inputs the workflow accepts. + inputs: + name: + # Friendly description to be shown in the UI instead of 'name' + description: 'Detekt' + # Default value if no value is explicitly provided + default: 'World' + # Input has to be provided for the workflow to run + required: true + # The data type of the input + type: string + + push: + branches: + - feature/detekt + pull_request: + branches: + - "master" + paths: + - ".github/workflows/detekt.yml" + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "greet" + run: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + - name: Set base line + run: ./gradlew detektBaseline + - name: module owncloudApp + run: ./gradlew detekt + - name: module owncloudDomain + run: ./gradlew owncloudDomain:detekt + - name: module owncloudData + run: ./gradlew owncloudData:detekt + - name: module owncloudComLibrary + run: ./gradlew owncloudComLibrary:detekt + - name: module owncloudTestUtil + run: ./gradlew owncloudTestUtil:detekt diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 9879910ba86..1c0e0dec11c 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -48,7 +48,7 @@ output-reports: # - 'HtmlOutputReport' comments: - active: true + active: false AbsentOrWrongFileLicense: active: false licenseTemplateFile: 'license.template' @@ -85,7 +85,7 @@ complexity: active: true ComplexCondition: active: true - threshold: 4 + threshold: 5 ComplexInterface: active: false threshold: 10 @@ -111,20 +111,20 @@ complexity: active: false ignoredLabels: [] LargeClass: - active: true + active: false threshold: 600 LongMethod: active: true - threshold: 60 + threshold: 100 LongParameterList: - active: true + active: false functionThreshold: 6 constructorThreshold: 7 ignoreDefaultParameters: false ignoreDataClasses: true ignoreAnnotatedParameter: [] MethodOverloading: - active: false + active: true threshold: 6 NamedArguments: active: false @@ -132,7 +132,7 @@ complexity: ignoreArgumentsMatchingNames: false NestedBlockDepth: active: true - threshold: 4 + threshold: 5 ReplaceSafeCallChainWithRun: active: false StringLiteralDuplication: @@ -143,7 +143,7 @@ complexity: excludeStringsWithLessThan5Characters: true ignoreStringsRegex: '$^' TooManyFunctions: - active: true + active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] thresholdInFiles: 11 thresholdInClasses: 11 @@ -157,7 +157,7 @@ complexity: coroutines: active: true GlobalCoroutineUsage: - active: false + active: true InjectDispatcher: active: false dispatcherNames: @@ -165,13 +165,13 @@ coroutines: - 'Default' - 'Unconfined' RedundantSuspendModifier: - active: false + active: true SleepInsteadOfDelay: - active: false + active: true SuspendFunWithCoroutineScopeReceiver: - active: false + active: true SuspendFunWithFlowReturnType: - active: false + active: true empty-blocks: active: true @@ -192,7 +192,7 @@ empty-blocks: active: true EmptyFunctionBlock: active: true - ignoreOverridden: false + ignoreOverridden: true EmptyIfBlock: active: true EmptyInitBlock: @@ -211,19 +211,19 @@ empty-blocks: exceptions: active: true ExceptionRaisedInUnexpectedLocation: - active: true + active: false methodNames: - 'equals' - 'finalize' - 'hashCode' - 'toString' InstanceOfCheckForException: - active: false + active: true excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] NotImplementedDeclaration: - active: false + active: true ObjectExtendsThrowable: - active: false + active: true PrintStackTrace: active: true RethrowCaughtException: @@ -259,7 +259,7 @@ exceptions: ThrowingNewInstanceOfSameException: active: true TooGenericExceptionCaught: - active: true + active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] exceptionNames: - 'ArrayIndexOutOfBoundsException' @@ -293,7 +293,6 @@ naming: parameterPattern: '[a-z][A-Za-z0-9]*' privateParameterPattern: '[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true EnumNaming: active: true enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' @@ -311,27 +310,25 @@ naming: excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] functionPattern: '[a-z][a-zA-Z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true FunctionParameterNaming: active: true parameterPattern: '[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true InvalidPackageDeclaration: - active: false + active: true rootPackage: '' requireRootInDeclaration: false LambdaParameterNaming: - active: false + active: true parameterPattern: '[a-z][A-Za-z0-9]*|_' MatchingDeclarationName: active: true - mustBeFirst: true + mustBeFirst: false MemberNameEqualsClassName: active: true ignoreOverridden: true NoNameShadowing: - active: false + active: true NonBooleanPropertyPrefixedWithIs: active: false ObjectPropertyNaming: @@ -368,7 +365,7 @@ performance: active: true excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] SpreadOperator: - active: true + active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] UnnecessaryTemporaryInstantiation: active: true @@ -539,7 +536,7 @@ style: active: true maxJumpCount: 1 MagicNumber: - active: true + active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] ignoreNumbers: - '-1' @@ -562,7 +559,7 @@ style: active: false MaxLineLength: active: true - maxLineLength: 120 + maxLineLength: 150 excludePackageStatements: true excludeImportStatements: true excludeCommentStatements: false @@ -610,7 +607,7 @@ style: SpacingBetweenPackageAndImports: active: false ThrowsCount: - active: true + active: false max: 2 excludeGuardClauses: false TrailingWhitespace: From 40333448bb508aa0ae61abc3f5b7660bc39c922d Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Thu, 14 Nov 2024 09:20:40 +0100 Subject: [PATCH 03/31] feat: update detekt version to 1.23.3, adding new fields and removed deprecated ones --- config/detekt/detekt.yml | 53 +++++++++++++-------------------------- gradle/libs.versions.toml | 2 +- 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 1c0e0dec11c..dc9eeda31f1 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -83,6 +83,9 @@ comments: complexity: active: true + CognitiveComplexMethod: + active: false + threshold: 15 ComplexCondition: active: true threshold: 5 @@ -91,7 +94,7 @@ complexity: threshold: 10 includeStaticDeclarations: false includePrivateDeclarations: false - ComplexMethod: + CyclomaticComplexMethod: active: true threshold: 15 ignoreSingleWhenExpression: false @@ -284,7 +287,6 @@ naming: BooleanPropertyNaming: active: false allowedPattern: '^(is|has|are)' - ignoreOverridden: true ClassNaming: active: true classPattern: '[A-Z][a-zA-Z0-9]*' @@ -355,7 +357,6 @@ naming: variablePattern: '[a-z][A-Za-z0-9]*' privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' - ignoreOverridden: true performance: active: true @@ -393,8 +394,6 @@ potential-bugs: - 'java.util.HashSet' - 'java.util.LinkedHashMap' - 'java.util.HashMap' - DuplicateCaseInWhenExpression: - active: true ElseCaseInsteadOfExhaustiveWhen: active: false EqualsAlwaysReturnsTrueOrFalse: @@ -409,7 +408,7 @@ potential-bugs: active: false IgnoredReturnValue: active: false - restrictToAnnotatedMethods: true + restrictToConfig: true returnValueAnnotations: - '*.CheckResult' - '*.CheckReturnValue' @@ -436,15 +435,10 @@ potential-bugs: MissingPackageDeclaration: active: false excludes: ['**/*.kts'] - MissingWhenCase: - active: true - allowElseExpression: true NullCheckOnMutableProperty: active: false NullableToStringCall: active: false - RedundantElseInWhen: - active: true UnconditionalJumpStatementInLoop: active: false UnnecessaryNotNullOperator: @@ -469,6 +463,14 @@ potential-bugs: style: active: true + AlsoCouldBeApply: + active: false + BracesOnIfStatements: + singleLine: 'never' + multiLine: 'always' + BracesOnWhenStatements: + singleLine: 'necessary' + multiLine: 'consistent' CanBeNonNullable: active: false ClassOrdering: @@ -477,7 +479,8 @@ style: active: false DataClassContainsFunctions: active: false - conversionFunctionPrefix: 'to' + allowOperators: false + conversionFunctionPrefix: ['to'] DataClassShouldBeImmutable: active: false DestructuringDeclarationWithTooManyEntries: @@ -496,12 +499,8 @@ style: includeLineWrapping: false ForbiddenComment: active: true - values: - - 'FIXME:' - - 'STOPSHIP:' - - 'TODO:' allowedPatterns: '' - customMessage: '' + comments: ['FIXME:', 'STOPSHIP:', 'TODO:'] ForbiddenImport: active: false imports: [] @@ -511,12 +510,6 @@ style: methods: - 'kotlin.io.print' - 'kotlin.io.println' - ForbiddenPublicDataClass: - active: true - excludes: ['**'] - ignorePackages: - - '*.internal' - - '*.internal.*' ForbiddenVoid: active: false ignoreOverridden: false @@ -525,13 +518,7 @@ style: active: true ignoreOverridableFunction: true ignoreActualFunction: true - excludedFunctions: '' - LibraryCodeMustSpecifyReturnType: - active: true - excludes: ['**'] - LibraryEntitiesShouldNotBePublic: - active: true - excludes: ['**'] + excludedFunctions: [] LoopWithTooManyJumpStatements: active: true maxJumpCount: 1 @@ -553,8 +540,6 @@ style: ignoreEnums: false ignoreRanges: false ignoreExtensionFunctions: true - MandatoryBracesIfStatements: - active: false MandatoryBracesLoops: active: false MaxLineLength: @@ -581,8 +566,6 @@ style: active: true OptionalUnit: active: false - OptionalWhenBraces: - active: false PreferToOverPairSyntax: active: false ProtectedMemberInFinalClass: @@ -596,7 +579,7 @@ style: ReturnCount: active: true max: 2 - excludedFunctions: 'equals' + excludedFunctions: ['equals'] excludeLabeled: false excludeReturnFromLambda: true excludeGuardClauses: false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0611eb9cb03..0aa22203c6c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ androidxTestMonitor = "1.6.1" androidxTestUiAutomator ="2.2.0" androidxWork = "2.8.1" coil = "2.2.2" -detekt="1.20.0" +detekt="1.23.3" dexopener = "2.0.5" disklrucache = "2.0.2" media3 ="1.1.1" From c507846761aaf216cd1cbdaf06aad8cba6b7a396 Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Wed, 20 Nov 2024 11:09:48 +0100 Subject: [PATCH 04/31] feat: add dependency for detekt-rules-libraries and add available fields to detekt.yml file --- config/detekt/detekt.yml | 11 +++++++++++ gradle/libs.versions.toml | 1 + owncloudApp/build.gradle | 3 +++ owncloudComLibrary/build.gradle | 3 +++ owncloudData/build.gradle | 3 +++ owncloudDomain/build.gradle | 3 +++ owncloudTestUtil/build.gradle | 3 +++ 7 files changed, 27 insertions(+) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index dc9eeda31f1..1ad5d1301ad 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -282,6 +282,17 @@ exceptions: - 'RuntimeException' - 'Throwable' +libraries: + active: true + ForbiddenPublicDataClass: + active: true + ignorePackages: ['*.internal', '*.internal.*'] + LibraryCodeMustSpecifyReturnType: + active: true + allowOmitUnit: false + LibraryEntitiesShouldNotBePublic: + active: true + naming: active: true BooleanPropertyNaming: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0aa22203c6c..a9deda2f568 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -81,6 +81,7 @@ androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "androidxTestUiAutomator" } androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidxWork" } coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } +detekt-libraries = { module = "io.gitlab.arturbosch.detekt:detekt-rules-libraries", version.ref = "detekt" } dexopener = { group = "com.github.tmurakami", name = "dexopener", version.ref = "dexopener" } disklrucache = { group = "com.jakewharton", name = "disklrucache", version.ref = "disklrucache" } media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3" } diff --git a/owncloudApp/build.gradle b/owncloudApp/build.gradle index 45cf212a379..ad2ef86b50b 100644 --- a/owncloudApp/build.gradle +++ b/owncloudApp/build.gradle @@ -85,6 +85,9 @@ dependencies { debugImplementation libs.androidx.fragment.testing debugImplementation libs.androidx.test.monitor debugImplementation libs.stetho + + // Detekt + detektPlugins libs.detekt.libraries } android { diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 990895e4ff7..5660fc75c3c 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -26,6 +26,9 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.10' debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.6.0' + + // Detekt + detektPlugins libs.detekt.libraries } android { diff --git a/owncloudData/build.gradle b/owncloudData/build.gradle index 0e62c821d84..f0ad6aff321 100644 --- a/owncloudData/build.gradle +++ b/owncloudData/build.gradle @@ -89,4 +89,7 @@ dependencies { androidTestImplementation libs.androidx.test.runner androidTestImplementation libs.kotlinx.coroutines.test androidTestImplementation(libs.mockk.android) { exclude module: "objenesis" } + + // Detekt + detektPlugins libs.detekt.libraries } diff --git a/owncloudDomain/build.gradle b/owncloudDomain/build.gradle index 93d50153250..cf369752485 100644 --- a/owncloudDomain/build.gradle +++ b/owncloudDomain/build.gradle @@ -45,4 +45,7 @@ dependencies { testImplementation libs.junit4 testImplementation libs.kotlinx.coroutines.test testImplementation libs.mockk + + // Detekt + detektPlugins libs.detekt.libraries } diff --git a/owncloudTestUtil/build.gradle b/owncloudTestUtil/build.gradle index 9e03fd7fc45..d3a3c184176 100644 --- a/owncloudTestUtil/build.gradle +++ b/owncloudTestUtil/build.gradle @@ -33,4 +33,7 @@ dependencies { implementation project(':owncloudComLibrary') implementation libs.kotlin.stdlib implementation libs.androidx.lifecycle.livedata.ktx + + // Detekt + detektPlugins libs.detekt.libraries } From 07f9cad03ddb78e7860d10a0e2b8ab2dd431cf99 Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Wed, 20 Nov 2024 13:05:42 +0100 Subject: [PATCH 05/31] feat: add dependency for detekt-formatting and add available fields to detekt.yml file --- config/detekt/detekt.yml | 196 +++++++++++++++++++++++++++++++- gradle/libs.versions.toml | 1 + owncloudApp/build.gradle | 1 + owncloudComLibrary/build.gradle | 1 + owncloudData/build.gradle | 1 + owncloudDomain/build.gradle | 1 + owncloudTestUtil/build.gradle | 1 + 7 files changed, 201 insertions(+), 1 deletion(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 1ad5d1301ad..afa5077a48a 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -282,8 +282,202 @@ exceptions: - 'RuntimeException' - 'Throwable' +formatting: + active: false + AnnotationOnSeparateLine: + active: true + indentSize: 4 + AnnotationSpacing: + active: true + ArgumentListWrapping: + active: true + indentSize: 4 + maxLineLength: 120 + BlockCommentInitialStarAlignment: + active: true + ChainWrapping: + active: true + indentSize: 4 + ClassName: + active: false + CommentSpacing: + active: true + CommentWrapping: + active: true + indentSize: 4 + ContentReceiverMapping: + active: false + maxLineLength: 120 + indentSize: 4 + DiscouragedCommentLocation: + active: false + EnumEntryNameCase: + active: true + EnumWrapping: + active: false + intentSize: 4 + Filename: + active: true + FinalNewline: + active: true + insertFinalNewLine: true + FunKeywordSpacing: + active: true + FunctionName: + active: false + FunctionReturnTypeSpacing: + active: true + maxLineLength: 120 + FunctionSignature: + active: false + forceMultilineWhenParameterCountGreaterOrEqualThan: 2147483647 + functionBodyExpressionWrapping: 'default' + maxLineLength: 120 + indentSize: 4 + FunctionStartOfBodySpacing: + active: true + FunctionTypeReferenceSpacing: + active: true + IfElseBracing: + active: false + IfElseWrapping: + active: false + indentSize: 4 + ImportOrdering: + active: true + layout: '*,java.**,javax.**,kotlin.**,^' + Indentation: + active: true + indentSize: 4 + KdocWrapping: + active: true + indentSize: 4 + MaximumLineLength: + active: true + maxLineLength: 120 + ignoreBackTickedIdentifier: false + ModifierListSpacing: + active: true + MultiLineIfElse: + active: true + indentSize: 4 + MultilineExpressionWrapping: + active: false + indentSize: 4 + NoBlankLineBeforeRbrace: + active: true + NoBlankLineInList: + active: false + NoBlankLinesInChainedMethodCalls: + active: true + NoConsecutiveBlankLines: + active: true + NoConsecutiveComments: + active: false + NoEmptyClassBody: + active: true + NoEmptyFirstLineInClassBody: + active: false + indentSize: 4 + NoEmptyFirstLineInMethodBlock: + active: true + NoLineBreakAfterElse: + active: true + NoLineBreakBeforeAssignment: + active: true + NoMultipleSpaces: + active: true + NoSemicolons: + active: true + NoSingleLineBlockComment: + active: false + indentSize: 4 + NoTrailingSpaces: + active: true + NoUnitReturn: + active: true + NoUnusedImports: + active: true + NoWildcardImports: + active: true + packagesToUseImportOnDemandProperty: 'java.util.*,kotlinx.android.synthetic.**' + NullableTypeSpacing: + active: true + PackageName: + active: true + ParameterListSpacing: + active: false + ParameterListWrapping: + active: true + maxLineLength: 120 + indentSize: 4 + ParameterWrapping: + active: true + indentSize: 4 + MaxLineLength: 120 + PropertyName: + active: false + PropertyWrapping: + active: true + indentSize: 4 + maxLineLength: 120 + SpacingAroundAngleBrackets: + active: true + SpacingAroundColon: + active: true + SpacingAroundComma: + active: true + SpacingAroundCurly: + active: true + SpacingAroundDot: + active: true + SpacingAroundDoubleColon: + active: true + SpacingAroundKeyword: + active: true + SpacingAroundOperators: + active: true + SpacingAroundParens: + active: true + SpacingAroundRangeOperator: + active: true + SpacingAroundUnaryOperator: + active: true + SpacingBetweenDeclarationsWithAnnotations: + active: true + SpacingBetweenDeclarationsWithComments: + active: true + SpacingBetweenFunctionNameAndOpeningParenthesis: + active: true + StringTemplate: + active: true + StringTemplateIndent: + active: false + indentSize: 4 + TrailingCommaOnCallSite: + active: false + useTrailingCommaOnCallSite: true + TrailingCommaOnDeclarationSite: + active: false + useTrailingCommaOnDeclarationSite: true + TryCatchFinallySpacing: + active: false + indentSize: 4 + TypeArgumentListSpacing: + active: false + indentSize: 4 + TypeParameterListSpacing: + active: false + indentSize: 4 + UnnecessaryParenthesesBeforeTrailingLambda: + active: true + Wrapping: + active: true + indentSize: 4 + maxLineLength: 120 + libraries: - active: true + active: false ForbiddenPublicDataClass: active: true ignorePackages: ['*.internal', '*.internal.*'] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a9deda2f568..df12f8d39a2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -81,6 +81,7 @@ androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "androidxTestUiAutomator" } androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidxWork" } coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } +detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } detekt-libraries = { module = "io.gitlab.arturbosch.detekt:detekt-rules-libraries", version.ref = "detekt" } dexopener = { group = "com.github.tmurakami", name = "dexopener", version.ref = "dexopener" } disklrucache = { group = "com.jakewharton", name = "disklrucache", version.ref = "disklrucache" } diff --git a/owncloudApp/build.gradle b/owncloudApp/build.gradle index ad2ef86b50b..1d419095ec7 100644 --- a/owncloudApp/build.gradle +++ b/owncloudApp/build.gradle @@ -87,6 +87,7 @@ dependencies { debugImplementation libs.stetho // Detekt + detektPlugins libs.detekt.formatting detektPlugins libs.detekt.libraries } diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 5660fc75c3c..b67c6464539 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -28,6 +28,7 @@ dependencies { debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.6.0' // Detekt + detektPlugins libs.detekt.formatting detektPlugins libs.detekt.libraries } diff --git a/owncloudData/build.gradle b/owncloudData/build.gradle index f0ad6aff321..7f50823a276 100644 --- a/owncloudData/build.gradle +++ b/owncloudData/build.gradle @@ -91,5 +91,6 @@ dependencies { androidTestImplementation(libs.mockk.android) { exclude module: "objenesis" } // Detekt + detektPlugins libs.detekt.formatting detektPlugins libs.detekt.libraries } diff --git a/owncloudDomain/build.gradle b/owncloudDomain/build.gradle index cf369752485..e547d68bcd2 100644 --- a/owncloudDomain/build.gradle +++ b/owncloudDomain/build.gradle @@ -47,5 +47,6 @@ dependencies { testImplementation libs.mockk // Detekt + detektPlugins libs.detekt.formatting detektPlugins libs.detekt.libraries } diff --git a/owncloudTestUtil/build.gradle b/owncloudTestUtil/build.gradle index d3a3c184176..52a902d188f 100644 --- a/owncloudTestUtil/build.gradle +++ b/owncloudTestUtil/build.gradle @@ -35,5 +35,6 @@ dependencies { implementation libs.androidx.lifecycle.livedata.ktx // Detekt + detektPlugins libs.detekt.formatting detektPlugins libs.detekt.libraries } From fe7969eccd261c861568b0d1095e458fe023a989 Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Wed, 20 Nov 2024 13:42:50 +0100 Subject: [PATCH 06/31] feat: add new fields in 1.23.3 that were disabled: KDocReferencesNonPublicProperty and NestedScopeFunctions --- config/detekt/detekt.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index afa5077a48a..a4e1763fa2e 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -62,6 +62,8 @@ comments: EndOfSentenceFormat: active: false endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' + KDocReferencesNonPublicProperty: + active: false OutdatedDocumentation: active: false matchTypeParameters: true @@ -136,6 +138,10 @@ complexity: NestedBlockDepth: active: true threshold: 5 + NestedScopeFunctions: + active: false + threshold: 1 + functions: ['kotlin.apply', 'kotlin.run', 'kotlin.with', 'kotlin.let', 'kotlin.also'] ReplaceSafeCallChainWithRun: active: false StringLiteralDuplication: From 0d57de0a7b6d6fba69e513086b232d8af47d8efa Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Mon, 2 Dec 2024 09:14:17 +0100 Subject: [PATCH 07/31] fix: set the version line with correct format in toml file --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index df12f8d39a2..16106794a60 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ androidxTestMonitor = "1.6.1" androidxTestUiAutomator ="2.2.0" androidxWork = "2.8.1" coil = "2.2.2" -detekt="1.23.3" +detekt = "1.23.3" dexopener = "2.0.5" disklrucache = "2.0.2" media3 ="1.1.1" From 20bd1b1980b27e415d8f83004635f736ade695ca Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Wed, 4 Dec 2024 10:51:21 +0100 Subject: [PATCH 08/31] feat: detekt.yml file with latest rules changes for the first iteration --- config/detekt/detekt.yml | 167 ++++++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 57 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index a4e1763fa2e..cb449f47faf 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -86,8 +86,8 @@ comments: complexity: active: true CognitiveComplexMethod: - active: false - threshold: 15 + active: true + threshold: 20 ComplexCondition: active: true threshold: 5 @@ -573,29 +573,36 @@ performance: active: true ArrayPrimitive: active: true + CouldBeSequence: + active: false + threshold: 3 ForEachOnRange: active: true excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] SpreadOperator: - active: false + active: true excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnnecessaryPartOfBinaryExpression: + active: true UnnecessaryTemporaryInstantiation: active: true potential-bugs: active: true AvoidReferentialEquality: - active: false + active: true forbiddenTypePatterns: - 'kotlin.String' + CastNullableToNonNullableType: + active: true CastToNullableType: - active: false + active: true Deprecation: active: false DontDowncastCollectionTypes: - active: false + active: true DoubleMutabilityForCollection: - active: false + active: true mutableTypes: - 'kotlin.collections.MutableList' - 'kotlin.collections.MutableMap' @@ -606,17 +613,18 @@ potential-bugs: - 'java.util.LinkedHashMap' - 'java.util.HashMap' ElseCaseInsteadOfExhaustiveWhen: - active: false + active: true + ignoredSubjectTypes: [] EqualsAlwaysReturnsTrueOrFalse: active: true EqualsWithHashCodeExist: active: true ExitOutsideMain: - active: false + active: true ExplicitGarbageCollectionCall: active: true HasPlatformType: - active: false + active: true IgnoredReturnValue: active: false restrictToConfig: true @@ -629,8 +637,8 @@ potential-bugs: ImplicitDefaultLocale: active: true ImplicitUnitReturnType: - active: false - allowExplicitReturnType: true + active: true + allowExplicitReturnType: false InvalidRange: active: true IteratorHasNextCallsNextMethod: @@ -642,52 +650,59 @@ potential-bugs: excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] ignoreOnClassesPattern: '' MapGetWithNotNullAssertionOperator: - active: false + active: true MissingPackageDeclaration: - active: false - excludes: ['**/*.kts'] + active: true NullCheckOnMutableProperty: active: false NullableToStringCall: - active: false + active: true + PropertyUsedBeforeDeclaration: + active: true UnconditionalJumpStatementInLoop: - active: false + active: true + UnnecessaryNotNullCheck: + active: true UnnecessaryNotNullOperator: active: true UnnecessarySafeCall: active: true UnreachableCatchBlock: - active: false + active: true UnreachableCode: active: true UnsafeCallOnNullableType: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + active: false UnsafeCast: active: true UnusedUnaryOperator: - active: false + active: true UselessPostfixExpression: - active: false + active: true WrongEqualsTypeParameter: active: true style: active: true AlsoCouldBeApply: - active: false + active: true BracesOnIfStatements: - singleLine: 'never' - multiLine: 'always' + active: true + singleLine: 'consistent' + multiLine: 'consistent' BracesOnWhenStatements: - singleLine: 'necessary' + active: true + singleLine: 'consistent' multiLine: 'consistent' CanBeNonNullable: + active: true + CascadingCallWrapping: active: false + includeElvis: true ClassOrdering: - active: false + active: true CollapsibleIfStatements: - active: false + active: true DataClassContainsFunctions: active: false allowOperators: false @@ -697,17 +712,24 @@ style: DestructuringDeclarationWithTooManyEntries: active: false maxDestructuringEntries: 3 + DoubleNegativeLambda: + active: true + negativeFunctions: ['takeUnless', 'none'] + negativeFunctionNameParts: ['not', 'non'] EqualsNullCall: active: true EqualsOnSignatureLine: - active: false + active: true ExplicitCollectionElementAccessMethod: - active: false + active: true ExplicitItLambdaParameter: - active: false + active: true ExpressionBodySyntax: + active: true + includeLineWrapping: true + ForbiddenAnnotation: active: false - includeLineWrapping: false + annotations: ['java.lang.SuppressWarnings', 'java.lang.Deprecated', 'java.lang.annotation.Documented', 'java.lang.annotation.Target', 'java.lang.annotation.Retention', 'java.lang.annotation.Repeatable', 'java.lang.annotation.Inherited'] ForbiddenComment: active: true allowedPatterns: '' @@ -717,12 +739,13 @@ style: imports: [] forbiddenPatterns: '' ForbiddenMethodCall: + active: true + methods: ['kotlin.io.print', 'kotlin.io.println'] + ForbiddenSuppress: active: false - methods: - - 'kotlin.io.print' - - 'kotlin.io.println' + rules: [] ForbiddenVoid: - active: false + active: true ignoreOverridden: false ignoreUsageInGenerics: false FunctionOnlyReturningConstant: @@ -752,7 +775,7 @@ style: ignoreRanges: false ignoreExtensionFunctions: true MandatoryBracesLoops: - active: false + active: true MaxLineLength: active: true maxLineLength: 150 @@ -765,28 +788,34 @@ style: active: true MultilineLambdaItParameter: active: false + MultilineRawStringIndentation: + active: false + indentSize: 4 + trimmingMethods: ['trimIndent', 'trimMargin'] NestedClassesVisibility: active: true NewLineAtEndOfFile: active: true NoTabs: active: false + NullableBooleanCheck: + active: true ObjectLiteralToLambda: - active: false + active: true OptionalAbstractKeyword: active: true OptionalUnit: - active: false + active: true PreferToOverPairSyntax: - active: false + active: true ProtectedMemberInFinalClass: active: true RedundantExplicitType: - active: false + active: true RedundantHigherOrderMapUsage: - active: false + active: true RedundantVisibilityModifierRule: - active: false + active: true ReturnCount: active: true max: 2 @@ -799,13 +828,20 @@ style: SerialVersionUIDInSerializableClass: active: true SpacingBetweenPackageAndImports: + active: true + StringShouldBeRawString: active: false + maxEscapedCharacterCount: 2 + ignoredCharacters: [] ThrowsCount: active: false max: 2 excludeGuardClauses: false TrailingWhitespace: + active: true + TrimMultilineRawString: active: false + trimmingMethods: ['trimIndent', 'trimMargin'] UnderscoresInNumericLiterals: active: false acceptableLength: 4 @@ -816,56 +852,73 @@ style: active: false UnnecessaryApply: active: true - UnnecessaryFilter: + UnnecessaryBackticks: active: false + UnnecessaryBracesAroundTrailingLambda: + active: true + UnnecessaryFilter: + active: true UnnecessaryInheritance: active: true UnnecessaryInnerClass: - active: false + active: true UnnecessaryLet: - active: false + active: true UnnecessaryParentheses: active: false + allowForUnclearPrecedence: true UntilInsteadOfRangeTo: - active: false + active: true UnusedImports: - active: false + active: true + UnusedParameter: + active: true + allowedNames: 'ignored|expected' UnusedPrivateClass: active: true UnusedPrivateMember: active: true allowedNames: '(_|ignored|expected|serialVersionUID)' + UnusedPrivateProperty: + active: true + allowedNames: '_|ignored|expected|serialVersionUID' UseAnyOrNoneInsteadOfFind: - active: false + active: true UseArrayLiteralsInAnnotations: - active: false + active: true UseCheckNotNull: active: false UseCheckOrError: active: false UseDataClass: - active: false - allowVars: false + active: true + allowVars: true UseEmptyCounterpart: - active: false + active: true UseIfEmptyOrIfBlank: - active: false + active: true UseIfInsteadOfWhen: - active: false + active: true + ignoreWhenContainingVariableDeclaration: false UseIsNullOrEmpty: - active: false + active: true + UseLet: + active: true UseOrEmpty: - active: false + active: true UseRequire: active: false UseRequireNotNull: active: false + UseSumOfInsteadOfFlatMapSize: + active: false UselessCallOnNotNull: active: true UtilityClassWithPublicConstructor: active: true VarCouldBeVal: active: true + ignoreLateinitVar: false WildcardImport: active: true excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] From 20f1b6246592e4ab3bda0bb4bed42e35e4019782 Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Wed, 4 Dec 2024 10:54:20 +0100 Subject: [PATCH 09/31] fix: remove base line, and use correct version of action for gradle --- .github/workflows/detekt.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml index eb1d6b19ec9..efc259ff36b 100644 --- a/.github/workflows/detekt.yml +++ b/.github/workflows/detekt.yml @@ -47,9 +47,7 @@ jobs: # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle - uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 - - name: Set base line - run: ./gradlew detektBaseline + uses: gradle/actions/setup-gradle@v4 - name: module owncloudApp run: ./gradlew detekt - name: module owncloudDomain From 9ef865ecdb2e69309a9a7a644c0d1b3fafc63afc Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 4 Dec 2024 08:26:52 +0100 Subject: [PATCH 10/31] style: make lines wrap automatically when they reach 150 characters in IDE --- .idea/codeStyles/Project.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 0a8ab42d20d..af4fbad11b6 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -2,6 +2,7 @@ - \ No newline at end of file + From 5f948d4238e2f2f8ced50fd0db23aa0b27ddd36c Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 4 Dec 2024 14:41:10 +0100 Subject: [PATCH 11/31] style: wrap lines more than 150 characters in module `owncloudApp` --- .../datamodel/FileDataStorageManager.kt | 17 ++++++----- .../dependecyinjection/ViewModelModule.kt | 6 ++-- .../authentication/LoginActivity.kt | 6 ++-- .../conflicts/ConflictsResolveActivity.kt | 3 +- .../files/details/FileDetailsFragment.kt | 3 +- .../files/filelist/MainFileListFragment.kt | 30 ++++++++++++------- .../files/filelist/MainFileListViewModel.kt | 7 +++-- .../operations/FileOperationsViewModel.kt | 3 +- .../SettingsVideoUploadsFragment.kt | 3 +- .../security/SettingsSecurityFragment.kt | 3 +- .../sharing/PublicLinkPasswordUtils.kt | 3 +- .../sharing/ShareFragmentListener.kt | 2 +- .../shares/PublicShareDialogFragment.kt | 18 ++++++++--- .../android/providers/LogsProvider.kt | 3 +- .../android/ui/activity/DrawerActivity.kt | 6 ++-- .../ui/activity/FileDisplayActivity.kt | 6 ++-- .../ui/preview/PreviewAudioFragment.kt | 3 +- .../ui/preview/PreviewImageFragment.kt | 3 +- .../android/ui/preview/PreviewTextFragment.kt | 3 +- .../ui/preview/PreviewVideoActivity.kt | 12 +++++--- .../synchronization/SynchronizeFileUseCase.kt | 3 +- .../sharing/PublicLinkPasswordUtilsTest.kt | 3 +- 22 files changed, 96 insertions(+), 50 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.kt b/owncloudApp/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.kt index 398586f1590..dca870423ec 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.kt @@ -52,14 +52,15 @@ class FileDataStorageManager( getFileByPathAndAccount(remotePath, account.name, spaceId) } - private fun getFileByPathAndAccount(remotePath: String, accountName: String, spaceId: String? = null): OCFile? = runBlocking(CoroutinesDispatcherProvider().io) { - val getFileByRemotePathUseCase: GetFileByRemotePathUseCase by inject() - - val result = withContext(CoroutineScope(CoroutinesDispatcherProvider().io).coroutineContext) { - getFileByRemotePathUseCase(GetFileByRemotePathUseCase.Params(accountName, remotePath, spaceId)) - }.getDataOrNull() - result - } + private fun getFileByPathAndAccount(remotePath: String, accountName: String, spaceId: String? = null): OCFile? = + runBlocking(CoroutinesDispatcherProvider().io) { + val getFileByRemotePathUseCase: GetFileByRemotePathUseCase by inject() + + val result = withContext(CoroutineScope(CoroutinesDispatcherProvider().io).coroutineContext) { + getFileByRemotePathUseCase(GetFileByRemotePathUseCase.Params(accountName, remotePath, spaceId)) + }.getDataOrNull() + result + } fun getRootPersonalFolder() = runBlocking(CoroutinesDispatcherProvider().io) { val getPersonalRootFolderForAccountUseCase: GetPersonalRootFolderForAccountUseCase by inject() diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt index 0dbc8bd07ff..835b724a67f 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt @@ -91,12 +91,14 @@ val viewModelModule = module { ShareViewModel(filePath, accountName, get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { (initialFolderToDisplay: OCFile, fileListOption: FileListOption) -> - MainFileListViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), initialFolderToDisplay, fileListOption) + MainFileListViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), + initialFolderToDisplay, fileListOption) } viewModel { (ocFile: OCFile) -> ConflictsResolveViewModel(get(), get(), get(), get(), get(), ocFile) } viewModel { AuthenticationViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } viewModel { MigrationViewModel(MainApp.dataFolder, get(), get(), get(), get(), get(), get(), get()) } - viewModel { TransfersViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) } + viewModel { TransfersViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), + get()) } viewModel { ReceiveExternalFilesViewModel(get(), get(), get(), get()) } viewModel { (accountName: String, showPersonalSpace: Boolean) -> SpacesListViewModel(get(), get(), get(), get(), get(), accountName, showPersonalSpace) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt index 4720c437baa..81889dac1c7 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt @@ -548,7 +548,8 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted codeChallenge = authenticationViewModel.codeChallenge, state = authenticationViewModel.oidcState, username = username, - sendLoginHintAndUser = mdmProvider.getBrandingBoolean(mdmKey = CONFIGURATION_SEND_LOGIN_HINT_AND_USER, booleanKey = R.bool.send_login_hint_and_user), + sendLoginHintAndUser = mdmProvider.getBrandingBoolean(mdmKey = CONFIGURATION_SEND_LOGIN_HINT_AND_USER, + booleanKey = R.bool.send_login_hint_and_user), ) try { @@ -585,7 +586,8 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted val authorizationError = intent.data?.getQueryParameter("error") val authorizationErrorDescription = intent.data?.getQueryParameter("error_description") - Timber.e("OAuth request to get authorization code failed. Error: [$authorizationError]. Error description: [$authorizationErrorDescription]") + Timber.e("OAuth request to get authorization code failed. Error: [$authorizationError]." + + " Error description: [$authorizationErrorDescription]") val authorizationException = if (authorizationError == "access_denied") UnauthorizedException() else Throwable() updateOAuthStatusIconAndText(authorizationException) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/conflicts/ConflictsResolveActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/conflicts/ConflictsResolveActivity.kt index 67380a633be..af746e819bf 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/conflicts/ConflictsResolveActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/conflicts/ConflictsResolveActivity.kt @@ -50,7 +50,8 @@ class ConflictsResolveActivity : AppCompatActivity(), ConflictsResolveDialogFrag lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { conflictsResolveViewModel.currentFile.collectLatest { updatedOCFile -> - Timber.d("File ${updatedOCFile?.remotePath} from ${updatedOCFile?.owner} needs to fix a conflict with etag in conflict ${updatedOCFile?.etagInConflict}") + Timber.d("File ${updatedOCFile?.remotePath} from ${updatedOCFile?.owner} needs to fix a conflict with etag" + + " in conflict ${updatedOCFile?.etagInConflict}") // Finish if the file does not exists or if the file is not in conflict anymore. updatedOCFile?.etagInConflict ?: finish() } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/details/FileDetailsFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/details/FileDetailsFragment.kt index f1973a9f407..3af7d5892c2 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/details/FileDetailsFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/details/FileDetailsFragment.kt @@ -149,7 +149,8 @@ class FileDetailsFragment : FileFragment() { // Mimetypes not supported via open in web, send 500 if (uiResult.error is InstanceNotConfiguredException) { val message = - getString(R.string.open_in_web_error_generic) + " " + getString(R.string.error_reason) + " " + getString(R.string.open_in_web_error_not_supported) + getString(R.string.open_in_web_error_generic) + " " + getString(R.string.error_reason) + + " " + getString(R.string.open_in_web_error_not_supported) this.showMessageInSnackbar(message, Snackbar.LENGTH_LONG) } else if (uiResult.error is TooEarlyException) { this.showMessageInSnackbar(getString(R.string.open_in_web_error_too_early), Snackbar.LENGTH_LONG) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt index ee9abe69faf..d62967464a5 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt @@ -366,7 +366,8 @@ class MainFileListFragment : Fragment(), // Mimetypes not supported via open in web, send 500 if (uiResult.error is InstanceNotConfiguredException) { val message = - getString(R.string.open_in_web_error_generic) + " " + getString(R.string.error_reason) + " " + getString(R.string.open_in_web_error_not_supported) + getString(R.string.open_in_web_error_generic) + " " + getString(R.string.error_reason) + + " " + getString(R.string.open_in_web_error_not_supported) this.showMessageInSnackbar(message, Snackbar.LENGTH_LONG) } else if (uiResult.error is TooEarlyException) { this.showMessageInSnackbar(getString(R.string.open_in_web_error_too_early), Snackbar.LENGTH_LONG) @@ -826,7 +827,8 @@ class MainFileListFragment : Fragment(), * @param newFileListOption new file list option to enable. */ private fun showOrHideFab(newFileListOption: FileListOption, currentFolder: OCFile) { - if (!newFileListOption.isAllFiles() || isPickingAFolder() || (!currentFolder.hasAddFilePermission && !currentFolder.hasAddSubdirectoriesPermission)) { + if (!newFileListOption.isAllFiles() || isPickingAFolder() || + (!currentFolder.hasAddFilePermission && !currentFolder.hasAddSubdirectoriesPermission)) { toggleFabVisibility(false) } else { toggleFabVisibility(true) @@ -872,7 +874,8 @@ class MainFileListFragment : Fragment(), fabNewfile.isFocusable = isFabExpanded() fabNewshortcut.isFocusable = isFabExpanded() if (fabMain.isExpanded) { - binding.fabMain.findViewById(com.getbase.floatingactionbutton.R.id.fab_expand_menu_button).contentDescription = getString(R.string.content_description_add_new_content_expanded) + binding.fabMain.findViewById(com.getbase.floatingactionbutton.R.id.fab_expand_menu_button) + .contentDescription = getString(R.string.content_description_add_new_content_expanded) } else { setFabMainContentDescription() } @@ -1442,16 +1445,23 @@ class MainFileListFragment : Fragment(), if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val roleAccessibilityDescription = getString(R.string.button_role_accessibility) menu?.apply { - findItem(R.id.file_action_select_all)?.contentDescription = "${getString(R.string.actionbar_select_all)} $roleAccessibilityDescription" - findItem(R.id.action_select_inverse)?.contentDescription = "${getString(R.string.actionbar_select_inverse)} $roleAccessibilityDescription" - findItem(R.id.action_open_file_with)?.contentDescription = "${getString(R.string.actionbar_open_with)} $roleAccessibilityDescription" + findItem(R.id.file_action_select_all)?.contentDescription = + "${getString(R.string.actionbar_select_all)} $roleAccessibilityDescription" + findItem(R.id.action_select_inverse)?.contentDescription = + "${getString(R.string.actionbar_select_inverse)} $roleAccessibilityDescription" + findItem(R.id.action_open_file_with)?.contentDescription = + "${getString(R.string.actionbar_open_with)} $roleAccessibilityDescription" findItem(R.id.action_rename_file)?.contentDescription = "${getString(R.string.common_rename)} $roleAccessibilityDescription" findItem(R.id.action_move)?.contentDescription = "${getString(R.string.actionbar_move)} $roleAccessibilityDescription" findItem(R.id.action_copy)?.contentDescription = "${getString(R.string.copy)} $roleAccessibilityDescription" - findItem(R.id.action_send_file)?.contentDescription = "${getString(R.string.actionbar_send_file)} $roleAccessibilityDescription" - findItem(R.id.action_set_available_offline)?.contentDescription = "${getString(R.string.set_available_offline)} $roleAccessibilityDescription" - findItem(R.id.action_unset_available_offline)?.contentDescription = "${getString(R.string.unset_available_offline)} $roleAccessibilityDescription" - findItem(R.id.action_see_details)?.contentDescription = "${getString(R.string.actionbar_see_details)} $roleAccessibilityDescription" + findItem(R.id.action_send_file)?.contentDescription = + "${getString(R.string.actionbar_send_file)} $roleAccessibilityDescription" + findItem(R.id.action_set_available_offline)?.contentDescription = + "${getString(R.string.set_available_offline)} $roleAccessibilityDescription" + findItem(R.id.action_unset_available_offline)?.contentDescription = + "${getString(R.string.unset_available_offline)} $roleAccessibilityDescription" + findItem(R.id.action_see_details)?.contentDescription = + "${getString(R.string.actionbar_see_details)} $roleAccessibilityDescription" findItem(R.id.action_remove_file)?.contentDescription = "${getString(R.string.common_remove)} $roleAccessibilityDescription" } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListViewModel.kt index 62246558373..37bdfd2ba31 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListViewModel.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListViewModel.kt @@ -226,9 +226,10 @@ class MainFileListViewModel( FileListOption.SHARED_BY_LINK -> { val fileById = fileByIdResult.getDataOrNull() - parentDir = if (fileById != null && (!fileById.sharedByLink || fileById.sharedWithSharee != true) && fileById.spaceId == null) { - getFileByRemotePathUseCase(GetFileByRemotePathUseCase.Params(fileById.owner, ROOT_PATH)).getDataOrNull() - } else fileById + parentDir = + if (fileById != null && (!fileById.sharedByLink || fileById.sharedWithSharee != true) && fileById.spaceId == null) { + getFileByRemotePathUseCase(GetFileByRemotePathUseCase.Params(fileById.owner, ROOT_PATH)).getDataOrNull() + } else fileById } FileListOption.AV_OFFLINE -> { diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/operations/FileOperationsViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/operations/FileOperationsViewModel.kt index 7a0781c5a19..7b894b52850 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/operations/FileOperationsViewModel.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/operations/FileOperationsViewModel.kt @@ -275,7 +275,8 @@ class FileOperationsViewModel( remotePath = fileOperation.folderToRefresh.remotePath, accountName = fileOperation.folderToRefresh.owner, spaceId = fileOperation.folderToRefresh.spaceId, - syncMode = if (fileOperation.shouldSyncContents) SynchronizeFolderUseCase.SyncFolderMode.SYNC_CONTENTS else SynchronizeFolderUseCase.SyncFolderMode.REFRESH_FOLDER + syncMode = if (fileOperation.shouldSyncContents) SynchronizeFolderUseCase.SyncFolderMode.SYNC_CONTENTS + else SynchronizeFolderUseCase.SyncFolderMode.REFRESH_FOLDER ) ) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/automaticuploads/SettingsVideoUploadsFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/automaticuploads/SettingsVideoUploadsFragment.kt index 9d1f39b2b45..a2e4ceab694 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/automaticuploads/SettingsVideoUploadsFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/automaticuploads/SettingsVideoUploadsFragment.kt @@ -103,7 +103,8 @@ class SettingsVideoUploadsFragment : PreferenceFragmentCompat() { prefVideoUploadsSourcePath = findPreference(PREF__CAMERA_VIDEO_UPLOADS_SOURCE) prefVideoUploadsLastSync = findPreference(PreferenceManager.PREF__CAMERA_VIDEO_UPLOADS_LAST_SYNC) prefVideoUploadsBehaviour = findPreference(PREF__CAMERA_VIDEO_UPLOADS_BEHAVIOUR)?.apply { - entries = listOf(getString(R.string.pref_behaviour_entries_keep_file), getString(R.string.pref_behaviour_entries_remove_original_file)).toTypedArray() + entries = listOf(getString(R.string.pref_behaviour_entries_keep_file), + getString(R.string.pref_behaviour_entries_remove_original_file)).toTypedArray() entryValues = listOf(UploadBehavior.COPY.name, UploadBehavior.MOVE.name).toTypedArray() } prefVideoUploadsAccount = findPreference(PREF__CAMERA_VIDEO_UPLOADS_ACCOUNT_NAME) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt index 0e3cbab8d17..a883999ac51 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt @@ -172,7 +172,8 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() { if (!BiometricManager.isHardwareDetected()) { // Biometric not supported screenSecurity?.removePreferenceFromScreen(prefBiometric) } else { - if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) { // Disable biometric lock if Passcode or Pattern locks are disabled + // Disable biometric lock if Passcode or Pattern locks are disabled + if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) { disableBiometric() } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt index c322c5d5a9c..b64730ba364 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt @@ -25,7 +25,8 @@ import java.security.SecureRandom private val charsetLowercase = ('a'..'z').toList() private val charsetUppercase = ('A'..'Z').toList() private val charsetDigits = ('0'..'9').toList() -private val charsetSpecial = listOf('!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~') +private val charsetSpecial = listOf('!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', + '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~') fun generatePassword( minChars: Int?, diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareFragmentListener.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareFragmentListener.kt index 7f52b90220e..ee921df5f10 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareFragmentListener.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareFragmentListener.kt @@ -34,7 +34,7 @@ import com.owncloud.android.domain.sharing.shares.model.OCShare * contained in that activity. * * - * See the Android Training lesson [Communicating with Other Fragments](http://developer.android.com/training/basics/fragments/communicating.html) for more information. + * See the Android docs [Communicating with fragments](https://developer.android.com/guide/fragments/communicate) for more information. */ interface ShareFragmentListener { fun copyOrSendPrivateLink(file: OCFile) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/shares/PublicShareDialogFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/shares/PublicShareDialogFragment.kt index 5ee96c8656d..daffcdb5573 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/shares/PublicShareDialogFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/shares/PublicShareDialogFragment.kt @@ -518,7 +518,8 @@ class PublicShareDialogFragment : DialogFragment() { val x = event.x.toInt() val y = event.y.toInt() val bounds = rightDrawable.bounds - if (x >= view.right - bounds.width() - fuzz && x <= view.right - view.paddingRight + fuzz && y >= view.paddingTop - fuzz && y <= view.height - view.paddingBottom + fuzz) { + if (x >= view.right - bounds.width() - fuzz && x <= view.right - view.paddingRight + fuzz && y >= view.paddingTop - fuzz && + y <= view.height - view.paddingBottom + fuzz) { return onDrawableTouch(event) } @@ -836,7 +837,9 @@ class PublicShareDialogFragment : DialogFragment() { // - Upload only is supported by the server version // - Upload only capability is set // - Allow editing capability is set - if (!(isSharedFolder && serverVersion?.isPublicSharingWriteOnlySupported == true && capabilities?.filesSharingPublicSupportsUploadOnly == CapabilityBooleanType.TRUE && capabilities?.filesSharingPublicUpload == CapabilityBooleanType.TRUE)) { + if (!(isSharedFolder && serverVersion?.isPublicSharingWriteOnlySupported == true && + capabilities?.filesSharingPublicSupportsUploadOnly == CapabilityBooleanType.TRUE && + capabilities?.filesSharingPublicUpload == CapabilityBooleanType.TRUE)) { binding.shareViaLinkEditPermissionGroup.isVisible = false } @@ -867,7 +870,12 @@ class PublicShareDialogFragment : DialogFragment() { } // Set password label when opening the dialog - if (binding.shareViaLinkEditPermissionReadOnly.isChecked && capabilities?.filesSharingPublicPasswordEnforcedReadOnly == CapabilityBooleanType.TRUE || binding.shareViaLinkEditPermissionReadAndWrite.isChecked && capabilities?.filesSharingPublicPasswordEnforcedReadWrite == CapabilityBooleanType.TRUE || binding.shareViaLinkEditPermissionUploadFiles.isChecked && capabilities?.filesSharingPublicPasswordEnforcedUploadOnly == CapabilityBooleanType.TRUE) { + if (binding.shareViaLinkEditPermissionReadOnly.isChecked && + capabilities?.filesSharingPublicPasswordEnforcedReadOnly == CapabilityBooleanType.TRUE || + binding.shareViaLinkEditPermissionReadAndWrite.isChecked && + capabilities?.filesSharingPublicPasswordEnforcedReadWrite == CapabilityBooleanType.TRUE || + binding.shareViaLinkEditPermissionUploadFiles.isChecked && + capabilities?.filesSharingPublicPasswordEnforcedUploadOnly == CapabilityBooleanType.TRUE) { setPasswordEnforced() } @@ -898,7 +906,9 @@ class PublicShareDialogFragment : DialogFragment() { // When there's no password enforced for capability val hasPasswordEnforcedFor = - capabilities?.filesSharingPublicPasswordEnforcedReadOnly == CapabilityBooleanType.TRUE || capabilities?.filesSharingPublicPasswordEnforcedReadWrite == CapabilityBooleanType.TRUE || capabilities?.filesSharingPublicPasswordEnforcedUploadOnly == CapabilityBooleanType.TRUE + capabilities?.filesSharingPublicPasswordEnforcedReadOnly == CapabilityBooleanType.TRUE || + capabilities?.filesSharingPublicPasswordEnforcedReadWrite == CapabilityBooleanType.TRUE || + capabilities?.filesSharingPublicPasswordEnforcedUploadOnly == CapabilityBooleanType.TRUE // hide password switch if password is enforced to prevent it is removed if (!hasPasswordEnforcedFor && capabilities?.filesSharingPublicPasswordEnforced == CapabilityBooleanType.TRUE) { diff --git a/owncloudApp/src/main/java/com/owncloud/android/providers/LogsProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/providers/LogsProvider.kt index 3a8818ebaa1..25a21bb84e8 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/providers/LogsProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/providers/LogsProvider.kt @@ -58,7 +58,8 @@ class LogsProvider( private fun initHttpLogs() { val httpLogsEnabled: Boolean = sharedPreferencesProvider.getBoolean(PREFERENCE_LOG_HTTP, false) LogInterceptor.httpLogsEnabled = httpLogsEnabled - val redactAuthHeader = mdmProvider.getBrandingBoolean(mdmKey = CONFIGURATION_REDACT_AUTH_HEADER_LOGS, booleanKey = R.bool.redact_auth_header_logs) + val redactAuthHeader = + mdmProvider.getBrandingBoolean(mdmKey = CONFIGURATION_REDACT_AUTH_HEADER_LOGS, booleanKey = R.bool.redact_auth_header_logs) LogInterceptor.redactAuthHeader = redactAuthHeader } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt index 10a17618690..b7a4a285177 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt @@ -376,7 +376,8 @@ abstract class DrawerActivity : ToolbarActivity() { visibility = View.VISIBLE text = getString(R.string.drawer_nearing_quota) } - } else if (userQuota.state == UserQuotaState.CRITICAL || userQuota.state == UserQuotaState.EXCEEDED) { // Critical storage. Value over 90% + } else if (userQuota.state == UserQuotaState.CRITICAL || + userQuota.state == UserQuotaState.EXCEEDED) { // Critical storage. Value over 90% getAccountQuotaBar()?.apply { isVisible = true progress = userQuota.getRelative().toInt() @@ -496,7 +497,8 @@ abstract class DrawerActivity : ToolbarActivity() { findItem(R.id.nav_settings)?.contentDescription = "${getString(R.string.actionbar_settings)} $roleAccessibilityDescription" findItem(R.id.drawer_menu_feedback)?.contentDescription = "${getString(R.string.drawer_feedback)} $roleAccessibilityDescription" findItem(R.id.drawer_menu_help)?.contentDescription = "${getString(R.string.prefs_help)} $roleAccessibilityDescription" - findItem(R.id.drawer_menu_privacy_policy)?.contentDescription = "${getString(R.string.prefs_privacy_policy)} $roleAccessibilityDescription" + findItem(R.id.drawer_menu_privacy_policy)?.contentDescription = + "${getString(R.string.prefs_privacy_policy)} $roleAccessibilityDescription" } } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 74319110fa8..444f7dbc406 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -749,7 +749,8 @@ class FileDisplayActivity : FileActivity(), // If secondFragment was shown, we need to navigate to the parent of the displayed file // Need a cleanup val folderIdToDisplay = - if (fileListOption == FileListOption.AV_OFFLINE) storageManager.getRootPersonalFolder()!!.id!! else secondFragment!!.file!!.parentId!! + if (fileListOption == FileListOption.AV_OFFLINE) storageManager.getRootPersonalFolder()!!.id!! + else secondFragment!!.file!!.parentId!! mainFileListFragment?.navigateToFolderId(folderIdToDisplay) cleanSecondFragment() updateToolbar(mainFileListFragment?.getCurrentFile()) @@ -962,7 +963,8 @@ class FileDisplayActivity : FileActivity(), private fun updateToolbar(chosenFileFromParam: OCFile?, space: OCSpace? = null) { val chosenFile = chosenFileFromParam ?: file // If no file is passed, current file decides - // If we come from a preview activity (image or video), not updating toolbar when initializing this activity or it will show the root folder one + // If we come from a preview activity (image or video), not updating toolbar when initializing this activity + // or it will show the root folder one if (intent.action == ACTION_DETAILS && chosenFile?.remotePath == OCFile.ROOT_PATH && secondFragment is FileDetailsFragment) return if (chosenFile == null || (chosenFile.remotePath == OCFile.ROOT_PATH && (space == null || !space.isProject))) { diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt index 2087cfffb49..a02d50d26d0 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt @@ -259,7 +259,8 @@ class PreviewAudioFragment : FileFragment() { private fun setRolesAccessibilityToMenuItems(menu: Menu) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - menu.findItem(R.id.action_see_details)?.contentDescription = "${getString(R.string.actionbar_see_details)} ${getString(R.string.button_role_accessibility)}" + menu.findItem(R.id.action_see_details)?.contentDescription = + "${getString(R.string.actionbar_see_details)} ${getString(R.string.button_role_accessibility)}" } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt index 1e1e2bdd7b8..a3e0bdd3dfc 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt @@ -206,7 +206,8 @@ class PreviewImageFragment : FileFragment() { private fun setRolesAccessibilityToMenuItems(menu: Menu) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - menu.findItem(R.id.action_see_details)?.contentDescription = "${getString(R.string.actionbar_see_details)} ${getString(R.string.button_role_accessibility)}" + menu.findItem(R.id.action_see_details)?.contentDescription = + "${getString(R.string.actionbar_see_details)} ${getString(R.string.button_role_accessibility)}" } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt index 18421282bc6..b56c0ea2bf3 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt @@ -247,7 +247,8 @@ class PreviewTextFragment : FileFragment() { private fun setRolesAccessibilityToMenuItems(menu: Menu) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - menu.findItem(R.id.action_see_details)?.contentDescription = "${getString(R.string.actionbar_see_details)} ${getString(R.string.button_role_accessibility)}" + menu.findItem(R.id.action_see_details)?.contentDescription = + "${getString(R.string.actionbar_see_details)} ${getString(R.string.button_role_accessibility)}" } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt index 0cd8482b328..072ef4d7955 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt @@ -354,11 +354,15 @@ class PreviewVideoActivity : FileActivity(), Player.Listener, OnPrepareVideoPlay if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val roleAccessibilityDescription = getString(R.string.button_role_accessibility) menu.apply { - menu.findItem(R.id.action_open_file_with)?.contentDescription = "${getString(R.string.actionbar_open_with)} $roleAccessibilityDescription" + menu.findItem(R.id.action_open_file_with)?.contentDescription = + "${getString(R.string.actionbar_open_with)} $roleAccessibilityDescription" menu.findItem(R.id.action_send_file)?.contentDescription = "${getString(R.string.actionbar_send_file)} $roleAccessibilityDescription" - menu.findItem(R.id.action_set_available_offline)?.contentDescription = "${getString(R.string.set_available_offline)} $roleAccessibilityDescription" - menu.findItem(R.id.action_unset_available_offline)?.contentDescription = "${getString(R.string.unset_available_offline)} $roleAccessibilityDescription" - menu.findItem(R.id.action_see_details)?.contentDescription = "${getString(R.string.actionbar_see_details)} $roleAccessibilityDescription" + menu.findItem(R.id.action_set_available_offline)?.contentDescription = + "${getString(R.string.set_available_offline)} $roleAccessibilityDescription" + menu.findItem(R.id.action_unset_available_offline)?.contentDescription = + "${getString(R.string.unset_available_offline)} $roleAccessibilityDescription" + menu.findItem(R.id.action_see_details)?.contentDescription = + "${getString(R.string.actionbar_see_details)} $roleAccessibilityDescription" menu.findItem(R.id.action_remove_file)?.contentDescription = "${getString(R.string.common_remove)} $roleAccessibilityDescription" } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt index b87f24c3590..543930d9b01 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt @@ -73,7 +73,8 @@ class SynchronizeFileUseCase( // 3. Check if file has changed locally val changedLocally = fileToSynchronize.localModificationTimestamp > fileToSynchronize.lastSyncDateForData!! - Timber.i("Local file modification timestamp :${fileToSynchronize.localModificationTimestamp} and last sync date for data :${fileToSynchronize.lastSyncDateForData}") + Timber.i("Local file modification timestamp :${fileToSynchronize.localModificationTimestamp}" + + " and last sync date for data :${fileToSynchronize.lastSyncDateForData}") Timber.i("So it has changed locally: $changedLocally") // 4. Check if file has changed remotely diff --git a/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt b/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt index f81abe73df5..c4a2471b72f 100644 --- a/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt +++ b/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt @@ -28,7 +28,8 @@ class PublicLinkPasswordUtilsTest { private val charsetLowercase = ('a'..'z').toList() private val charsetUppercase = ('A'..'Z').toList() private val charsetDigits = ('0'..'9').toList() - private val charsetSpecial = listOf('!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~') + private val charsetSpecial = listOf('!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', + '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~') private val minCharacters = 10 private val maxCharacters = 100 From 487df0717bb6a128081ca160c88e044c09f9ab36 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 4 Dec 2024 17:05:24 +0100 Subject: [PATCH 12/31] style: wrap lines more than 150 characters in module `owncloudComLibrary` --- ...reateRemoteFileWithAppProviderOperation.kt | 3 ++- .../status/responses/CapabilityResponse.kt | 24 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt index e4f85a32fa1..9428b5c8c3e 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt @@ -61,7 +61,8 @@ class CreateRemoteFileWithAppProviderOperation( } val status = client.executeHttpMethod(postMethod) - Timber.d("Create file $filename with app provider in folder with ID $parentContainerId - $status${if (!isSuccess(status)) "(FAIL)" else ""}") + Timber.d("Create file $filename with app provider in folder with ID $parentContainerId" + + " - $status${if (!isSuccess(status)) "(FAIL)" else ""}") if (isSuccess(status)) RemoteOperationResult(ResultCode.OK).apply { val moshi = Moshi.Builder().build() diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt index 06b14ca62b0..9c659127120 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt @@ -50,10 +50,14 @@ data class CapabilityResponse( filesSharingApiEnabled = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingApiEnabled), filesSharingResharing = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingReSharing), filesSharingPublicEnabled = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.enabled), - filesSharingPublicUpload = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicUpload), - filesSharingPublicSupportsUploadOnly = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicUploadOnly), - filesSharingPublicMultiple = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicMultiple), - filesSharingPublicPasswordEnforced = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforced), + filesSharingPublicUpload = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicUpload), + filesSharingPublicSupportsUploadOnly = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicUploadOnly), + filesSharingPublicMultiple = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicMultiple), + filesSharingPublicPasswordEnforced = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforced), filesSharingPublicPasswordEnforcedReadOnly = CapabilityBooleanType.fromBooleanValue( capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforcedFor?.enforcedReadOnly ), @@ -63,7 +67,8 @@ data class CapabilityResponse( filesSharingPublicPasswordEnforcedUploadOnly = CapabilityBooleanType.fromBooleanValue( capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforcedFor?.enforcedUploadOnly ), - filesSharingPublicExpireDateEnabled = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicExpireDate?.enabled), + filesSharingPublicExpireDateEnabled = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicExpireDate?.enabled), filesSharingPublicExpireDateDays = capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicExpireDate?.days ?: 0, filesSharingPublicExpireDateEnforced = CapabilityBooleanType.fromBooleanValue( @@ -75,9 +80,12 @@ data class CapabilityResponse( filesPrivateLinks = capabilities?.fileCapabilities?.privateLinks?.let { CapabilityBooleanType.fromBooleanValue(it) } ?: CapabilityBooleanType.UNKNOWN, filesAppProviders = capabilities?.fileCapabilities?.appProviders?.map { it.toAppProviders() }, - filesSharingFederationIncoming = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.incoming), - filesSharingFederationOutgoing = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.outgoing), - filesSharingUserProfilePicture = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingUser?.profilePicture), + filesSharingFederationIncoming = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.incoming), + filesSharingFederationOutgoing = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.outgoing), + filesSharingUserProfilePicture = + CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingUser?.profilePicture), spaces = capabilities?.spacesCapabilities?.toSpaces(), passwordPolicy = capabilities?.passwordPolicyCapabilities?.toPasswordPolicy(), ) From c573d052745a6d516aa4aa4ac5775e03c6275b5b Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 10 Dec 2024 11:06:35 +0100 Subject: [PATCH 13/31] style: wrap lines more than 150 characters in module `owncloudData` --- .../data/files/repository/OCFileRepository.kt | 6 +- .../android/data/migrations/Migration_28.kt | 26 ++++++++- .../android/data/migrations/Migration_29.kt | 33 ++++++++++- .../android/data/migrations/Migration_30.kt | 28 ++++++++- .../android/data/migrations/Migration_32.kt | 3 +- .../android/data/migrations/Migration_33.kt | 6 +- .../android/data/migrations/Migration_34.kt | 4 +- .../android/data/migrations/Migration_38.kt | 12 +++- .../OCLocalFileDataSourceTest.kt | 19 ++++-- .../files/repository/OCFileRepositoryTest.kt | 58 ++++++++++++++++--- .../repository/OCServerInfoRepositoryTest.kt | 3 +- .../OCLocalTransferDataSourceTest.kt | 7 ++- 12 files changed, 175 insertions(+), 30 deletions(-) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/files/repository/OCFileRepository.kt b/owncloudData/src/main/java/com/owncloud/android/data/files/repository/OCFileRepository.kt index 0ada7453f64..29421665a4f 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/files/repository/OCFileRepository.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/files/repository/OCFileRepository.kt @@ -396,7 +396,8 @@ class OCFileRepository( // DO NOT update etag till contents are synced. etag = localChildToSync.etag needsToUpdateThumbnail = - (!remoteChild.isFolder && remoteChild.modificationTimestamp != localChildToSync.modificationTimestamp) || localChildToSync.needsToUpdateThumbnail + (!remoteChild.isFolder && remoteChild.modificationTimestamp != localChildToSync.modificationTimestamp) || + localChildToSync.needsToUpdateThumbnail // Probably not needed, if the child was already in the database, the av offline status should be also there if (remoteFolder.isAvailableOffline) { availableOfflineStatus = AVAILABLE_OFFLINE_PARENT @@ -584,7 +585,8 @@ class OCFileRepository( // 1. Remove folder content recursively folderContent.forEach { file -> - if (!(onlyFromLocalStorage && file.isAvailableOffline)) { // The condition will not be met when onlyFromLocalStorage is true and the file is of type available offline + // The condition will not be met when onlyFromLocalStorage is true and the file is of type available offline + if (!(onlyFromLocalStorage && file.isAvailableOffline)) { if (file.isFolder) { deleteLocalFolderRecursively(ocFile = file, onlyFromLocalStorage = onlyFromLocalStorage) } else { diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_28.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_28.kt index f69a271d7fe..6f0bb2c0143 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_28.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_28.kt @@ -26,11 +26,33 @@ val MIGRATION_27_28 = object : Migration(27, 28) { override fun migrate(database: SupportSQLiteDatabase) { database.run { execSQL( - "CREATE TABLE IF NOT EXISTS `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `version_mayor` INTEGER NOT NULL, `version_minor` INTEGER NOT NULL, `version_micro` INTEGER NOT NULL, `version_string` TEXT, `version_edition` TEXT, `core_pollinterval` INTEGER NOT NULL, `sharing_api_enabled` INTEGER NOT NULL DEFAULT -1, `search_min_length` INTEGER, `sharing_public_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_write` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_public_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_days` INTEGER NOT NULL, `sharing_public_expire_date_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_public_upload` INTEGER NOT NULL DEFAULT -1, `sharing_public_multiple` INTEGER NOT NULL DEFAULT -1, `supports_upload_only` INTEGER NOT NULL DEFAULT -1, `sharing_user_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_resharing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_outgoing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_incoming` INTEGER NOT NULL DEFAULT -1, `files_bigfilechunking` INTEGER NOT NULL DEFAULT -1, `files_undelete` INTEGER NOT NULL DEFAULT -1, `files_versioning` INTEGER NOT NULL DEFAULT -1)" + "CREATE TABLE IF NOT EXISTS `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + + " `account` TEXT, `version_mayor` INTEGER NOT NULL, `version_minor` INTEGER NOT NULL, `version_micro` INTEGER NOT NULL," + + " `version_string` TEXT, `version_edition` TEXT, `core_pollinterval` INTEGER NOT NULL, `sharing_api_enabled`" + + " INTEGER NOT NULL DEFAULT -1, `search_min_length` INTEGER, `sharing_public_enabled` INTEGER NOT NULL DEFAULT -1," + + " `sharing_public_password_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_only`" + + " INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_write` INTEGER NOT NULL DEFAULT -1," + + " `sharing_public_password_enforced_public_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_enabled`" + + " INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_days` INTEGER NOT NULL, `sharing_public_expire_date_enforced`" + + " INTEGER NOT NULL DEFAULT -1, `sharing_public_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_public_upload` INTEGER" + + " NOT NULL DEFAULT -1, `sharing_public_multiple` INTEGER NOT NULL DEFAULT -1, `supports_upload_only` INTEGER NOT NULL" + + " DEFAULT -1, `sharing_user_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_resharing` INTEGER NOT NULL DEFAULT -1," + + " `sharing_federation_outgoing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_incoming` INTEGER NOT NULL DEFAULT -1," + + " `files_bigfilechunking` INTEGER NOT NULL DEFAULT -1, `files_undelete` INTEGER NOT NULL DEFAULT -1, `files_versioning`" + + " INTEGER NOT NULL DEFAULT -1)" ) execSQL("ALTER TABLE ${ProviderTableMeta.CAPABILITIES_TABLE_NAME} ADD COLUMN search_min_length INTEGER") execSQL( - "INSERT INTO `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` SELECT id, account, version_mayor, version_minor, version_micro, version_string, version_edition,core_pollinterval, IFNULL(sharing_api_enabled, -1), search_min_length, IFNULL(sharing_public_enabled, -1), IFNULL(sharing_public_password_enforced, -1),IFNULL(sharing_public_password_enforced_read_only, -1),IFNULL(sharing_public_password_enforced_read_write, -1),IFNULL(sharing_public_password_enforced_public_only, -1),IFNULL(sharing_public_expire_date_enabled, -1),IFNULL(sharing_public_expire_date_days, 0),IFNULL(sharing_public_expire_date_enforced, -1),IFNULL(sharing_public_send_mail, -1),IFNULL(sharing_public_upload, -1),IFNULL(sharing_public_multiple, -1), IFNULL(supports_upload_only, -1), IFNULL(sharing_user_send_mail, -1),IFNULL(sharing_resharing, -1),IFNULL(sharing_federation_outgoing, -1),IFNULL(sharing_federation_incoming, -1),IFNULL(files_bigfilechunking, -1),IFNULL(files_undelete, -1),IFNULL(files_versioning, -1) FROM ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}" + "INSERT INTO `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` SELECT id, account, version_mayor, version_minor, version_micro," + + " version_string, version_edition,core_pollinterval, IFNULL(sharing_api_enabled, -1), search_min_length," + + " IFNULL(sharing_public_enabled, -1), IFNULL(sharing_public_password_enforced, -1)," + + "IFNULL(sharing_public_password_enforced_read_only, -1),IFNULL(sharing_public_password_enforced_read_write, -1)," + + "IFNULL(sharing_public_password_enforced_public_only, -1),IFNULL(sharing_public_expire_date_enabled, -1)," + + "IFNULL(sharing_public_expire_date_days, 0),IFNULL(sharing_public_expire_date_enforced, -1)," + + "IFNULL(sharing_public_send_mail, -1),IFNULL(sharing_public_upload, -1),IFNULL(sharing_public_multiple, -1)," + + " IFNULL(supports_upload_only, -1), IFNULL(sharing_user_send_mail, -1),IFNULL(sharing_resharing, -1)," + + "IFNULL(sharing_federation_outgoing, -1),IFNULL(sharing_federation_incoming, -1),IFNULL(files_bigfilechunking, -1)," + + "IFNULL(files_undelete, -1),IFNULL(files_versioning, -1) FROM ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}" ) execSQL("DROP TABLE ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}") execSQL("ALTER TABLE ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2 RENAME TO ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}") diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_29.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_29.kt index 500d651d60e..e4e42d20f57 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_29.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_29.kt @@ -27,13 +27,40 @@ val MIGRATION_28_29 = object : Migration(28, 29) { database.run { execSQL("DROP TABLE ${ProviderTableMeta.OCSHARES_TABLE_NAME}") execSQL( - "CREATE TABLE IF NOT EXISTS `${ProviderTableMeta.OCSHARES_TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `file_source` TEXT NOT NULL, `item_source` TEXT NOT NULL, `share_type` INTEGER NOT NULL, `shate_with` TEXT, `path` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `shared_date` INTEGER NOT NULL, `expiration_date` INTEGER NOT NULL, `token` TEXT, `shared_with_display_name` TEXT, `share_with_additional_info` TEXT, `is_directory` INTEGER NOT NULL, `user_id` INTEGER NOT NULL, `id_remote_shared` INTEGER NOT NULL, `owner_share` TEXT NOT NULL, `name` TEXT, `url` TEXT)" + "CREATE TABLE IF NOT EXISTS `${ProviderTableMeta.OCSHARES_TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + + " `file_source` TEXT NOT NULL, `item_source` TEXT NOT NULL, `share_type` INTEGER NOT NULL, `shate_with` TEXT," + + " `path` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `shared_date` INTEGER NOT NULL, `expiration_date` INTEGER" + + " NOT NULL, `token` TEXT, `shared_with_display_name` TEXT, `share_with_additional_info` TEXT, `is_directory` INTEGER" + + " NOT NULL, `user_id` INTEGER NOT NULL, `id_remote_shared` INTEGER NOT NULL, `owner_share` TEXT NOT NULL," + + " `name` TEXT, `url` TEXT)" ) execSQL( - "CREATE TABLE IF NOT EXISTS `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `version_mayor` INTEGER NOT NULL, `version_minor` INTEGER NOT NULL, `version_micro` INTEGER NOT NULL, `version_string` TEXT, `version_edition` TEXT, `core_pollinterval` INTEGER NOT NULL, `sharing_api_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_write` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_public_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_days` INTEGER NOT NULL, `sharing_public_expire_date_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_public_upload` INTEGER NOT NULL DEFAULT -1, `sharing_public_multiple` INTEGER NOT NULL DEFAULT -1, `supports_upload_only` INTEGER NOT NULL DEFAULT -1, `sharing_user_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_resharing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_outgoing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_incoming` INTEGER NOT NULL DEFAULT -1, `files_bigfilechunking` INTEGER NOT NULL DEFAULT -1, `files_undelete` INTEGER NOT NULL DEFAULT -1, `files_versioning` INTEGER NOT NULL DEFAULT -1)" + "CREATE TABLE IF NOT EXISTS `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + + " `account` TEXT, `version_mayor` INTEGER NOT NULL, `version_minor` INTEGER NOT NULL, `version_micro` INTEGER NOT NULL," + + " `version_string` TEXT, `version_edition` TEXT, `core_pollinterval` INTEGER NOT NULL, `sharing_api_enabled` INTEGER NOT" + + " NULL DEFAULT -1, `sharing_public_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced` INTEGER NOT" + + " NULL DEFAULT -1, `sharing_public_password_enforced_read_only` INTEGER NOT NULL DEFAULT -1," + + " `sharing_public_password_enforced_read_write` INTEGER NOT NULL DEFAULT -1," + + " `sharing_public_password_enforced_public_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_enabled`" + + " INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_days` INTEGER NOT NULL, `sharing_public_expire_date_enforced`" + + " INTEGER NOT NULL DEFAULT -1, `sharing_public_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_public_upload` INTEGER NOT" + + " NULL DEFAULT -1, `sharing_public_multiple` INTEGER NOT NULL DEFAULT -1, `supports_upload_only` INTEGER NOT NULL DEFAULT" + + " -1, `sharing_user_send_mail` INTEGER NOT NULL DEFAULT -1, `sharing_resharing` INTEGER NOT NULL DEFAULT -1," + + " `sharing_federation_outgoing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_incoming` INTEGER NOT NULL DEFAULT -1," + + " `files_bigfilechunking` INTEGER NOT NULL DEFAULT -1, `files_undelete` INTEGER NOT NULL DEFAULT -1, `files_versioning`" + + " INTEGER NOT NULL DEFAULT -1)" ) execSQL( - "INSERT INTO `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` SELECT id, account, version_mayor, version_minor, version_micro, version_string, version_edition, core_pollinterval, IFNULL(sharing_api_enabled, -1), IFNULL(sharing_public_enabled, -1), IFNULL(sharing_public_password_enforced, -1),IFNULL(sharing_public_password_enforced_read_only, -1),IFNULL(sharing_public_password_enforced_read_write, -1),IFNULL(sharing_public_password_enforced_public_only, -1),IFNULL(sharing_public_expire_date_enabled, -1),IFNULL(sharing_public_expire_date_days, 0),IFNULL(sharing_public_expire_date_enforced, -1),IFNULL(sharing_public_send_mail, -1),IFNULL(sharing_public_upload, -1),IFNULL(sharing_public_multiple, -1), IFNULL(supports_upload_only, -1), IFNULL(sharing_user_send_mail, -1),IFNULL(sharing_resharing, -1),IFNULL(sharing_federation_outgoing, -1),IFNULL(sharing_federation_incoming, -1),IFNULL(files_bigfilechunking, -1),IFNULL(files_undelete, -1),IFNULL(files_versioning, -1) FROM ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}" + "INSERT INTO `${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` SELECT id, account, version_mayor, version_minor, version_micro," + + " version_string, version_edition, core_pollinterval, IFNULL(sharing_api_enabled, -1), IFNULL(sharing_public_enabled, -1)," + + " IFNULL(sharing_public_password_enforced, -1),IFNULL(sharing_public_password_enforced_read_only, -1)," + + "IFNULL(sharing_public_password_enforced_read_write, -1),IFNULL(sharing_public_password_enforced_public_only, -1)," + + "IFNULL(sharing_public_expire_date_enabled, -1),IFNULL(sharing_public_expire_date_days, 0)," + + "IFNULL(sharing_public_expire_date_enforced, -1),IFNULL(sharing_public_send_mail, -1),IFNULL(sharing_public_upload, -1)," + + "IFNULL(sharing_public_multiple, -1), IFNULL(supports_upload_only, -1), IFNULL(sharing_user_send_mail, -1)," + + "IFNULL(sharing_resharing, -1),IFNULL(sharing_federation_outgoing, -1),IFNULL(sharing_federation_incoming, -1)," + + "IFNULL(files_bigfilechunking, -1),IFNULL(files_undelete, -1),IFNULL(files_versioning, -1) " + + "FROM ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}" ) execSQL("DROP TABLE ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}") execSQL("ALTER TABLE ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}2 RENAME TO ${ProviderTableMeta.CAPABILITIES_TABLE_NAME}") diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_30.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_30.kt index 8cf2ccf6d82..2d700cdec94 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_30.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_30.kt @@ -27,13 +27,35 @@ val MIGRATION_29_30 = object : Migration(29, 30) { override fun migrate(database: SupportSQLiteDatabase) { database.run { execSQL( - "CREATE TABLE IF NOT EXISTS `${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `version_mayor` INTEGER NOT NULL, `version_minor` INTEGER NOT NULL, `version_micro` INTEGER NOT NULL, `version_string` TEXT, `version_edition` TEXT, `core_pollinterval` INTEGER NOT NULL, `dav_chunking_version` TEXT NOT NULL DEFAULT '',`sharing_api_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_write` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_public_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_days` INTEGER NOT NULL, `sharing_public_expire_date_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_upload` INTEGER NOT NULL DEFAULT -1, `sharing_public_multiple` INTEGER NOT NULL DEFAULT -1, `supports_upload_only` INTEGER NOT NULL DEFAULT -1, `sharing_resharing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_outgoing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_incoming` INTEGER NOT NULL DEFAULT -1, `files_bigfilechunking` INTEGER NOT NULL DEFAULT -1, `files_undelete` INTEGER NOT NULL DEFAULT -1, `files_versioning` INTEGER NOT NULL DEFAULT -1)" + "CREATE TABLE IF NOT EXISTS `${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT" + + " NOT NULL, `account` TEXT, `version_mayor` INTEGER NOT NULL, `version_minor` INTEGER NOT NULL, `version_micro` INTEGER" + + " NOT NULL, `version_string` TEXT, `version_edition` TEXT, `core_pollinterval` INTEGER NOT NULL, `dav_chunking_version`" + + " TEXT NOT NULL DEFAULT '',`sharing_api_enabled` INTEGER NOT NULL DEFAULT -1, `sharing_public_enabled` INTEGER NOT NULL" + + " DEFAULT -1, `sharing_public_password_enforced` INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_only`" + + " INTEGER NOT NULL DEFAULT -1, `sharing_public_password_enforced_read_write` INTEGER NOT NULL DEFAULT -1," + + " `sharing_public_password_enforced_public_only` INTEGER NOT NULL DEFAULT -1, `sharing_public_expire_date_enabled` INTEGER" + + " NOT NULL DEFAULT -1, `sharing_public_expire_date_days` INTEGER NOT NULL, `sharing_public_expire_date_enforced` INTEGER" + + " NOT NULL DEFAULT -1, `sharing_public_upload` INTEGER NOT NULL DEFAULT -1, `sharing_public_multiple` INTEGER NOT NULL" + + " DEFAULT -1, `supports_upload_only` INTEGER NOT NULL DEFAULT -1, `sharing_resharing` INTEGER NOT NULL DEFAULT -1," + + " `sharing_federation_outgoing` INTEGER NOT NULL DEFAULT -1, `sharing_federation_incoming` INTEGER NOT NULL DEFAULT -1," + + " `files_bigfilechunking` INTEGER NOT NULL DEFAULT -1, `files_undelete` INTEGER NOT NULL DEFAULT -1, `files_versioning`" + + " INTEGER NOT NULL DEFAULT -1)" ) execSQL( - "INSERT INTO `${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` SELECT id, account, version_mayor, version_minor, version_micro, version_string, version_edition, core_pollinterval, '', IFNULL(sharing_api_enabled, -1), IFNULL(sharing_public_enabled, -1), IFNULL(sharing_public_password_enforced, -1),IFNULL(sharing_public_password_enforced_read_only, -1),IFNULL(sharing_public_password_enforced_read_write, -1),IFNULL(sharing_public_password_enforced_public_only, -1),IFNULL(sharing_public_expire_date_enabled, -1),IFNULL(sharing_public_expire_date_days, 0),IFNULL(sharing_public_expire_date_enforced, -1), IFNULL(sharing_public_upload, -1),IFNULL(sharing_public_multiple, -1), IFNULL(supports_upload_only, -1), IFNULL(sharing_resharing, -1),IFNULL(sharing_federation_outgoing, -1),IFNULL(sharing_federation_incoming, -1),IFNULL(files_bigfilechunking, -1),IFNULL(files_undelete, -1),IFNULL(files_versioning, -1) FROM ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}" + "INSERT INTO `${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}2` SELECT id, account, version_mayor, version_minor," + + " version_micro, version_string, version_edition, core_pollinterval, '', IFNULL(sharing_api_enabled, -1)," + + " IFNULL(sharing_public_enabled, -1), IFNULL(sharing_public_password_enforced, -1)," + + "IFNULL(sharing_public_password_enforced_read_only, -1),IFNULL(sharing_public_password_enforced_read_write, -1)," + + "IFNULL(sharing_public_password_enforced_public_only, -1),IFNULL(sharing_public_expire_date_enabled, -1)," + + "IFNULL(sharing_public_expire_date_days, 0),IFNULL(sharing_public_expire_date_enforced, -1)," + + " IFNULL(sharing_public_upload, -1),IFNULL(sharing_public_multiple, -1), IFNULL(supports_upload_only, -1)," + + " IFNULL(sharing_resharing, -1),IFNULL(sharing_federation_outgoing, -1),IFNULL(sharing_federation_incoming, -1)," + + "IFNULL(files_bigfilechunking, -1),IFNULL(files_undelete, -1),IFNULL(files_versioning, -1) " + + "FROM ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}" ) execSQL("DROP TABLE ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}") - execSQL("ALTER TABLE ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}2 RENAME TO ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}") + execSQL("ALTER TABLE ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}2 RENAME TO" + + " ${ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME}") } } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_32.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_32.kt index da58db549f2..fb9cde4f05d 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_32.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_32.kt @@ -24,6 +24,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase val MIGRATION_31_32 = object : Migration(31, 32) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE IF NOT EXISTS `user_quotas` (`accountName` TEXT NOT NULL, `used` INTEGER NOT NULL, `available` INTEGER NOT NULL, PRIMARY KEY(`accountName`))") + database.execSQL("CREATE TABLE IF NOT EXISTS `user_quotas` (`accountName` TEXT NOT NULL, `used` INTEGER NOT NULL," + + " `available` INTEGER NOT NULL, PRIMARY KEY(`accountName`))") } } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_33.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_33.kt index 13ac1365bb0..c14dfa68146 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_33.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_33.kt @@ -31,7 +31,11 @@ val MIGRATION_32_33 = object : Migration(32, 33) { try { // 1. Create new OCShares table - database.execSQL("CREATE TABLE IF NOT EXISTS `${OCSHARES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `share_type` INTEGER NOT NULL, `share_with` TEXT, `path` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `shared_date` INTEGER NOT NULL, `expiration_date` INTEGER NOT NULL, `token` TEXT, `shared_with_display_name` TEXT, `share_with_additional_info` TEXT, `is_directory` INTEGER NOT NULL, `id_remote_shared` TEXT NOT NULL, `owner_share` TEXT NOT NULL, `name` TEXT, `url` TEXT)") + database.execSQL("CREATE TABLE IF NOT EXISTS `${OCSHARES_TABLE_NAME}2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + + " `share_type` INTEGER NOT NULL, `share_with` TEXT, `path` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `shared_date`" + + " INTEGER NOT NULL, `expiration_date` INTEGER NOT NULL, `token` TEXT, `shared_with_display_name` TEXT," + + " `share_with_additional_info` TEXT, `is_directory` INTEGER NOT NULL, `id_remote_shared` TEXT NOT NULL, `owner_share`" + + " TEXT NOT NULL, `name` TEXT, `url` TEXT)") // 2. Get old OCShares and insert them into the new table val cursor = database.query("SELECT * FROM $OCSHARES_TABLE_NAME") diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_34.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_34.kt index f58b2d83e4a..1c3500eceea 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_34.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_34.kt @@ -31,7 +31,9 @@ import java.io.File val MIGRATION_33_34 = object : Migration(33, 34) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE IF NOT EXISTS `$FOLDER_BACKUP_TABLE_NAME` (`accountName` TEXT NOT NULL, `behavior` TEXT NOT NULL, `sourcePath` TEXT NOT NULL, `uploadPath` TEXT NOT NULL, `wifiOnly` INTEGER NOT NULL, `name` TEXT NOT NULL, `lastSyncTimestamp` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") + database.execSQL("CREATE TABLE IF NOT EXISTS `$FOLDER_BACKUP_TABLE_NAME` (`accountName` TEXT NOT NULL, `behavior` TEXT NOT NULL," + + " `sourcePath` TEXT NOT NULL, `uploadPath` TEXT NOT NULL, `wifiOnly` INTEGER NOT NULL, `name` TEXT NOT NULL," + + " `lastSyncTimestamp` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") } } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_38.kt b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_38.kt index e52800ade85..87039dedef4 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_38.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/migrations/Migration_38.kt @@ -26,7 +26,15 @@ import androidx.sqlite.db.SupportSQLiteDatabase val MIGRATION_37_38 = object : Migration(37, 38) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE IF NOT EXISTS `files` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `parentId` INTEGER, `owner` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `remoteId` TEXT, `length` INTEGER NOT NULL, `creationTimestamp` INTEGER, `modificationTimestamp` INTEGER NOT NULL, `mimeType` TEXT NOT NULL, `etag` TEXT, `permissions` TEXT, `privateLink` TEXT, `storagePath` TEXT, `name` TEXT, `treeEtag` TEXT, `keepInSync` INTEGER, `lastSyncDateForData` INTEGER, `fileShareViaLink` INTEGER, `lastSyncDateForProperties` INTEGER, `needsToUpdateThumbnail` INTEGER NOT NULL, `modifiedAtLastSyncForData` INTEGER, `etagInConflict` TEXT, `fileIsDownloading` INTEGER, `sharedWithSharee` INTEGER, `sharedByLink` INTEGER NOT NULL)") - database.execSQL("CREATE TABLE IF NOT EXISTS `transfers` (`localPath` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `accountName` TEXT NOT NULL, `fileSize` INTEGER NOT NULL, `status` INTEGER NOT NULL, `localBehaviour` INTEGER NOT NULL, `forceOverwrite` INTEGER NOT NULL, `transferEndTimestamp` INTEGER, `lastResult` INTEGER, `createdBy` INTEGER NOT NULL, `transferId` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") + database.execSQL("CREATE TABLE IF NOT EXISTS `files` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `parentId` INTEGER," + + " `owner` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `remoteId` TEXT, `length` INTEGER NOT NULL, `creationTimestamp` INTEGER," + + " `modificationTimestamp` INTEGER NOT NULL, `mimeType` TEXT NOT NULL, `etag` TEXT, `permissions` TEXT, `privateLink` TEXT," + + " `storagePath` TEXT, `name` TEXT, `treeEtag` TEXT, `keepInSync` INTEGER, `lastSyncDateForData` INTEGER, `fileShareViaLink`" + + " INTEGER, `lastSyncDateForProperties` INTEGER, `needsToUpdateThumbnail` INTEGER NOT NULL, `modifiedAtLastSyncForData` INTEGER," + + " `etagInConflict` TEXT, `fileIsDownloading` INTEGER, `sharedWithSharee` INTEGER, `sharedByLink` INTEGER NOT NULL)") + database.execSQL("CREATE TABLE IF NOT EXISTS `transfers` (`localPath` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `accountName`" + + " TEXT NOT NULL, `fileSize` INTEGER NOT NULL, `status` INTEGER NOT NULL, `localBehaviour` INTEGER NOT NULL, `forceOverwrite`" + + " INTEGER NOT NULL, `transferEndTimestamp` INTEGER, `lastResult` INTEGER, `createdBy` INTEGER NOT NULL, `transferId` TEXT," + + " `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") } } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt index 55c6766443a..5c36eef73ff 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt @@ -296,7 +296,9 @@ class OCLocalFileDataSourceTest { @Test fun `getSearchAvailableOfflineFolderContent returns a list of OCFile`() { - every { fileDao.getSearchAvailableOfflineFolderContent(OC_FILE_AVAILABLE_OFFLINE_ENTITY.parentId!!, "test") } returns listOf(OC_FILE_AVAILABLE_OFFLINE_ENTITY) + every { + fileDao.getSearchAvailableOfflineFolderContent(OC_FILE_AVAILABLE_OFFLINE_ENTITY.parentId!!, "test") + } returns listOf(OC_FILE_AVAILABLE_OFFLINE_ENTITY) val result = ocLocalFileDataSource.getSearchAvailableOfflineFolderContent(OC_FILE_AVAILABLE_OFFLINE_ENTITY.parentId!!, "test") @@ -384,7 +386,9 @@ class OCLocalFileDataSourceTest { @Test fun `getSharedByLinkWithSyncInfoForAccountAsFlow returns a Flow with a list of OCFileWithSyncInfo`() = runTest { - val fileAndFileSyncEntitySharedByLink = OC_FILE_AND_FILE_SYNC.copy(file = OC_FILE_ENTITY.copy(sharedByLink = true).apply { this.id = OC_FILE_ENTITY.id }) + val fileAndFileSyncEntitySharedByLink = OC_FILE_AND_FILE_SYNC.copy(file = OC_FILE_ENTITY.copy(sharedByLink = true).apply { + this.id = OC_FILE_ENTITY.id + }) val fileWithSyncInfoSharedByLink = OC_FILE_WITH_SYNC_INFO_AND_SPACE.copy(file = OC_FILE.copy(sharedByLink = true)) @@ -411,14 +415,18 @@ class OCLocalFileDataSourceTest { @Test fun `getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow returns a Flow with a list of OCFileWithSyncInfo`() = runTest { val fileAndFileSyncEntityAvailableOffline = OC_FILE_AND_FILE_SYNC.copy( - file = OC_FILE_ENTITY.copy(availableOfflineStatus = AvailableOfflineStatus.AVAILABLE_OFFLINE.ordinal).apply { this.id = OC_FILE_ENTITY.id } + file = OC_FILE_ENTITY.copy(availableOfflineStatus = AvailableOfflineStatus.AVAILABLE_OFFLINE.ordinal).apply { + this.id = OC_FILE_ENTITY.id + } ) val fileWithSyncInfoAvailableOffline = OC_FILE_WITH_SYNC_INFO_AND_SPACE.copy( file = OC_FILE.copy(availableOfflineStatus = AvailableOfflineStatus.AVAILABLE_OFFLINE) ) - every { fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) } returns flowOf(listOf(fileAndFileSyncEntityAvailableOffline)) + every { + fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) + } returns flowOf(listOf(fileAndFileSyncEntityAvailableOffline)) val result = ocLocalFileDataSource.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME).first() @@ -428,7 +436,8 @@ class OCLocalFileDataSourceTest { } @Test - fun `getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow returns a Flow with an empty list when DAO returns a Flow with an empty list`() = runTest { + fun `getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow returns a Flow with an empty list when DAO returns a Flow with an empty list`() + = runTest { every { fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) } returns flowOf(emptyList()) val result = ocLocalFileDataSource.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME).first() diff --git a/owncloudData/src/test/java/com/owncloud/android/data/files/repository/OCFileRepositoryTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/files/repository/OCFileRepositoryTest.kt index f63a53c41aa..70929cc9cb6 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/files/repository/OCFileRepositoryTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/files/repository/OCFileRepositoryTest.kt @@ -131,6 +131,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `copyFile returns a list with the OCFile in conflict (the copied OCFile) when replace parameter is empty and expected path already exists`() { every { @@ -341,6 +342,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `copyFile removes target folder locally and throws a ConflictException when replace parameter is empty and expected path doesn't exist but target folder doesn't exist anymore`() { every { @@ -398,6 +400,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `copyFile removes source file locally and throws a FileNotFoundException when replace parameter is empty and expected path doesn't exist but source file doesn't exist anymore`() { every { @@ -548,7 +551,11 @@ class OCFileRepositoryTest { ) } returns OC_FILE_WITH_SPACE_ID - val ocFile = ocFileRepository.getFileByRemotePath(OC_FILE_WITH_SPACE_ID.remotePath, OC_FOLDER_WITH_SPACE_ID.owner, OC_FOLDER_WITH_SPACE_ID.spaceId) + val ocFile = ocFileRepository.getFileByRemotePath( + OC_FILE_WITH_SPACE_ID.remotePath, + OC_FOLDER_WITH_SPACE_ID.owner, + OC_FOLDER_WITH_SPACE_ID.spaceId + ) assertEquals(OC_FILE_WITH_SPACE_ID, ocFile) verify(exactly = 1) { @@ -570,7 +577,11 @@ class OCFileRepositoryTest { ) } returns null - val ocFile = ocFileRepository.getFileByRemotePath(OC_FILE_WITH_SPACE_ID.remotePath, OC_FOLDER_WITH_SPACE_ID.owner, OC_FOLDER_WITH_SPACE_ID.spaceId) + val ocFile = ocFileRepository.getFileByRemotePath( + OC_FILE_WITH_SPACE_ID.remotePath, + OC_FOLDER_WITH_SPACE_ID.owner, + OC_FOLDER_WITH_SPACE_ID.spaceId + ) assertNull(ocFile) verify(exactly = 1) { @@ -1093,6 +1104,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `moveFile returns an empty list with no OCFiles in conflict when replace parameter is empty, expected path doesn't exist and file has a conflict`() { every { @@ -1271,6 +1283,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `moveFile removes target folder locally and throws a ConflictException when replace parameter is empty and expected path doesn't exist but target folder doesn't exist anymore`() { every { @@ -1334,6 +1347,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `moveFile removes source file locally and throws a FileNotFoundException when replace parameter is empty and expected path doesn't exist but source file doesn't exist anymore`() { every { @@ -1449,7 +1463,12 @@ class OCFileRepositoryTest { ) } returns emptyList() - val listOfFiles = ocFileRepository.refreshFolder(OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, OC_PARENT_FOLDER_WITH_SPACE_ID.owner, OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, false) + val listOfFiles = ocFileRepository.refreshFolder( + OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, + OC_PARENT_FOLDER_WITH_SPACE_ID.owner, + OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, + false + ) assertEquals(emptyList(), listOfFiles) verify(exactly = 1) { @@ -1505,7 +1524,12 @@ class OCFileRepositoryTest { ) } returns emptyList() - val listOfFiles = ocFileRepository.refreshFolder(OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, OC_PARENT_FOLDER_WITH_SPACE_ID.owner, OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, false) + val listOfFiles = ocFileRepository.refreshFolder( + OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, + OC_PARENT_FOLDER_WITH_SPACE_ID.owner, + OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, + false + ) assertEquals(emptyList(), listOfFiles) verify(exactly = 1) { @@ -1533,6 +1557,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `refreshFolder returns a list with the OCFile that changed when folder and its content already exists in database but needs to be updated`() { val ocParentFolderWithoutSpaceId = OC_PARENT_FOLDER_WITH_SPACE_ID.copy(spaceId = null) @@ -1563,7 +1588,12 @@ class OCFileRepositoryTest { ) } returns listOf(OC_FILE_WITH_SPACE_ID) - val listOfFiles = ocFileRepository.refreshFolder(OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, OC_PARENT_FOLDER_WITH_SPACE_ID.owner, OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, true) + val listOfFiles = ocFileRepository.refreshFolder( + OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, + OC_PARENT_FOLDER_WITH_SPACE_ID.owner, + OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, + true + ) assertEquals(listOf(OC_FILE_WITH_SPACE_ID), listOfFiles) verify(exactly = 1) { @@ -1591,6 +1621,7 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `refreshFolder returns an empty list of OCFiles when folder and its content already exists in database updated and the action is not set folder available offline or synchronize`() { val ocParentFolderWithoutSpaceId = OC_PARENT_FOLDER_WITH_SPACE_ID.copy(spaceId = null) @@ -1621,7 +1652,12 @@ class OCFileRepositoryTest { ) } returns emptyList() - val listOfFiles = ocFileRepository.refreshFolder(OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, OC_PARENT_FOLDER_WITH_SPACE_ID.owner, OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, false) + val listOfFiles = ocFileRepository.refreshFolder( + OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, + OC_PARENT_FOLDER_WITH_SPACE_ID.owner, + OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, + false + ) assertEquals(emptyList(), listOfFiles) verify(exactly = 1) { @@ -1649,11 +1685,13 @@ class OCFileRepositoryTest { } } + @Suppress("MaxLineLength") @Test fun `refreshFolder returns an empty list of OCFiles when folder and its content already exists in database but there are additional files in conflict in local to be removed`() { val ocParentFolderWithoutSpaceId = OC_PARENT_FOLDER_WITH_SPACE_ID.copy(spaceId = null) val ocFileWithoutSpaceId = OC_FILE_WITH_SPACE_ID.copy(spaceId = null) - val additionalOcFile = OC_FILE_WITH_SPACE_ID.copy(id = 300, remotePath = "/Folder/image3.jpt", remoteId = "00000003oci9p7er2hox2", privateLink = "http://server.url/f/70", etagInConflict = etagInConflict) + val additionalOcFile = OC_FILE_WITH_SPACE_ID.copy(id = 300, remotePath = "/Folder/image3.jpt", + remoteId = "00000003oci9p7er2hox2", privateLink = "http://server.url/f/70", etagInConflict = etagInConflict) every { remoteFileDataSource.refreshFolder( remotePath = OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, @@ -1683,7 +1721,11 @@ class OCFileRepositoryTest { ) } returns emptyList() - val listOfFiles = ocFileRepository.refreshFolder(OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, OC_PARENT_FOLDER_WITH_SPACE_ID.owner, OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, false) + val listOfFiles = ocFileRepository.refreshFolder( + OC_PARENT_FOLDER_WITH_SPACE_ID.remotePath, + OC_PARENT_FOLDER_WITH_SPACE_ID.owner, + OC_PARENT_FOLDER_WITH_SPACE_ID.spaceId, + false) assertEquals(emptyList(), listOfFiles) verify(exactly = 1) { diff --git a/owncloudData/src/test/java/com/owncloud/android/data/server/repository/OCServerInfoRepositoryTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/server/repository/OCServerInfoRepositoryTest.kt index c28ada8c960..d4fd55ae7fc 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/server/repository/OCServerInfoRepositoryTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/server/repository/OCServerInfoRepositoryTest.kt @@ -37,7 +37,8 @@ class OCServerInfoRepositoryTest { private val remoteServerInfoDataSource = mockk(relaxed = true) private val webFingerDataSource = mockk(relaxed = true) private val oidcRemoteOAuthDataSource = mockk(relaxed = true) - private val ocServerInfoRepository: OCServerInfoRepository = OCServerInfoRepository(remoteServerInfoDataSource, webFingerDataSource, oidcRemoteOAuthDataSource) + private val ocServerInfoRepository: OCServerInfoRepository = + OCServerInfoRepository(remoteServerInfoDataSource, webFingerDataSource, oidcRemoteOAuthDataSource) @Test fun getServerInfoSuccess() { diff --git a/owncloudData/src/test/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSourceTest.kt index df3bcca4496..a1e36cdc435 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSourceTest.kt @@ -108,7 +108,12 @@ class OCLocalTransferDataSourceTest { ocLocalTransferDataSource.updateTransferWhenFinished(OC_TRANSFER.id!!, TransferStatus.TRANSFER_SUCCEEDED, timestamp, TransferResult.UPLOADED) verify(exactly = 1) { - transferDao.updateTransferWhenFinished(OC_TRANSFER.id!!, TransferStatus.TRANSFER_SUCCEEDED.value, timestamp, TransferResult.UPLOADED.value) + transferDao.updateTransferWhenFinished( + OC_TRANSFER.id!!, + TransferStatus.TRANSFER_SUCCEEDED.value, + timestamp, + TransferResult.UPLOADED.value + ) } } From 4f6a856b13132a6409349e4262d35fce8adfcaad Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 10 Dec 2024 11:09:20 +0100 Subject: [PATCH 14/31] style: wrap lines more than 150 characters in module `owncloudDomain` --- .../GetFilesAvailableOfflineFromAccountAsStreamUseCase.kt | 3 ++- .../domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/availableoffline/usecases/GetFilesAvailableOfflineFromAccountAsStreamUseCase.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/availableoffline/usecases/GetFilesAvailableOfflineFromAccountAsStreamUseCase.kt index a100b186325..a6e71d852af 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/availableoffline/usecases/GetFilesAvailableOfflineFromAccountAsStreamUseCase.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/availableoffline/usecases/GetFilesAvailableOfflineFromAccountAsStreamUseCase.kt @@ -26,7 +26,8 @@ class GetFilesAvailableOfflineFromAccountAsStreamUseCase( private val fileRepository: FileRepository ) : BaseUseCase>, GetFilesAvailableOfflineFromAccountAsStreamUseCase.Params>() { - override fun run(params: Params): Flow> = fileRepository.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(params.owner) + override fun run(params: Params): Flow> = + fileRepository.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(params.owner) data class Params( val owner: String diff --git a/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt b/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt index f39c7977b7d..c266e4e4ff7 100644 --- a/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt +++ b/owncloudDomain/src/test/java/com/owncloud/android/domain/server/usecases/GetServerInfoAsyncUseCaseTest.kt @@ -78,6 +78,7 @@ class GetServerInfoAsyncUseCaseTest { verify(exactly = 1) { repository.getServerInfo(useCaseParams.serverPath, false, false) } } + @Suppress("MaxLineLength") @Test fun `Should throw SSLErrorException when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning false`() { every { repository.getServerInfo(useCaseParams.serverPath, false, false) } returns OC_INSECURE_SERVER_INFO_BASIC_AUTH @@ -90,6 +91,7 @@ class GetServerInfoAsyncUseCaseTest { verify(exactly = 1) { repository.getServerInfo(useCaseParams.serverPath, false, false) } } + @Suppress("MaxLineLength") @Test fun `Should work correctly when secureConnectionEnforced is true and ServerInfoRepository returns ServerInfo with isSecureConnection returning true`() { every { repository.getServerInfo(useCaseParams.serverPath, false, false) } returns OC_SECURE_SERVER_INFO_BASIC_AUTH From f5e6c18fdf2cfef9fda2195a3e497ded5090dcda Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 10 Dec 2024 11:11:22 +0100 Subject: [PATCH 15/31] style: wrap lines more than 150 characters in module `owncloudTestUtil` --- .../src/main/java/com/owncloud/android/testutil/OCSpace.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt b/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt index 26ff75cd45a..36c0d6ccbae 100644 --- a/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt +++ b/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt @@ -55,7 +55,8 @@ val OC_SPACE_SPECIAL_README = SpaceSpecial( specialFolder = SpaceSpecialFolder( name = "readme" ), - webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199%210aa0e03c-ec36-498c-bb9f-857315568199/.space/readme.md" + webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$" + + "0aa0e03c-ec36-498c-bb9f-857315568199%210aa0e03c-ec36-498c-bb9f-857315568199/.space/readme.md" ) val OC_SPACE_SPECIAL_IMAGE = SpaceSpecial( @@ -70,7 +71,8 @@ val OC_SPACE_SPECIAL_IMAGE = SpaceSpecial( specialFolder = SpaceSpecialFolder( name = "image" ), - webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199%210aa0e03c-ec36-498c-bb9f-857315568199/.space/image.jpg" + webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$" + + "0aa0e03c-ec36-498c-bb9f-857315568199%210aa0e03c-ec36-498c-bb9f-857315568199/.space/image.jpg" ) val OC_SPACE_PROJECT_WITH_IMAGE = OCSpace( From fd7e0260e4050a3971f723557c5d9bb0962a9927 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 11 Dec 2024 13:42:08 +0100 Subject: [PATCH 16/31] refactor: refactor methods with more than 100 lines --- .../files/filelist/FileListAdapter.kt | 137 +++--- .../files/filelist/MainFileListFragment.kt | 425 ++++++++++-------- .../security/SettingsSecurityFragment.kt | 9 +- .../sharees/UsersAndGroupsSearchProvider.kt | 29 +- .../transfers/TransfersAdapter.kt | 266 +++++------ .../android/providers/FileContentProvider.kt | 1 + .../android/ui/activity/DrawerActivity.kt | 202 ++++----- 7 files changed, 567 insertions(+), 502 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt index cba5cdf369e..d84a1a6a467 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt @@ -207,71 +207,7 @@ class FileListAdapter( holder.itemView.findViewById(R.id.shared_via_users_icon).isVisible = file.sharedWithSharee == true || file.isSharedWithMe - when (viewType) { - ViewType.LIST_ITEM.ordinal -> { - val view = holder as ListViewHolder - view.binding.let { - it.fileListConstraintLayout.filterTouchesWhenObscured = PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(context) - it.Filename.text = file.fileName - it.fileListSize.text = DisplayUtils.bytesToHumanReadable(file.length, context, true) - it.fileListLastMod.text = DisplayUtils.getRelativeTimestamp(context, file.modificationTimestamp) - it.threeDotMenu.isVisible = getCheckedItems().isEmpty() - it.threeDotMenu.contentDescription = context.getString(R.string.content_description_file_operations, file.fileName) - if (fileListOption.isAvailableOffline() || (fileListOption.isSharedByLink() && fileWithSyncInfo.space == null)) { - it.spacePathLine.path.apply { - text = file.getParentRemotePath() - isVisible = true - } - fileWithSyncInfo.space?.let { space -> - it.spacePathLine.spaceIcon.isVisible = true - it.spacePathLine.spaceName.isVisible = true - if (space.isPersonal) { - it.spacePathLine.spaceIcon.setImageResource(R.drawable.ic_folder) - it.spacePathLine.spaceName.setText(R.string.bottom_nav_personal) - } else { - it.spacePathLine.spaceName.text = space.name - } - } - } else { - it.spacePathLine.path.isVisible = false - it.spacePathLine.spaceIcon.isVisible = false - it.spacePathLine.spaceName.isVisible = false - } - it.threeDotMenu.setOnClickListener { - listener.onThreeDotButtonClick(fileWithSyncInfo = fileWithSyncInfo) - } - } - } - - ViewType.GRID_ITEM.ordinal -> { - // Filename - val view = holder as GridViewHolder - view.binding.Filename.text = file.fileName - } - - ViewType.GRID_IMAGE.ordinal -> { - val view = holder as GridImageViewHolder - val layoutParams = fileIcon.layoutParams as ViewGroup.MarginLayoutParams - - if (thumbnail == null) { - view.binding.Filename.text = file.fileName - // Reset layout params values default - manageGridLayoutParams( - layoutParams = layoutParams, - marginVertical = 0, - height = context.resources.getDimensionPixelSize(R.dimen.item_file_grid_height), - width = context.resources.getDimensionPixelSize(R.dimen.item_file_grid_width), - ) - } else { - manageGridLayoutParams( - layoutParams = layoutParams, - marginVertical = context.resources.getDimensionPixelSize(R.dimen.item_file_image_grid_margin), - height = ViewGroup.LayoutParams.MATCH_PARENT, - width = ViewGroup.LayoutParams.MATCH_PARENT, - ) - } - } - } + setSpecificViewHolder(viewType, holder, fileWithSyncInfo, thumbnail) setIconPinAccordingToFilesLocalState(holder.itemView.findViewById(R.id.localFileIndicator), fileWithSyncInfo) @@ -342,6 +278,77 @@ class FileListAdapter( } } + private fun setSpecificViewHolder(viewType: Int, holder: RecyclerView.ViewHolder, fileWithSyncInfo: OCFileWithSyncInfo, thumbnail: Bitmap?) { + val file = fileWithSyncInfo.file + + when (viewType) { + ViewType.LIST_ITEM.ordinal -> { + val view = holder as ListViewHolder + view.binding.let { + it.fileListConstraintLayout.filterTouchesWhenObscured = PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(context) + it.Filename.text = file.fileName + it.fileListSize.text = DisplayUtils.bytesToHumanReadable(file.length, context, true) + it.fileListLastMod.text = DisplayUtils.getRelativeTimestamp(context, file.modificationTimestamp) + it.threeDotMenu.isVisible = getCheckedItems().isEmpty() + it.threeDotMenu.contentDescription = context.getString(R.string.content_description_file_operations, file.fileName) + if (fileListOption.isAvailableOffline() || (fileListOption.isSharedByLink() && fileWithSyncInfo.space == null)) { + it.spacePathLine.path.apply { + text = file.getParentRemotePath() + isVisible = true + } + fileWithSyncInfo.space?.let { space -> + it.spacePathLine.spaceIcon.isVisible = true + it.spacePathLine.spaceName.isVisible = true + if (space.isPersonal) { + it.spacePathLine.spaceIcon.setImageResource(R.drawable.ic_folder) + it.spacePathLine.spaceName.setText(R.string.bottom_nav_personal) + } else { + it.spacePathLine.spaceName.text = space.name + } + } + } else { + it.spacePathLine.path.isVisible = false + it.spacePathLine.spaceIcon.isVisible = false + it.spacePathLine.spaceName.isVisible = false + } + it.threeDotMenu.setOnClickListener { + listener.onThreeDotButtonClick(fileWithSyncInfo = fileWithSyncInfo) + } + } + } + + ViewType.GRID_ITEM.ordinal -> { + // Filename + val view = holder as GridViewHolder + view.binding.Filename.text = file.fileName + } + + ViewType.GRID_IMAGE.ordinal -> { + val view = holder as GridImageViewHolder + val fileIcon = holder.itemView.findViewById(R.id.thumbnail) + val layoutParams = fileIcon.layoutParams as ViewGroup.MarginLayoutParams + + if (thumbnail == null) { + view.binding.Filename.text = file.fileName + // Reset layout params values default + manageGridLayoutParams( + layoutParams = layoutParams, + marginVertical = 0, + height = context.resources.getDimensionPixelSize(R.dimen.item_file_grid_height), + width = context.resources.getDimensionPixelSize(R.dimen.item_file_grid_width), + ) + } else { + manageGridLayoutParams( + layoutParams = layoutParams, + marginVertical = context.resources.getDimensionPixelSize(R.dimen.item_file_image_grid_margin), + height = ViewGroup.LayoutParams.MATCH_PARENT, + width = ViewGroup.LayoutParams.MATCH_PARENT, + ) + } + } + } + } + private fun manageGridLayoutParams(layoutParams: ViewGroup.MarginLayoutParams, marginVertical: Int, height: Int, width: Int) { val marginHorizontal = context.resources.getDimensionPixelSize(R.dimen.item_file_image_grid_margin) layoutParams.setMargins(marginHorizontal, marginVertical, marginHorizontal, marginVertical) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt index d62967464a5..5883200360b 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt @@ -314,6 +314,50 @@ class MainFileListFragment : Fragment(), private fun subscribeToViewModels() { /* MainFileListViewModel observables */ // Observe the current folder displayed + observeCurrentFolderDisplayed() + + // Observe the current space to update the toolbar + // We can't rely exclusively on the [currentFolderDisplayed] because sometimes retrieving the space takes more time + observeSpace() + + // Observe the list of app registries that allow creating new files + observeAppRegistryToCreateFiles() + + // Observe the open in web action to trigger browser + observeOpenInWebFlow() + + // Observe the menu filtered options in multiselection + observeMenuOptions() + + // Observe the app registry in multiselection + observeAppRegistryMimeType() + + // Observe the menu filtered options for a single file + observeMenuOptionsSingleFile() + + // Observe the app registry for a single file + observeAppRegistryMimeTypeSingleFile() + + // Observe the file list UI state + observeFileListUiState() + + /* FileOperationsViewModel observables */ + // Observe the refresh folder operation + observeRefreshFolder() + + // Observe the create file with app provider operation + observeCreateFileWithAppProvider() + + // Observe the check if file is local and not available offline operation + observeCheckIfFileIsLocalAndNotAvailableOffline() + + /* TransfersViewModel observables */ + // Observe transfers + observeTransfers() + + } + + private fun observeCurrentFolderDisplayed() { collectLatestLifecycleFlow(mainFileListViewModel.currentFolderDisplayed) { currentFolderDisplayed: OCFile -> fileActions?.onCurrentFolderUpdated(currentFolderDisplayed, mainFileListViewModel.getSpace()) val fileListOption = mainFileListViewModel.fileListOption.value @@ -336,22 +380,23 @@ class MainFileListFragment : Fragment(), numberOfUploadsRefreshed = 0 hideRefreshFab() } + } - // Observe the current space to update the toolbar - // We can't rely exclusively on the [currentFolderDisplayed] because sometimes retrieving the space takes more time + private fun observeSpace() { collectLatestLifecycleFlow(mainFileListViewModel.space) { currentSpace: OCSpace? -> currentSpace?.let { fileActions?.onCurrentFolderUpdated(mainFileListViewModel.getFile(), currentSpace) } } - - // Observe the list of app registries that allow creating new files + } + private fun observeAppRegistryToCreateFiles() { collectLatestLifecycleFlow(mainFileListViewModel.appRegistryToCreateFiles) { listAppRegistry -> binding.fabNewfile.isVisible = listAppRegistry.isNotEmpty() registerFabNewFileListener(listAppRegistry) } + } - // Observe the open in web action to trigger browser + private fun observeOpenInWebFlow() { collectLatestLifecycleFlow(mainFileListViewModel.openInWebFlow) { if (it != null) { val uiResult = it.peekContent() @@ -382,8 +427,9 @@ class MainFileListFragment : Fragment(), currentDefaultApplication = null } } + } - // Observe the menu filtered options in multiselection + private fun observeMenuOptions() { collectLatestLifecycleFlow(mainFileListViewModel.menuOptions) { menuOptions -> val hasWritePermission = if (checkedFiles.size == 1) { checkedFiles.first().hasWritePermission @@ -392,16 +438,18 @@ class MainFileListFragment : Fragment(), } menu?.filterMenuOptions(menuOptions, hasWritePermission) } + } - // Observe the app registry in multiselection + private fun observeAppRegistryMimeType() { collectLatestLifecycleFlow(mainFileListViewModel.appRegistryMimeType) { appRegistryMimeType -> val appProviders = appRegistryMimeType?.appProviders menu?.let { openInWebProviders = addOpenInWebMenuOptions(it, openInWebProviders, appProviders) } } + } - // Observe the menu filtered options for a single file + private fun observeMenuOptionsSingleFile() { collectLatestLifecycleFlow(mainFileListViewModel.menuOptionsSingleFile) { menuOptions -> fileSingleFile?.let { file -> val fileOptionsBottomSheetSingleFile = layoutInflater.inflate(R.layout.file_options_bottom_sheet_fragment, null) @@ -462,119 +510,124 @@ class MainFileListFragment : Fragment(), fileOptionsBottomSheetSingleFileLayout = fileOptionsBottomSheetSingleFile.findViewById(R.id.file_options_bottom_sheet_layout) menuOptions.forEach { menuOption -> - val fileOptionItemView = BottomSheetFragmentItemView(requireContext()) - fileOptionItemView.apply { - title = if (menuOption.toResId() == R.id.action_open_file_with && !file.hasWritePermission) { - getString(R.string.actionbar_open_with_read_only) - } else { - getString(menuOption.toStringResId()) + setMenuOption(menuOption, file, dialog) + } + // Disable drag gesture + fileOptionsBottomSheetSingleFileBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { + override fun onStateChanged(bottomSheet: View, newState: Int) { + if (newState == BottomSheetBehavior.STATE_DRAGGING) { + fileOptionsBottomSheetSingleFileBehavior.state = BottomSheetBehavior.STATE_EXPANDED } - itemIcon = ResourcesCompat.getDrawable(resources, menuOption.toDrawableResId(), null) - setOnClickListener { - when (menuOption) { - FileMenuOption.SELECT_ALL -> { - // Not applicable here - } + } - FileMenuOption.SELECT_INVERSE -> { - // Not applicable here - } + override fun onSlide(bottomSheet: View, slideOffset: Float) {} + }) + dialog.setOnShowListener { fileOptionsBottomSheetSingleFileBehavior.peekHeight = fileOptionsBottomSheetSingleFile.measuredHeight } + dialog.show() + mainFileListViewModel.getAppRegistryForMimeType(file.mimeType, isMultiselection = false) + } + } + } - FileMenuOption.DOWNLOAD, FileMenuOption.SYNC -> { - syncFiles(listOf(file)) - } + private fun setMenuOption(menuOption: FileMenuOption, file: OCFile, dialog: BottomSheetDialog) { + val fileOptionItemView = BottomSheetFragmentItemView(requireContext()) + fileOptionItemView.apply { + title = if (menuOption.toResId() == R.id.action_open_file_with && !file.hasWritePermission) { + getString(R.string.actionbar_open_with_read_only) + } else { + getString(menuOption.toStringResId()) + } + itemIcon = ResourcesCompat.getDrawable(resources, menuOption.toDrawableResId(), null) + setOnClickListener { + when (menuOption) { + FileMenuOption.SELECT_ALL -> { + // Not applicable here + } - FileMenuOption.RENAME -> { - val dialogRename = RenameFileDialogFragment.newInstance(file) - dialogRename.show(requireActivity().supportFragmentManager, FRAGMENT_TAG_RENAME_FILE) - } + FileMenuOption.SELECT_INVERSE -> { + // Not applicable here + } - FileMenuOption.MOVE -> { - val action = Intent(activity, FolderPickerActivity::class.java) - action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, arrayListOf(file)) - action.putExtra(FolderPickerActivity.EXTRA_PICKER_MODE, FolderPickerActivity.PickerMode.MOVE) - requireActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__MOVE_FILES) - } + FileMenuOption.DOWNLOAD, FileMenuOption.SYNC -> { + syncFiles(listOf(file)) + } - FileMenuOption.COPY -> { - val action = Intent(activity, FolderPickerActivity::class.java) - action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, arrayListOf(file)) - action.putExtra(FolderPickerActivity.EXTRA_PICKER_MODE, FolderPickerActivity.PickerMode.COPY) - requireActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__COPY_FILES) - } + FileMenuOption.RENAME -> { + val dialogRename = RenameFileDialogFragment.newInstance(file) + dialogRename.show(requireActivity().supportFragmentManager, FRAGMENT_TAG_RENAME_FILE) + } - FileMenuOption.REMOVE -> { - filesToRemove = listOf(file) - fileOperationsViewModel.showRemoveDialog(filesToRemove) - } + FileMenuOption.MOVE -> { + val action = Intent(activity, FolderPickerActivity::class.java) + action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, arrayListOf(file)) + action.putExtra(FolderPickerActivity.EXTRA_PICKER_MODE, FolderPickerActivity.PickerMode.MOVE) + requireActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__MOVE_FILES) + } - FileMenuOption.OPEN_WITH -> { - fileActions?.openFile(file) - } + FileMenuOption.COPY -> { + val action = Intent(activity, FolderPickerActivity::class.java) + action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, arrayListOf(file)) + action.putExtra(FolderPickerActivity.EXTRA_PICKER_MODE, FolderPickerActivity.PickerMode.COPY) + requireActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__COPY_FILES) + } - FileMenuOption.CANCEL_SYNC -> { - fileActions?.cancelFileTransference(arrayListOf(file)) - } + FileMenuOption.REMOVE -> { + filesToRemove = listOf(file) + fileOperationsViewModel.showRemoveDialog(filesToRemove) + } - FileMenuOption.SHARE -> { - fileActions?.onShareFileClicked(file) - } + FileMenuOption.OPEN_WITH -> { + fileActions?.openFile(file) + } - FileMenuOption.DETAILS -> { - fileActions?.showDetails(file) - } + FileMenuOption.CANCEL_SYNC -> { + fileActions?.cancelFileTransference(arrayListOf(file)) + } - FileMenuOption.SEND -> { - if (!file.isAvailableLocally) { // Download the file - Timber.d("${file.remotePath} : File must be downloaded") - fileActions?.initDownloadForSending(file) - } else { - fileActions?.sendDownloadedFile(file) - } - } + FileMenuOption.SHARE -> { + fileActions?.onShareFileClicked(file) + } - FileMenuOption.SET_AV_OFFLINE -> { - fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(listOf(file))) - if (file.isFolder) { - fileOperationsViewModel.performOperation( - FileOperation.SynchronizeFolderOperation( - folderToSync = file, - accountName = file.owner, - isActionSetFolderAvailableOfflineOrSynchronize = true, - ) - ) - } else { - fileOperationsViewModel.performOperation(FileOperation.SynchronizeFileOperation(file, file.owner)) - } - } + FileMenuOption.DETAILS -> { + fileActions?.showDetails(file) + } - FileMenuOption.UNSET_AV_OFFLINE -> { - fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(listOf(file))) - } - } - dialog.hide() - dialog.dismiss() + FileMenuOption.SEND -> { + if (!file.isAvailableLocally) { // Download the file + Timber.d("${file.remotePath} : File must be downloaded") + fileActions?.initDownloadForSending(file) + } else { + fileActions?.sendDownloadedFile(file) } } - fileOptionsBottomSheetSingleFileLayout!!.addView(fileOptionItemView) - } - // Disable drag gesture - fileOptionsBottomSheetSingleFileBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { - override fun onStateChanged(bottomSheet: View, newState: Int) { - if (newState == BottomSheetBehavior.STATE_DRAGGING) { - fileOptionsBottomSheetSingleFileBehavior.state = BottomSheetBehavior.STATE_EXPANDED + + FileMenuOption.SET_AV_OFFLINE -> { + fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(listOf(file))) + if (file.isFolder) { + fileOperationsViewModel.performOperation( + FileOperation.SynchronizeFolderOperation( + folderToSync = file, + accountName = file.owner, + isActionSetFolderAvailableOfflineOrSynchronize = true, + ) + ) + } else { + fileOperationsViewModel.performOperation(FileOperation.SynchronizeFileOperation(file, file.owner)) } } - override fun onSlide(bottomSheet: View, slideOffset: Float) {} - }) - dialog.setOnShowListener { fileOptionsBottomSheetSingleFileBehavior.peekHeight = fileOptionsBottomSheetSingleFile.measuredHeight } - dialog.show() - mainFileListViewModel.getAppRegistryForMimeType(file.mimeType, isMultiselection = false) + FileMenuOption.UNSET_AV_OFFLINE -> { + fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(listOf(file))) + } + } + dialog.hide() + dialog.dismiss() } } + fileOptionsBottomSheetSingleFileLayout!!.addView(fileOptionItemView) + } - // Observe the app registry for a single file + private fun observeAppRegistryMimeTypeSingleFile() { collectLatestLifecycleFlow(mainFileListViewModel.appRegistryMimeTypeSingleFile) { appRegistryMimeType -> fileSingleFile?.let { file -> val appProviders = appRegistryMimeType?.appProviders @@ -600,8 +653,19 @@ class MainFileListFragment : Fragment(), } fileSingleFile = null } + } - // Observe the file list UI state + private suspend fun getDrawableFromUrl(context: Context, url: String): Drawable? { + return withContext(Dispatchers.IO) { + Glide.with(context) + .load(url) + .fitCenter() + .submit() + .get() + } + } + + private fun observeFileListUiState() { collectLatestLifecycleFlow(mainFileListViewModel.fileListUiState) { fileListUiState -> if (fileListUiState !is MainFileListViewModel.FileListUiState.Success) return@collectLatestLifecycleFlow @@ -636,9 +700,9 @@ class MainFileListFragment : Fragment(), actionMode?.invalidate() } + } - /* FileOperationsViewModel observables */ - // Observe the refresh folder operation + private fun observeRefreshFolder() { fileOperationsViewModel.refreshFolderLiveData.observe(viewLifecycleOwner) { binding.syncProgressBar.isIndeterminate = it.peekContent().isLoading binding.swipeRefreshMainFileList.isRefreshing = it.peekContent().isLoading @@ -648,8 +712,9 @@ class MainFileListFragment : Fragment(), hideRefreshFab() } + } - // Observe the create file with app provider operation + private fun observeCreateFileWithAppProvider() { collectLatestLifecycleFlow(fileOperationsViewModel.createFileWithAppProviderFlow) { val uiResult = it?.peekContent() if (uiResult is UIResult.Error) { @@ -666,7 +731,9 @@ class MainFileListFragment : Fragment(), } } } + } + private fun observeCheckIfFileIsLocalAndNotAvailableOffline() { collectLatestLifecycleFlow(fileOperationsViewModel.checkIfFileIsLocalAndNotAvailableOfflineSharedFlow) { val fileActivity = (requireActivity() as FileActivity) when (it) { @@ -682,20 +749,6 @@ class MainFileListFragment : Fragment(), } } } - - /* TransfersViewModel observables */ - observeTransfers() - - } - - private suspend fun getDrawableFromUrl(context: Context, url: String): Drawable? { - return withContext(Dispatchers.IO) { - Glide.with(context) - .load(url) - .fitCenter() - .submit() - .get() - } } private fun observeTransfers() { @@ -1148,91 +1201,102 @@ class MainFileListFragment : Fragment(), */ @SuppressLint("UseRequireInsteadOfGet") private fun onFileActionChosen(menuId: Int?): Boolean { + var handled: Boolean val checkedFilesWithSyncInfo = fileListAdapter.getCheckedItems() as ArrayList if (checkedFilesWithSyncInfo.isEmpty()) { return false } else if (checkedFilesWithSyncInfo.size == 1) { - /// action only possible on a single file + /// Action possible on a single file val singleFile = checkedFilesWithSyncInfo.first().file + handled = onSingleFileActionChosen(menuId, singleFile) + } - openInWebProviders.forEach { (openInWebProviderName, menuItemId) -> - if (menuItemId == menuId) { - mainFileListViewModel.openInWeb(singleFile.remoteId!!, openInWebProviderName) - return true - } + /// Actions possible on a batch of files + val checkedFiles = checkedFilesWithSyncInfo.map { it.file } as ArrayList + handled = onCheckedFilesActionChosen(menuId, checkedFiles) + return handled + } + + private fun onSingleFileActionChosen(menuId: Int?, singleFile: OCFile): Boolean { + openInWebProviders.forEach { (openInWebProviderName, menuItemId) -> + if (menuItemId == menuId) { + mainFileListViewModel.openInWeb(singleFile.remoteId!!, openInWebProviderName) + return true } + } - when (menuId) { - R.id.action_share_file -> { - fileActions?.onShareFileClicked(singleFile) - fileListAdapter.clearSelection() - updateActionModeAfterTogglingSelected() - return true - } + when (menuId) { + R.id.action_share_file -> { + fileActions?.onShareFileClicked(singleFile) + fileListAdapter.clearSelection() + updateActionModeAfterTogglingSelected() + return true + } - R.id.action_open_file_with -> { - fileActions?.openFile(singleFile) - fileListAdapter.clearSelection() - updateActionModeAfterTogglingSelected() - return true - } + R.id.action_open_file_with -> { + fileActions?.openFile(singleFile) + fileListAdapter.clearSelection() + updateActionModeAfterTogglingSelected() + return true + } - R.id.action_rename_file -> { - val dialog = RenameFileDialogFragment.newInstance(singleFile) - dialog.show(requireActivity().supportFragmentManager, FRAGMENT_TAG_RENAME_FILE) - fileListAdapter.clearSelection() - updateActionModeAfterTogglingSelected() - return true - } + R.id.action_rename_file -> { + val dialog = RenameFileDialogFragment.newInstance(singleFile) + dialog.show(requireActivity().supportFragmentManager, FRAGMENT_TAG_RENAME_FILE) + fileListAdapter.clearSelection() + updateActionModeAfterTogglingSelected() + return true + } - R.id.action_see_details -> { - fileListAdapter.clearSelection() - updateActionModeAfterTogglingSelected() - fileActions?.showDetails(singleFile) - return true - } + R.id.action_see_details -> { + fileListAdapter.clearSelection() + updateActionModeAfterTogglingSelected() + fileActions?.showDetails(singleFile) + return true + } - R.id.action_sync_file -> { - syncFiles(listOf(singleFile)) - return true - } + R.id.action_sync_file -> { + syncFiles(listOf(singleFile)) + return true + } - R.id.action_send_file -> { - //Obtain the file - if (!singleFile.isAvailableLocally) { // Download the file - Timber.d("%s : File must be downloaded", singleFile.remotePath) - fileActions?.initDownloadForSending(singleFile) - } else { - fileActions?.sendDownloadedFile(singleFile) - } - return true + R.id.action_send_file -> { + //Obtain the file + if (!singleFile.isAvailableLocally) { // Download the file + Timber.d("%s : File must be downloaded", singleFile.remotePath) + fileActions?.initDownloadForSending(singleFile) + } else { + fileActions?.sendDownloadedFile(singleFile) } + return true + } - R.id.action_set_available_offline -> { - fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(listOf(singleFile))) - if (singleFile.isFolder) { - fileOperationsViewModel.performOperation( - FileOperation.SynchronizeFolderOperation( - folderToSync = singleFile, - accountName = singleFile.owner, - isActionSetFolderAvailableOfflineOrSynchronize = true, - ) + R.id.action_set_available_offline -> { + fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(listOf(singleFile))) + if (singleFile.isFolder) { + fileOperationsViewModel.performOperation( + FileOperation.SynchronizeFolderOperation( + folderToSync = singleFile, + accountName = singleFile.owner, + isActionSetFolderAvailableOfflineOrSynchronize = true, ) - } else { - fileOperationsViewModel.performOperation(FileOperation.SynchronizeFileOperation(singleFile, singleFile.owner)) - } - return true + ) + } else { + fileOperationsViewModel.performOperation(FileOperation.SynchronizeFileOperation(singleFile, singleFile.owner)) } + return true + } - R.id.action_unset_available_offline -> { - fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(listOf(singleFile))) - } + R.id.action_unset_available_offline -> { + fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(listOf(singleFile))) + return true } } + return false + } - /// Actions possible on a batch of files - val checkedFiles = checkedFilesWithSyncInfo.map { it.file } as ArrayList + private fun onCheckedFilesActionChosen(menuId: Int?, checkedFiles: ArrayList): Boolean { when (menuId) { R.id.file_action_select_all -> { fileListAdapter.selectAll() @@ -1304,7 +1368,6 @@ class MainFileListFragment : Fragment(), return true } } - return false } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt index a883999ac51..6a84ed1e116 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/security/SettingsSecurityFragment.kt @@ -107,7 +107,6 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.settings_security, rootKey) - screenSecurity = findPreference(SCREEN_SECURITY) prefPasscode = findPreference(PassCodeActivity.PREFERENCE_SET_PASSCODE) prefPattern = findPreference(PatternActivity.PREFERENCE_SET_PATTERN) @@ -173,9 +172,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() { screenSecurity?.removePreferenceFromScreen(prefBiometric) } else { // Disable biometric lock if Passcode or Pattern locks are disabled - if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) { - disableBiometric() - } + if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) { disableBiometric() } prefBiometric?.setOnPreferenceChangeListener { _: Preference?, newValue: Any -> val incomingValue = newValue as Boolean @@ -191,9 +188,7 @@ class SettingsSecurityFragment : PreferenceFragmentCompat() { } // Lock application - if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) { - prefLockApplication?.isEnabled = false - } + if (prefPasscode?.isChecked == false && prefPattern?.isChecked == false) { prefLockApplication?.isEnabled = false } // Lock access from document provider prefLockAccessDocumentProvider?.setOnPreferenceChangeListener { _: Preference?, newValue: Any -> diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt index a5a3d9d3011..82b46a959b0 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt @@ -167,15 +167,9 @@ class UsersAndGroupsSearchProvider : ContentProvider() { var dataUri: Uri? = null var count = 0 - val userBaseUri = Uri.Builder().scheme(CONTENT).authority( - suggestAuthority!! + DATA_USER_SUFFIX - ).build() - val groupBaseUri = Uri.Builder().scheme(CONTENT).authority( - suggestAuthority!! + DATA_GROUP_SUFFIX - ).build() - val remoteBaseUri = Uri.Builder().scheme(CONTENT).authority( - suggestAuthority!! + DATA_REMOTE_SUFFIX - ).build() + val userBaseUri = Uri.Builder().scheme(CONTENT).authority(suggestAuthority!! + DATA_USER_SUFFIX).build() + val groupBaseUri = Uri.Builder().scheme(CONTENT).authority(suggestAuthority!! + DATA_GROUP_SUFFIX).build() + val remoteBaseUri = Uri.Builder().scheme(CONTENT).authority(suggestAuthority!! + DATA_REMOTE_SUFFIX).build() val federatedShareAllowed = capabilities?.filesSharingFederationOutgoing?.isTrue ?: false @@ -184,9 +178,7 @@ class UsersAndGroupsSearchProvider : ContentProvider() { val fullName = AccountManager.get(context).getUserData(account, KEY_DISPLAY_NAME) while (namesIt.hasNext()) { item = namesIt.next() - if (item.label == userName || item.label == fullName && item.shareType == ShareType.USER) { - continue - } + if (item.label == userName || item.label == fullName && item.shareType == ShareType.USER) { continue } var userName = item.label val type = item.shareType val shareWith = item.shareWith @@ -212,15 +204,10 @@ class UsersAndGroupsSearchProvider : ContentProvider() { ShareType.FEDERATED -> { if (federatedShareAllowed) { icon = R.drawable.ic_user - displayName = if (userName == shareWith) { - context?.getString(R.string.share_remote_clarification, userName) - } else { - val uriSplitted = - shareWith.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - context?.getString( - R.string.share_known_remote_clarification, userName, - uriSplitted[uriSplitted.size - 1] - ) + displayName = if (userName == shareWith) { context?.getString(R.string.share_remote_clarification, userName) } + else { + val uriSplitted = shareWith.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + context?.getString(R.string.share_known_remote_clarification, userName, uriSplitted[uriSplitted.size - 1]) } dataUri = Uri.withAppendedPath(remoteBaseUri, shareWith) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/transfers/TransfersAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/transfers/TransfersAdapter.kt index 0c163464b0a..cd50af79117 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/transfers/TransfersAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/transfers/TransfersAdapter.kt @@ -77,137 +77,11 @@ class TransfersAdapter( when (holder) { is TransferItemViewHolder -> { val transferItem = getItem(position) as TransferItem - holder.binding.apply { - val remoteFile = File(transferItem.transfer.remotePath) - - var fileName = remoteFile.name - if (fileName.isEmpty()) { - fileName = File.separator - } - uploadName.text = fileName - - transferItem.space?.let { - spacePathLine.spaceName.isVisible = true - spacePathLine.spaceIcon.isVisible = true - if (it.isPersonal) { - spacePathLine.spaceIcon.setImageResource(R.drawable.ic_folder) - spacePathLine.spaceName.setText(R.string.bottom_nav_personal) - } else { - spacePathLine.spaceName.text = it.name - } - } - - remoteFile.parent?.let { - spacePathLine.path.text = if (it.endsWith("${OCFile.PATH_SEPARATOR}")) it else "$it${OCFile.PATH_SEPARATOR}" - } - - uploadFileSize.text = DisplayUtils.bytesToHumanReadable(transferItem.transfer.fileSize, holder.itemView.context, true) - - uploadDate.isVisible = - transferItem.transfer.transferEndTimestamp != null && transferItem.transfer.status != TransferStatus.TRANSFER_FAILED - transferItem.transfer.transferEndTimestamp?.let { - val dateString = DisplayUtils.getRelativeDateTimeString( - holder.itemView.context, - it, - DateUtils.SECOND_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) - uploadDate.text = ", $dateString" - } - - try { - val account = AccountUtils.getOwnCloudAccountByName(holder.itemView.context, transferItem.transfer.accountName) - val oca = OwnCloudAccount(account, holder.itemView.context) - val accountName = oca.displayName + " @ " + - DisplayUtils.convertIdn(account.name.substring(account.name.lastIndexOf("@") + 1), false) - uploadAccount.text = accountName - } catch (e: Exception) { - Timber.w("Couldn't get display name for account, using old style") - uploadAccount.text = transferItem.transfer.accountName - } - - uploadStatus.isVisible = transferItem.transfer.status != TransferStatus.TRANSFER_SUCCEEDED - uploadStatus.text = " — " + holder.itemView.context.getString(transferItem.transfer.statusToStringRes()) - - Glide.with(holder.itemView) - .load(transferItem.transfer.localPath) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .placeholder( - MimetypeIconUtil.getFileTypeIconId( - MimetypeIconUtil.getBestMimeTypeByFilename(transferItem.transfer.localPath), - fileName - ) - ) - .into(thumbnail) - - uploadRightButton.isVisible = transferItem.transfer.status != TransferStatus.TRANSFER_SUCCEEDED - - uploadProgressBar.isVisible = transferItem.transfer.status == TransferStatus.TRANSFER_IN_PROGRESS - - holder.itemView.setOnClickListener(null) - - when (transferItem.transfer.status) { - TransferStatus.TRANSFER_IN_PROGRESS, TransferStatus.TRANSFER_QUEUED -> { - uploadRightButton.apply { - setImageResource(R.drawable.ic_action_cancel_grey) - setOnClickListener { - cancel(transferItem.transfer) - } - } - } - TransferStatus.TRANSFER_FAILED -> { - uploadRightButton.apply { - setImageResource(R.drawable.ic_action_delete_grey) - setOnClickListener { - cancel(transferItem.transfer) - } - } - holder.itemView.setOnClickListener { - retry(transferItem.transfer) - } - holder.binding.ListItemLayout.isClickable = true - holder.binding.ListItemLayout.isFocusable = true - } - TransferStatus.TRANSFER_SUCCEEDED -> { - // Nothing to do - } - } - } + onBindTransferItemViewHolder(holder, transferItem) } is HeaderItemViewHolder -> { val headerItem = getItem(position) as HeaderItem - holder.binding.apply { - uploadListGroupName.text = holder.itemView.context.getString(headerTitleStringRes(headerItem.status)) - - val stringResFileCount = - if (headerItem.numberTransfers == 1) R.string.uploads_view_group_file_count_single else R.string.uploads_view_group_file_count - val fileCountText: String = String.format(holder.itemView.context.getString(stringResFileCount), headerItem.numberTransfers) - textViewFileCount.text = fileCountText - - uploadListGroupButtonClear.isVisible = headerItem.status == TransferStatus.TRANSFER_FAILED || - headerItem.status == TransferStatus.TRANSFER_SUCCEEDED - uploadListGroupButtonRetry.isVisible = headerItem.status == TransferStatus.TRANSFER_FAILED - - when (headerItem.status) { - TransferStatus.TRANSFER_FAILED -> { - uploadListGroupButtonClear.setOnClickListener { - clearFailed() - } - uploadListGroupButtonRetry.setOnClickListener { - retryFailed() - } - } - TransferStatus.TRANSFER_SUCCEEDED -> { - uploadListGroupButtonClear.setOnClickListener { - clearSuccessful() - } - } - TransferStatus.TRANSFER_QUEUED, TransferStatus.TRANSFER_IN_PROGRESS -> { - // Nothing to do - } - } - } + onBindHeaderItemViewHolder(holder, headerItem) } } @@ -226,6 +100,142 @@ class TransfersAdapter( } + private fun onBindTransferItemViewHolder(holder: TransferItemViewHolder, transferItem: TransferItem) { + holder.binding.apply { + val remoteFile = File(transferItem.transfer.remotePath) + + var fileName = remoteFile.name + if (fileName.isEmpty()) { + fileName = File.separator + } + uploadName.text = fileName + + transferItem.space?.let { + spacePathLine.spaceName.isVisible = true + spacePathLine.spaceIcon.isVisible = true + if (it.isPersonal) { + spacePathLine.spaceIcon.setImageResource(R.drawable.ic_folder) + spacePathLine.spaceName.setText(R.string.bottom_nav_personal) + } else { + spacePathLine.spaceName.text = it.name + } + } + + remoteFile.parent?.let { + spacePathLine.path.text = if (it.endsWith("${OCFile.PATH_SEPARATOR}")) it else "$it${OCFile.PATH_SEPARATOR}" + } + + uploadFileSize.text = DisplayUtils.bytesToHumanReadable(transferItem.transfer.fileSize, holder.itemView.context, true) + + uploadDate.isVisible = + transferItem.transfer.transferEndTimestamp != null && transferItem.transfer.status != TransferStatus.TRANSFER_FAILED + transferItem.transfer.transferEndTimestamp?.let { + val dateString = DisplayUtils.getRelativeDateTimeString( + holder.itemView.context, + it, + DateUtils.SECOND_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + uploadDate.text = ", $dateString" + } + + try { + val account = AccountUtils.getOwnCloudAccountByName(holder.itemView.context, transferItem.transfer.accountName) + val oca = OwnCloudAccount(account, holder.itemView.context) + val accountName = oca.displayName + " @ " + + DisplayUtils.convertIdn(account.name.substring(account.name.lastIndexOf("@") + 1), false) + uploadAccount.text = accountName + } catch (e: Exception) { + Timber.w("Couldn't get display name for account, using old style") + uploadAccount.text = transferItem.transfer.accountName + } + + uploadStatus.isVisible = transferItem.transfer.status != TransferStatus.TRANSFER_SUCCEEDED + uploadStatus.text = " — " + holder.itemView.context.getString(transferItem.transfer.statusToStringRes()) + + Glide.with(holder.itemView) + .load(transferItem.transfer.localPath) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .placeholder( + MimetypeIconUtil.getFileTypeIconId( + MimetypeIconUtil.getBestMimeTypeByFilename(transferItem.transfer.localPath), + fileName + ) + ) + .into(thumbnail) + + uploadRightButton.isVisible = transferItem.transfer.status != TransferStatus.TRANSFER_SUCCEEDED + + uploadProgressBar.isVisible = transferItem.transfer.status == TransferStatus.TRANSFER_IN_PROGRESS + + holder.itemView.setOnClickListener(null) + + when (transferItem.transfer.status) { + TransferStatus.TRANSFER_IN_PROGRESS, TransferStatus.TRANSFER_QUEUED -> { + uploadRightButton.apply { + setImageResource(R.drawable.ic_action_cancel_grey) + setOnClickListener { + cancel(transferItem.transfer) + } + } + } + + TransferStatus.TRANSFER_FAILED -> { + uploadRightButton.apply { + setImageResource(R.drawable.ic_action_delete_grey) + setOnClickListener { + cancel(transferItem.transfer) + } + } + holder.itemView.setOnClickListener { + retry(transferItem.transfer) + } + holder.binding.ListItemLayout.isClickable = true + holder.binding.ListItemLayout.isFocusable = true + } + + TransferStatus.TRANSFER_SUCCEEDED -> { + // Nothing to do + } + } + } + } + + private fun onBindHeaderItemViewHolder(holder: HeaderItemViewHolder, headerItem: HeaderItem) { + holder.binding.apply { + uploadListGroupName.text = holder.itemView.context.getString(headerTitleStringRes(headerItem.status)) + + val stringResFileCount = + if (headerItem.numberTransfers == 1) R.string.uploads_view_group_file_count_single else R.string.uploads_view_group_file_count + val fileCountText: String = String.format(holder.itemView.context.getString(stringResFileCount), headerItem.numberTransfers) + textViewFileCount.text = fileCountText + + uploadListGroupButtonClear.isVisible = headerItem.status == TransferStatus.TRANSFER_FAILED || + headerItem.status == TransferStatus.TRANSFER_SUCCEEDED + uploadListGroupButtonRetry.isVisible = headerItem.status == TransferStatus.TRANSFER_FAILED + + when (headerItem.status) { + TransferStatus.TRANSFER_FAILED -> { + uploadListGroupButtonClear.setOnClickListener { + clearFailed() + } + uploadListGroupButtonRetry.setOnClickListener { + retryFailed() + } + } + TransferStatus.TRANSFER_SUCCEEDED -> { + uploadListGroupButtonClear.setOnClickListener { + clearSuccessful() + } + } + TransferStatus.TRANSFER_QUEUED, TransferStatus.TRANSFER_IN_PROGRESS -> { + // Nothing to do + } + } + } + } + private fun headerTitleStringRes(status: TransferStatus): Int { return when (status) { TransferStatus.TRANSFER_IN_PROGRESS -> R.string.uploads_view_group_current_uploads diff --git a/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt index f00709fa4f8..db8409ebdba 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt @@ -482,6 +482,7 @@ class FileContentProvider(val executors: Executors = Executors()) : ContentProvi createCameraUploadsSyncTable(db) } + @Suppress("LongMethod") override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { Timber.i("SQL : Entering in onUpgrade") var upgraded = false diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt index b7a4a285177..0cc7ef9a8d7 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt @@ -57,6 +57,7 @@ import com.google.android.material.navigation.NavigationView import com.owncloud.android.R import com.owncloud.android.domain.capabilities.model.OCCapability import com.owncloud.android.domain.files.model.FileListOption +import com.owncloud.android.domain.user.model.UserQuota import com.owncloud.android.domain.user.model.UserQuotaState import com.owncloud.android.domain.utils.Event import com.owncloud.android.extensions.goToUrl @@ -311,106 +312,7 @@ abstract class DrawerActivity : ToolbarActivity() { when (val uiResult = event.peekContent()) { is UIResult.Success -> { uiResult.data?.let { userQuota -> - when { - userQuota.available == -4L -> { // Light users (oCIS) - getAccountQuotaText()?.text = getString(R.string.drawer_unavailable_used_storage) - getAccountQuotaBar()?.isVisible = false - getAccountQuotaStatusText()?.isVisible = false - } - - userQuota.available < 0 -> { // Pending, unknown or unlimited free storage - getAccountQuotaBar()?.apply { - isVisible = true - progress = 0 - progressTintList = ColorStateList.valueOf(resources.getColor(R.color.color_accent)) - } - getAccountQuotaText()?.text = String.format( - getString(R.string.drawer_unavailable_free_storage), - DisplayUtils.bytesToHumanReadable(userQuota.used, this, true) - ) - getAccountQuotaStatusText()?.visibility = View.GONE - } - - userQuota.available == 0L -> { // Exceeded storage. The value is over 100%. - getAccountQuotaBar()?.apply { - isVisible = true - progress = 100 - progressTintList = ColorStateList.valueOf(resources.getColor(R.color.quota_exceeded)) - } - - if (userQuota.state == UserQuotaState.EXCEEDED) { // oCIS - getAccountQuotaText()?.apply { - text = String.format( - getString(R.string.drawer_quota), - DisplayUtils.bytesToHumanReadable(userQuota.used, context, true), - DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), context, true), - userQuota.getRelative() - ) - } - getAccountQuotaStatusText()?.apply { - visibility = View.VISIBLE - text = getString(R.string.drawer_exceeded_quota) - } - } else { // oC10 - getAccountQuotaText()?.text = getString(R.string.drawer_exceeded_quota) - getAccountQuotaStatusText()?.visibility = View.GONE - } - } - - else -> { // Limited storage. Value under 100% - if (userQuota.state == UserQuotaState.NEARING) { // Nearing storage. Value between 75% and 90% - getAccountQuotaBar()?.apply { - isVisible = true - progress = userQuota.getRelative().toInt() - progressTintList = ColorStateList.valueOf(resources.getColor(R.color.color_accent)) - } - getAccountQuotaText()?.apply { - text = String.format( - getString(R.string.drawer_quota), - DisplayUtils.bytesToHumanReadable(userQuota.used, context, true), - DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), context, true), - userQuota.getRelative() - ) - } - getAccountQuotaStatusText()?.apply { - visibility = View.VISIBLE - text = getString(R.string.drawer_nearing_quota) - } - } else if (userQuota.state == UserQuotaState.CRITICAL || - userQuota.state == UserQuotaState.EXCEEDED) { // Critical storage. Value over 90% - getAccountQuotaBar()?.apply { - isVisible = true - progress = userQuota.getRelative().toInt() - progressTintList = ColorStateList.valueOf(resources.getColor(R.color.quota_exceeded)) - } - getAccountQuotaText()?.apply { - text = String.format( - getString(R.string.drawer_quota), - DisplayUtils.bytesToHumanReadable(userQuota.used, context, true), - DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), context, true), - userQuota.getRelative() - ) - } - getAccountQuotaStatusText()?.apply { - visibility = View.VISIBLE - text = getString(R.string.drawer_critical_quota) - } - } else { // Normal storage. Value under 75% - getAccountQuotaBar()?.apply { - progress = userQuota.getRelative().toInt() - isVisible = true - progressTintList = ColorStateList.valueOf(resources.getColor(R.color.color_accent)) - } - getAccountQuotaText()?.text = String.format( - getString(R.string.drawer_quota), - DisplayUtils.bytesToHumanReadable(userQuota.used, this, true), - DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), this, true), - userQuota.getRelative() - ) - getAccountQuotaStatusText()?.visibility = View.GONE - } - } - } + onUpdateQuotaIsSuccessful(userQuota) } } is UIResult.Loading -> getAccountQuotaText()?.text = getString(R.string.drawer_loading_quota) @@ -419,6 +321,106 @@ abstract class DrawerActivity : ToolbarActivity() { } } + private fun onUpdateQuotaIsSuccessful(userQuota: UserQuota) { + when { + userQuota.available == -4L -> { // Light users (oCIS) + getAccountQuotaText()?.text = getString(R.string.drawer_unavailable_used_storage) + getAccountQuotaBar()?.isVisible = false + getAccountQuotaStatusText()?.isVisible = false + } + userQuota.available < 0 -> { // Pending, unknown or unlimited free storage + getAccountQuotaBar()?.apply { + isVisible = true + progress = 0 + progressTintList = ColorStateList.valueOf(resources.getColor(R.color.color_accent)) + } + getAccountQuotaText()?.text = String.format( + getString(R.string.drawer_unavailable_free_storage), + DisplayUtils.bytesToHumanReadable(userQuota.used, this, true) + ) + getAccountQuotaStatusText()?.visibility = View.GONE + } + userQuota.available == 0L -> { // Exceeded storage. The value is over 100%. + getAccountQuotaBar()?.apply { + isVisible = true + progress = 100 + progressTintList = ColorStateList.valueOf(resources.getColor(R.color.quota_exceeded)) + } + + if (userQuota.state == UserQuotaState.EXCEEDED) { // oCIS + getAccountQuotaText()?.apply { + text = String.format( + getString(R.string.drawer_quota), + DisplayUtils.bytesToHumanReadable(userQuota.used, context, true), + DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), context, true), + userQuota.getRelative() + ) + } + getAccountQuotaStatusText()?.apply { + visibility = View.VISIBLE + text = getString(R.string.drawer_exceeded_quota) + } + } else { // oC10 + getAccountQuotaText()?.text = getString(R.string.drawer_exceeded_quota) + getAccountQuotaStatusText()?.visibility = View.GONE + } + } + else -> { // Limited storage. Value under 100% + if (userQuota.state == UserQuotaState.NEARING) { // Nearing storage. Value between 75% and 90% + getAccountQuotaBar()?.apply { + isVisible = true + progress = userQuota.getRelative().toInt() + progressTintList = ColorStateList.valueOf(resources.getColor(R.color.color_accent)) + } + getAccountQuotaText()?.apply { + text = String.format( + getString(R.string.drawer_quota), + DisplayUtils.bytesToHumanReadable(userQuota.used, context, true), + DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), context, true), + userQuota.getRelative() + ) + } + getAccountQuotaStatusText()?.apply { + visibility = View.VISIBLE + text = getString(R.string.drawer_nearing_quota) + } + } else if (userQuota.state == UserQuotaState.CRITICAL || + userQuota.state == UserQuotaState.EXCEEDED) { // Critical storage. Value over 90% + getAccountQuotaBar()?.apply { + isVisible = true + progress = userQuota.getRelative().toInt() + progressTintList = ColorStateList.valueOf(resources.getColor(R.color.quota_exceeded)) + } + getAccountQuotaText()?.apply { + text = String.format( + getString(R.string.drawer_quota), + DisplayUtils.bytesToHumanReadable(userQuota.used, context, true), + DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), context, true), + userQuota.getRelative() + ) + } + getAccountQuotaStatusText()?.apply { + visibility = View.VISIBLE + text = getString(R.string.drawer_critical_quota) + } + } else { // Normal storage. Value under 75% + getAccountQuotaBar()?.apply { + progress = userQuota.getRelative().toInt() + isVisible = true + progressTintList = ColorStateList.valueOf(resources.getColor(R.color.color_accent)) + } + getAccountQuotaText()?.text = String.format( + getString(R.string.drawer_quota), + DisplayUtils.bytesToHumanReadable(userQuota.used, this, true), + DisplayUtils.bytesToHumanReadable(userQuota.getTotal(), this, true), + userQuota.getRelative() + ) + getAccountQuotaStatusText()?.visibility = View.GONE + } + } + } + } + override fun setupRootToolbar(title: String, isSearchEnabled: Boolean, isAvatarRequested: Boolean) { super.setupRootToolbar( title = title, From f0076ff49a9d8075fcb504553410e44a94ec776d Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 11 Dec 2024 14:30:44 +0100 Subject: [PATCH 17/31] refactor: fix for KtLint report --- .../implementation/OCLocalFileDataSourceTest.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt index 5c36eef73ff..45d50196eb3 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/files/datasources/implementation/OCLocalFileDataSourceTest.kt @@ -436,16 +436,16 @@ class OCLocalFileDataSourceTest { } @Test - fun `getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow returns a Flow with an empty list when DAO returns a Flow with an empty list`() - = runTest { - every { fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) } returns flowOf(emptyList()) + fun `getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow returns a Flow with an empty list when DAO returns a Flow with an empty list`() = + runTest { + every { fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) } returns flowOf(emptyList()) - val result = ocLocalFileDataSource.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME).first() + val result = ocLocalFileDataSource.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME).first() - assertEquals(emptyList(), result) + assertEquals(emptyList(), result) - verify(exactly = 1) { fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) } - } + verify(exactly = 1) { fileDao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(OC_ACCOUNT_NAME) } + } @Test fun `getFilesAvailableOfflineFromAccount returns a list of OCFile`() { From ff60f031d5b9c897d8d188fca73ad2dc9a7b8328 Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 14:44:31 +0100 Subject: [PATCH 18/31] refactor: remove unused private members --- .../renamefile/RenameFileDialogFragment.kt | 12 --------- .../sharees/UsersAndGroupsSearchProvider.kt | 4 +-- .../android/workers/DownloadFileWorker.kt | 25 ------------------- 3 files changed, 2 insertions(+), 39 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/renamefile/RenameFileDialogFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/renamefile/RenameFileDialogFragment.kt index 1a284c06b94..b8ff0d8a7f9 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/renamefile/RenameFileDialogFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/renamefile/RenameFileDialogFragment.kt @@ -34,7 +34,6 @@ import com.google.android.material.textfield.TextInputLayout import com.owncloud.android.R import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.extensions.avoidScreenshotsIfNeeded -import com.owncloud.android.extensions.showMessageInSnackbar import com.owncloud.android.presentation.files.operations.FileOperation import com.owncloud.android.presentation.files.operations.FileOperationsViewModel import com.owncloud.android.utils.PreferenceUtils @@ -141,17 +140,6 @@ class RenameFileDialogFragment : DialogFragment(), DialogInterface.OnClickListen } } - /** - * Show a temporary message in a Snackbar bound to the content view of the parent Activity - * - * @param messageResource Message to show. - */ - private fun showSnackMessage(messageResource: Int) { - showMessageInSnackbar( - message = getString(messageResource) - ) - } - companion object { const val FRAGMENT_TAG_RENAME_FILE = "RENAME_FILE_FRAGMENT" private const val ARG_TARGET_FILE = "TARGET_FILE" diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt index 82b46a959b0..08bae7336e4 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt @@ -204,8 +204,8 @@ class UsersAndGroupsSearchProvider : ContentProvider() { ShareType.FEDERATED -> { if (federatedShareAllowed) { icon = R.drawable.ic_user - displayName = if (userName == shareWith) { context?.getString(R.string.share_remote_clarification, userName) } - else { + displayName = if (userName == shareWith) { context?.getString(R.string.share_remote_clarification, userName) + } else { val uriSplitted = shareWith.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() context?.getString(R.string.share_known_remote_clarification, userName, uriSplitted[uriSplitted.size - 1]) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/DownloadFileWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/DownloadFileWorker.kt index b8fdb94208d..e6ac9b0497f 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/DownloadFileWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/DownloadFileWorker.kt @@ -53,11 +53,7 @@ import com.owncloud.android.presentation.authentication.EXTRA_ACCOUNT import com.owncloud.android.presentation.authentication.EXTRA_ACTION import com.owncloud.android.presentation.authentication.LoginActivity import com.owncloud.android.presentation.transfers.TransferOperation.Download -import com.owncloud.android.ui.activity.FileActivity -import com.owncloud.android.ui.activity.FileDisplayActivity import com.owncloud.android.ui.errorhandling.ErrorMessageAdapter -import com.owncloud.android.ui.preview.PreviewImageActivity -import com.owncloud.android.ui.preview.PreviewImageFragment.Companion.canBePreviewed import com.owncloud.android.utils.DOWNLOAD_NOTIFICATION_CHANNEL_ID import com.owncloud.android.utils.DOWNLOAD_NOTIFICATION_ID_DEFAULT import com.owncloud.android.utils.FileStorageUtils @@ -309,27 +305,6 @@ class DownloadFileWorker( ) } - private fun composePendingIntentToPreviewFile(): PendingIntent { - /// includes a pending intent in the notification showing the details view of the file - val showDetailsIntent: Intent = - if (canBePreviewed(ocFile)) { - Intent(appContext, PreviewImageActivity::class.java) - } else { - Intent(appContext, FileDisplayActivity::class.java) - }.apply { - putExtra(FileActivity.EXTRA_FILE, ocFile) - putExtra(FileActivity.EXTRA_ACCOUNT, account) - flags = Intent.FLAG_ACTIVITY_CLEAR_TOP - } - - return PendingIntent.getActivity( - appContext, - System.currentTimeMillis().toInt(), - showDetailsIntent, - PendingIntent.FLAG_IMMUTABLE - ) - } - private fun getClientForThisDownload(): OwnCloudClient = SingleSessionManager.getDefaultSingleton() .getClientFor(OwnCloudAccount(AccountUtils.getOwnCloudAccountByName(appContext, account.name), appContext), appContext) From c62ebdf6856b1977b7401db40b1c44d7212096b0 Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 16:54:04 +0100 Subject: [PATCH 19/31] refactor: remove unused private properties in module `owncloudApp` --- .../presentation/files/filelist/MainFileListFragment.kt | 1 - .../presentation/sharing/PublicLinkPasswordUtils.kt | 8 ++++---- .../sharing/sharees/UsersAndGroupsSearchProvider.kt | 1 - .../com/owncloud/android/ui/activity/DrawerActivity.kt | 1 - .../owncloud/android/ui/activity/FileDisplayActivity.kt | 1 - .../presentation/sharing/PublicLinkPasswordUtilsTest.kt | 2 +- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt index 5883200360b..aaede7286fe 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt @@ -1611,7 +1611,6 @@ class MainFileListFragment : Fragment(), private const val DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER" private const val DIALOG_CREATE_SHORTCUT = "DIALOG_CREATE_SHORTCUT" - private const val TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT" private const val FILE_DOCXF_EXTENSION = "docxf" @JvmStatic diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt index b64730ba364..2890587b927 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt @@ -53,22 +53,22 @@ fun generatePassword( val passwordChars = mutableListOf() // Include the minimum number of digits established by the policy - for (i in 1..minDigits) { + repeat (minDigits) { passwordChars.add(charsetDigits[secureRandom.nextInt(charsetDigits.size)]) } // Include the minimum number of lowercase chars established by the policy - for (i in 1..minLowercaseCharacters) { + repeat (minLowercaseCharacters) { passwordChars.add(charsetLowercase[secureRandom.nextInt(charsetLowercase.size)]) } // Include the minimum number of uppercase chars established by the policy - for (i in 1..minUppercaseCharacters) { + repeat (minUppercaseCharacters) { passwordChars.add(charsetUppercase[secureRandom.nextInt(charsetUppercase.size)]) } // Include the minimum number of special chars established by the policy - for (i in 1..minSpecialCharacters) { + repeat (minSpecialCharacters) { passwordChars.add(charsetSpecial[secureRandom.nextInt(charsetSpecial.size)]) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt index 08bae7336e4..b7b7e6b4b8c 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt @@ -283,7 +283,6 @@ class UsersAndGroupsSearchProvider : ContentProvider() { private const val SEARCH = 1 - private const val DEFAULT_MIN_CHARACTERS_TO_SEARCH = 4 private const val RESULTS_PER_PAGE = 30 private const val REQUESTED_PAGE = 1 diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt index 0cc7ef9a8d7..3fd03b8d7f7 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.kt @@ -612,7 +612,6 @@ abstract class DrawerActivity : ToolbarActivity() { const val TALK_MOBILE_URL = "https://talk.owncloud.com/channel/mobile" const val GITHUB_URL = "https://github.com/owncloud/android/issues/new/choose" const val SURVEY_URL = "https://owncloud.com/android-app-feedback" - private const val KEY_IS_ACCOUNT_CHOOSER_ACTIVE = "IS_ACCOUNT_CHOOSER_ACTIVE" private const val KEY_CHECKED_MENU_ITEM = "CHECKED_MENU_ITEM" } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 444f7dbc406..e03c8f4f96e 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -2033,7 +2033,6 @@ class FileDisplayActivity : FileActivity(), private const val KEY_WAITING_TO_SEND = "WAITING_TO_SEND" private const val KEY_UPLOAD_HELPER = "FILE_UPLOAD_HELPER" private const val KEY_FILE_LIST_OPTION = "FILE_LIST_OPTION" - private const val MAX_URL_LENGTH = 90 const val MIMETYPE_TEXT_URI_LIST = "text/uri-list" const val KEY_DEEP_LINK_ACCOUNTS_CHECKED = "DEEP_LINK_ACCOUNTS_CHECKED" diff --git a/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt b/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt index c4a2471b72f..ec2d88def49 100644 --- a/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt +++ b/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt @@ -40,7 +40,7 @@ class PublicLinkPasswordUtilsTest { @Test fun `generatePassword creates password fulfilling all policies`() { - for (i in 1..1000) { + repeat (1000) { val password = generatePassword( minChars = minCharacters, maxChars = maxCharacters, From a0b2e15c19aa3c3f85950c51d3eb6f306be0b8ce Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 16:55:38 +0100 Subject: [PATCH 20/31] refactor: remove unused private properties in module `owncloudComLibrary` --- .../lib/resources/webfinger/responses/WebFingerResponseTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt index 4b275cd73b7..7b14da998ee 100644 --- a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt +++ b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt @@ -41,9 +41,7 @@ class WebFingerResponseTest { companion object { private const val RESOURCES_PATH = "src/test/responses/com.owncloud.android.lib.resources.webfinger.responses" - private const val EXAMPLE_RESPONSE_JSON = "$RESOURCES_PATH/simple_response.json" private const val TOO_MUCH_INFORMATION_JSON = "$RESOURCES_PATH/to_much_information_response.json" private const val BROKEN_JSON = "$RESOURCES_PATH/broken_response.json" - private const val NOT_CONTAINING_RELEVANT_INFORMATION_JSON = "$RESOURCES_PATH/not_containing_relevant_info_response.json" } } From f5a2801ab611b946ca7a2f4ec90b7c629123c407 Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 17:44:07 +0100 Subject: [PATCH 21/31] refactor: replace when by if for binary conditions in module `owncloudApp` --- .../android/extensions/ThrowableExt.kt | 9 +++--- .../authentication/LoginActivity.kt | 26 ++++++++--------- .../android/presentation/common/UIResult.kt | 7 +++-- .../presentation/security/SecurityEnforced.kt | 7 +++-- .../security/passcode/PassCodeActivity.kt | 7 +++-- .../privacypolicy/PrivacyPolicyActivity.kt | 7 +++-- .../presentation/sharing/ShareActivity.kt | 20 ++++++------- .../sharees/UsersAndGroupsSearchProvider.kt | 7 +++-- .../ui/activity/FileDisplayActivity.kt | 13 ++++----- .../PreviewFormatTextFragmentStateAdapter.kt | 7 +++-- .../ui/preview/PreviewImageActivity.kt | 28 +++++++++---------- 11 files changed, 69 insertions(+), 69 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/ThrowableExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/ThrowableExt.kt index 5dd0282e5f6..c2feb639f63 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/extensions/ThrowableExt.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/ThrowableExt.kt @@ -106,11 +106,10 @@ fun Throwable.parseError( else -> resources.getString(R.string.common_error_unknown) } - return when { - showJustReason -> { - reason - } - else -> "$genericErrorMessage ${resources.getString(R.string.error_reason)} ${reason.lowercase(Locale.getDefault())}" + return if (showJustReason) { + reason + } else { + "$genericErrorMessage ${resources.getString(R.string.error_reason)} ${reason.lowercase(Locale.getDefault())}" } } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt index 81889dac1c7..0c6cd7850cd 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/authentication/LoginActivity.kt @@ -298,13 +298,13 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted } private fun getLegacyWebfingerIsError(uiResult: UIResult.Error) { - when (uiResult.error) { - is NoNetworkConnectionException -> binding.webfingerStatusText.run { + if (uiResult.error is NoNetworkConnectionException) { + binding.webfingerStatusText.run { text = getString(R.string.error_no_network_connection) setCompoundDrawablesWithIntrinsicBounds(R.drawable.no_network, 0, 0, 0) } - - else -> binding.webfingerStatusText.run { + } else { + binding.webfingerStatusText.run { text = uiResult.getThrowableOrNull()?.parseError("", resources, true) setCompoundDrawablesWithIntrinsicBounds(R.drawable.common_error, 0, 0, 0) } @@ -616,17 +616,15 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted var clientId: String? = null var clientSecret: String? = null - when (val serverInfo = authenticationViewModel.serverInfo.value?.peekContent()?.getStoredData()) { - is ServerInfo.OIDCServer -> { - tokenEndPoint = serverInfo.oidcServerConfiguration.tokenEndpoint - if (serverInfo.oidcServerConfiguration.isTokenEndpointAuthMethodSupportedClientSecretPost()) { - clientId = clientRegistrationInfo?.clientId ?: contextProvider.getString(R.string.oauth2_client_id) - clientSecret = clientRegistrationInfo?.clientSecret ?: contextProvider.getString(R.string.oauth2_client_secret) - } - } - else -> { - tokenEndPoint = "$serverBaseUrl${File.separator}${contextProvider.getString(R.string.oauth2_url_endpoint_access)}" + val serverInfo = authenticationViewModel.serverInfo.value?.peekContent()?.getStoredData() + if (serverInfo is ServerInfo.OIDCServer) { + tokenEndPoint = serverInfo.oidcServerConfiguration.tokenEndpoint + if (serverInfo.oidcServerConfiguration.isTokenEndpointAuthMethodSupportedClientSecretPost()) { + clientId = clientRegistrationInfo?.clientId ?: contextProvider.getString(R.string.oauth2_client_id) + clientSecret = clientRegistrationInfo?.clientSecret ?: contextProvider.getString(R.string.oauth2_client_secret) } + } else { + tokenEndPoint = "$serverBaseUrl${File.separator}${contextProvider.getString(R.string.oauth2_url_endpoint_access)}" } val scope = resources.getString(R.string.oauth2_openid_scope) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/common/UIResult.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/common/UIResult.kt index 8e8c8f19774..c94df13a9ed 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/common/UIResult.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/common/UIResult.kt @@ -37,9 +37,10 @@ sealed class UIResult { } fun getThrowableOrNull(): Throwable? = - when (this) { - is Error -> error - else -> null + if (this is Error) { + error + } else { + null } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/security/SecurityEnforced.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/security/SecurityEnforced.kt index b8af17c0159..5561888737a 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/security/SecurityEnforced.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/security/SecurityEnforced.kt @@ -29,9 +29,10 @@ enum class LockType { companion object { fun parseFromInteger(value: Int): LockType { - return when (value) { - 0 -> PASSCODE - else -> PATTERN + return if (value == 0) { + PASSCODE + } else { + PATTERN } } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/security/passcode/PassCodeActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/security/passcode/PassCodeActivity.kt index 5dcda2ba161..ea1e6589dd7 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/security/passcode/PassCodeActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/security/passcode/PassCodeActivity.kt @@ -215,9 +215,10 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom } PasscodeAction.REMOVE -> { - when (status.type) { - PasscodeType.OK -> actionRemoveOk() - else -> actionRemoveError() + if (status.type == PasscodeType.OK) { + actionRemoveOk() + } else { + actionRemoveError() } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/privacypolicy/PrivacyPolicyActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/privacypolicy/PrivacyPolicyActivity.kt index 509f9b192f6..fc74f139ddd 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/privacypolicy/PrivacyPolicyActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/settings/privacypolicy/PrivacyPolicyActivity.kt @@ -91,9 +91,10 @@ class PrivacyPolicyActivity : AppCompatActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { var retval = true - when (item.itemId) { - android.R.id.home -> finish() - else -> retval = super.onOptionsItemSelected(item) + if (item.itemId == android.R.id.home) { + finish() + } else { + retval = super.onOptionsItemSelected(item) } return retval } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt index 530ba94b22f..9d009b33bc8 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt @@ -294,11 +294,12 @@ class ShareActivity : FileActivity(), ShareFragmentListener { override fun onOptionsItemSelected(item: MenuItem): Boolean { var retval = true - when (item.itemId) { - android.R.id.home -> if (!supportFragmentManager.popBackStackImmediate()) { + if (item.itemId == android.R.id.home) { + if (!supportFragmentManager.popBackStackImmediate()) { finish() } - else -> retval = super.onOptionsItemSelected(item) + } else { + retval = super.onOptionsItemSelected(item) } return retval } @@ -317,14 +318,13 @@ class ShareActivity : FileActivity(), ShareFragmentListener { } override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { - return when (keyCode) { - KeyEvent.KEYCODE_DPAD_DOWN -> { - if (findViewById(R.id.owncloud_app_bar).hasFocus()) { - findViewById(R.id.share_fragment_container).requestFocus() - } - true + return if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + if (findViewById(R.id.owncloud_app_bar).hasFocus()) { + findViewById(R.id.share_fragment_container).requestFocus() } - else -> super.onKeyUp(keyCode, event) + true + } else { + super.onKeyUp(keyCode, event) } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt index b7b7e6b4b8c..014e393771d 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/sharees/UsersAndGroupsSearchProvider.kt @@ -112,9 +112,10 @@ class UsersAndGroupsSearchProvider : ContentProvider() { sortOrder: String? ): Cursor? { Timber.d("query received in thread ${Thread.currentThread().name}") - return when (uriMatcher.match(uri)) { - SEARCH -> searchForUsersOrGroups(uri) - else -> null + return if (uriMatcher.match(uri) == SEARCH) { + searchForUsersOrGroups(uri) + } else { + null } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index e03c8f4f96e..04d5e259a6c 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -2012,14 +2012,13 @@ class FileDisplayActivity : FileActivity(), } override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { - return when (keyCode) { - KeyEvent.KEYCODE_DPAD_DOWN -> { - if (findViewById(R.id.owncloud_app_bar).hasFocus()) { - findViewById(R.id.left_fragment_container).requestFocus() - } - true + return if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + if (findViewById(R.id.owncloud_app_bar).hasFocus()) { + findViewById(R.id.left_fragment_container).requestFocus() } - else -> super.onKeyUp(keyCode, event) + true + } else { + super.onKeyUp(keyCode, event) } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewFormatTextFragmentStateAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewFormatTextFragmentStateAdapter.kt index 4c7f44b3fa7..27fd5f69b72 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewFormatTextFragmentStateAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewFormatTextFragmentStateAdapter.kt @@ -47,9 +47,10 @@ class PreviewFormatTextFragmentStateAdapter( override fun getItemCount(): Int = 2 override fun createFragment(position: Int): Fragment { - return when (position) { - 0 -> PreviewFormatTextFragment.newInstance(text, mimeType) - else -> PreviewFormatTextFragment.newInstance(text) + return if (position == 0) { + PreviewFormatTextFragment.newInstance(text, mimeType) + } else { + PreviewFormatTextFragment.newInstance(text) } } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt index 06fe6316acb..e8c1a7bb3ec 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt @@ -253,16 +253,15 @@ class PreviewImageActivity : FileActivity(), } override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - android.R.id.home -> { - if (isDrawerOpen()) { - closeDrawer() - } else { - backToDisplayActivity() - } - true + return if (item.itemId == android.R.id.home) { + if (isDrawerOpen()) { + closeDrawer() + } else { + backToDisplayActivity() } - else -> super.onOptionsItemSelected(item) + true + } else { + super.onOptionsItemSelected(item) } } @@ -411,12 +410,11 @@ class PreviewImageActivity : FileActivity(), } override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { - return when (keyCode) { - KeyEvent.KEYCODE_TAB -> { - showSystemUI(fullScreenAnchorView) - true - } - else -> super.onKeyUp(keyCode, event) + return if (keyCode == KeyEvent.KEYCODE_TAB) { + showSystemUI(fullScreenAnchorView) + true + } else { + super.onKeyUp(keyCode, event) } } From a8c8d780eb73a629cfb23f870c52c74d1f370bf3 Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 17:49:30 +0100 Subject: [PATCH 22/31] refactor: replace when by if for binary conditions in module `owncloudDomain` --- .../com/owncloud/android/domain/UseCaseResult.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/UseCaseResult.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/UseCaseResult.kt index 3b836ccfe17..575bc6f7b26 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/UseCaseResult.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/UseCaseResult.kt @@ -27,14 +27,16 @@ sealed class UseCaseResult { val isError get() = this is Error fun getDataOrNull(): T? = - when (this) { - is Success -> data - else -> null + if (this is Success) { + data + } else { + null } fun getThrowableOrNull(): Throwable? = - when (this) { - is Error -> throwable - else -> null + if (this is Error) { + throwable + } else { + null } } From d30be87d42f5733aa302282bc8800d0ebd816eb7 Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 18:08:14 +0100 Subject: [PATCH 23/31] refactor: replace if/else condition with a null block by let in module `owncloudApp` --- .../presentation/files/filelist/FileListAdapter.kt | 6 +----- .../android/ui/activity/FileDisplayActivity.kt | 10 ++-------- .../sharing/PublicLinkPasswordUtilsTest.kt | 2 +- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt index d84a1a6a467..b095463b895 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt @@ -188,11 +188,7 @@ class FileListAdapter( val fileIcon = holder.itemView.findViewById(R.id.thumbnail).apply { tag = file.id } - val thumbnail: Bitmap? = if (file.remoteId != null) { - ThumbnailsCacheManager.getBitmapFromDiskCache(file.remoteId) - } else { - null - } + val thumbnail: Bitmap? = file.remoteId?.let { ThumbnailsCacheManager.getBitmapFromDiskCache(file.remoteId) } holder.itemView.findViewById(R.id.ListItemLayout)?.apply { contentDescription = "LinearLayout-$name" diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 04d5e259a6c..45222e2e230 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -862,14 +862,8 @@ class FileDisplayActivity : FileActivity(), syncInProgress = true } else { - var currentFile: OCFile? = if (file == null) - null - else - storageManager.getFileByPath(file.remotePath, file.spaceId) - val currentDir = if (currentDir == null) - null - else - storageManager.getFileByPath(currentDir!!.remotePath, currentDir.spaceId) + var currentFile: OCFile? = file?.let { storageManager.getFileByPath(file.remotePath, file.spaceId) } + val currentDir = currentDir?.let { storageManager.getFileByPath(currentDir!!.remotePath, currentDir.spaceId) } if (currentDir == null) { // current folder was removed from the server diff --git a/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt b/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt index ec2d88def49..bf1ba92319d 100644 --- a/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt +++ b/owncloudApp/src/test/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtilsTest.kt @@ -40,7 +40,7 @@ class PublicLinkPasswordUtilsTest { @Test fun `generatePassword creates password fulfilling all policies`() { - repeat (1000) { + repeat(1000) { val password = generatePassword( minChars = minCharacters, maxChars = maxCharacters, From 06bfe202e54fb7890632f835970b8ff9792752fa Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 18:10:42 +0100 Subject: [PATCH 24/31] refactor: replace if/else condition with a null block by let in module `owncloudComLibrary` --- .../android/lib/common/http/logging/LogInterceptor.kt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/logging/LogInterceptor.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/logging/LogInterceptor.kt index 862846f521f..ecce97d7ea7 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/logging/LogInterceptor.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/logging/LogInterceptor.kt @@ -136,14 +136,7 @@ class LogInterceptor : Interceptor { LogResponse( Response( headers = logHeaders(response.headers), - body = if (responseBody == null) { - null - } else { - Body( - data = responseBody, - length = bodyLength, - ) - }, + body = responseBody?.let { Body(data = responseBody, length = bodyLength) }, info = ResponseInfo( id = requestId, method = request.method, From 6ac1cd76b69e3901303e1e88cab7e851dbc4d848 Mon Sep 17 00:00:00 2001 From: joragua Date: Wed, 11 Dec 2024 18:16:14 +0100 Subject: [PATCH 25/31] refactor: fix for KtLint report --- .../presentation/sharing/PublicLinkPasswordUtils.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt index 2890587b927..c71ab1ab24e 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/PublicLinkPasswordUtils.kt @@ -53,22 +53,22 @@ fun generatePassword( val passwordChars = mutableListOf() // Include the minimum number of digits established by the policy - repeat (minDigits) { + repeat(minDigits) { passwordChars.add(charsetDigits[secureRandom.nextInt(charsetDigits.size)]) } // Include the minimum number of lowercase chars established by the policy - repeat (minLowercaseCharacters) { + repeat(minLowercaseCharacters) { passwordChars.add(charsetLowercase[secureRandom.nextInt(charsetLowercase.size)]) } // Include the minimum number of uppercase chars established by the policy - repeat (minUppercaseCharacters) { + repeat(minUppercaseCharacters) { passwordChars.add(charsetUppercase[secureRandom.nextInt(charsetUppercase.size)]) } // Include the minimum number of special chars established by the policy - repeat (minSpecialCharacters) { + repeat(minSpecialCharacters) { passwordChars.add(charsetSpecial[secureRandom.nextInt(charsetSpecial.size)]) } From b88d32079a8eb8b8ebc326281c60ee15af16e05a Mon Sep 17 00:00:00 2001 From: joragua Date: Thu, 12 Dec 2024 09:30:55 +0100 Subject: [PATCH 26/31] refactor: remove unnecessary spaces between packages and imports --- .../android/presentation/files/filelist/MainEmptyListFragment.kt | 1 - .../owncloud/android/presentation/spaces/SpacesListViewModel.kt | 1 - .../android/lib/resources/status/services/ServerInfoService.kt | 1 - 3 files changed, 3 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainEmptyListFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainEmptyListFragment.kt index 01a3595105a..237c363fa4f 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainEmptyListFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainEmptyListFragment.kt @@ -29,7 +29,6 @@ import android.widget.TextView import com.owncloud.android.R import com.owncloud.android.databinding.MainEmptyListFragmentBinding - class MainEmptyListFragment : Fragment() { private var _binding: MainEmptyListFragmentBinding? = null diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/SpacesListViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/SpacesListViewModel.kt index 5207e16617b..8f78b4945bf 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/SpacesListViewModel.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/SpacesListViewModel.kt @@ -21,7 +21,6 @@ package com.owncloud.android.presentation.spaces - import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.owncloud.android.domain.UseCaseResult diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt index b1eb2871e39..e960f62cd06 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt @@ -23,7 +23,6 @@ */ package com.owncloud.android.lib.resources.status.services - import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.resources.status.RemoteServerInfo From 0fd43f16808157aed53015c7d18aef4223d8dc6a Mon Sep 17 00:00:00 2001 From: joragua Date: Thu, 12 Dec 2024 09:50:30 +0100 Subject: [PATCH 27/31] refactor: remove explicit `it` in lambda functions --- .../owncloud/android/data/capabilities/db/OCCapabilityEntity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudData/src/main/java/com/owncloud/android/data/capabilities/db/OCCapabilityEntity.kt b/owncloudData/src/main/java/com/owncloud/android/data/capabilities/db/OCCapabilityEntity.kt index 5eca4788088..d44bf2324de 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/capabilities/db/OCCapabilityEntity.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/capabilities/db/OCCapabilityEntity.kt @@ -132,7 +132,7 @@ data class OCCapabilityEntity( @PrimaryKey(autoGenerate = true) var id: Int = 0 companion object { - fun fromCursor(cursor: Cursor): OCCapabilityEntity = cursor.use { it -> + fun fromCursor(cursor: Cursor): OCCapabilityEntity = cursor.use { OCCapabilityEntity( it.getString(it.getColumnIndexOrThrow(CAPABILITIES_ACCOUNT_NAME)), it.getInt(it.getColumnIndexOrThrow(CAPABILITIES_VERSION_MAJOR)), From 52e462a97ba24c82b67e1dfedf6bd2a1f80b3973 Mon Sep 17 00:00:00 2001 From: joragua Date: Thu, 12 Dec 2024 10:49:19 +0100 Subject: [PATCH 28/31] refactor: collapse if statements --- .../files/filelist/FileListAdapter.kt | 16 ++++++-------- .../files/filelist/MainFileListFragment.kt | 22 +++++++++---------- .../workers/UploadFileFromContentUriWorker.kt | 6 ++--- .../lib/common/utils/OCFileLoggingTree.kt | 5 ++--- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt index b095463b895..00f668f74fc 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/FileListAdapter.kt @@ -243,18 +243,16 @@ class FileListAdapter( if (thumbnail != null) { fileIcon.setImageBitmap(thumbnail) } - if (file.needsToUpdateThumbnail) { + if (file.needsToUpdateThumbnail && ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, fileIcon)) { // generate new Thumbnail - if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, fileIcon)) { - val task = ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon, account) - val asyncDrawable = ThumbnailsCacheManager.AsyncThumbnailDrawable(context.resources, thumbnail, task) + val task = ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon, account) + val asyncDrawable = ThumbnailsCacheManager.AsyncThumbnailDrawable(context.resources, thumbnail, task) - // If drawable is not visible, do not update it. - if (asyncDrawable.minimumHeight > 0 && asyncDrawable.minimumWidth > 0) { - fileIcon.setImageDrawable(asyncDrawable) - } - task.execute(file) + // If drawable is not visible, do not update it. + if (asyncDrawable.minimumHeight > 0 && asyncDrawable.minimumWidth > 0) { + fileIcon.setImageDrawable(asyncDrawable) } + task.execute(file) } if (file.mimeType == "image/png") { diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt index aaede7286fe..e3144741639 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/files/filelist/MainFileListFragment.kt @@ -476,21 +476,19 @@ class MainFileListFragment : Fragment(), if (thumbnail != null) { thumbnailBottomSheet.setImageBitmap(thumbnail) } - if (file.needsToUpdateThumbnail) { + if (file.needsToUpdateThumbnail && ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailBottomSheet)) { // generate new Thumbnail - if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailBottomSheet)) { - val task = ThumbnailsCacheManager.ThumbnailGenerationTask( - thumbnailBottomSheet, - AccountUtils.getCurrentOwnCloudAccount(requireContext()) - ) - val asyncDrawable = ThumbnailsCacheManager.AsyncThumbnailDrawable(resources, thumbnail, task) + val task = ThumbnailsCacheManager.ThumbnailGenerationTask( + thumbnailBottomSheet, + AccountUtils.getCurrentOwnCloudAccount(requireContext()) + ) + val asyncDrawable = ThumbnailsCacheManager.AsyncThumbnailDrawable(resources, thumbnail, task) - // If drawable is not visible, do not update it. - if (asyncDrawable.minimumHeight > 0 && asyncDrawable.minimumWidth > 0) { - thumbnailBottomSheet.setImageDrawable(asyncDrawable) - } - task.execute(file) + // If drawable is not visible, do not update it. + if (asyncDrawable.minimumHeight > 0 && asyncDrawable.minimumWidth > 0) { + thumbnailBottomSheet.setImageDrawable(asyncDrawable) } + task.execute(file) } if (file.mimeType == "image/png") { diff --git a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt index a655a2c97ce..363cdec24a4 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt @@ -180,10 +180,8 @@ class UploadFileFromContentUriWorker( private fun copyFileToLocalStorage() { val cacheFile = File(cachePath) val cacheDir = cacheFile.parentFile - if (cacheDir != null) { - if (!cacheDir.exists()) { - cacheDir.mkdirs() - } + if (cacheDir != null && !cacheDir.exists()) { + cacheDir.mkdirs() } cacheFile.createNewFile() diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/OCFileLoggingTree.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/OCFileLoggingTree.kt index 03f854c874b..03b95ef0b60 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/OCFileLoggingTree.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/OCFileLoggingTree.kt @@ -48,9 +48,8 @@ class OCFileLoggingTree( init { externalCacheDir.let { - if (!it.exists()) { - if (!it.mkdirs()) - Log.e(LOG_TAG, "couldn't create ${it.absoluteFile}") + if (!it.exists() && !it.mkdirs()) { + Log.e(LOG_TAG, "couldn't create ${it.absoluteFile}") } var fileNameTimestamp = SimpleDateFormat(LOG_FILE_TIME_FORMAT, Locale.getDefault()).format(Date()) From c91e1b6f797b00467b66334bbda3ab2a9af695a6 Mon Sep 17 00:00:00 2001 From: joragua Date: Thu, 12 Dec 2024 11:13:24 +0100 Subject: [PATCH 29/31] refactor: remove unused parameters --- .../android/extensions/WorkManagerExt.kt | 10 ----- .../DocumentsStorageProvider.kt | 1 - .../presentation/sharing/ShareFileFragment.kt | 4 +- .../android/ui/activity/FileActivity.java | 2 +- .../ui/activity/FileDisplayActivity.kt | 38 +++---------------- .../ui/errorhandling/ErrorMessageAdapter.kt | 7 +--- .../synchronization/SynchronizeFileUseCase.kt | 4 +- .../android/utils/NotificationUtils.kt | 2 +- 8 files changed, 14 insertions(+), 54 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/WorkManagerExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/WorkManagerExt.kt index e4685b24327..6217218b233 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/extensions/WorkManagerExt.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/WorkManagerExt.kt @@ -62,16 +62,6 @@ fun WorkManager.getRunningWorkInfosLiveData(tags: List): LiveData - if (isFolder) { - startSyncFolderOperation(file, false) - } - } val syncProfileOperation = SyncProfileOperation(account) syncProfileOperation.syncUserProfile() val workManagerProvider = WorkManagerProvider(context = baseContext) @@ -604,7 +598,7 @@ class FileDisplayActivity : FileActivity(), // Handle calls form internal activities. if (requestCode == REQUEST_CODE__SELECT_CONTENT_FROM_APPS && (resultCode == RESULT_OK || resultCode == RESULT_OK_AND_MOVE)) { - requestUploadOfContentFromApps(data, resultCode) + requestUploadOfContentFromApps(data) } else if (requestCode == REQUEST_CODE__UPLOAD_FROM_CAMERA) { if (resultCode == RESULT_OK || resultCode == RESULT_OK_AND_MOVE) { @@ -618,7 +612,7 @@ class FileDisplayActivity : FileActivity(), capturedFilePaths: Array ) { if (hasEnoughSpace) { - requestUploadOfFilesFromFileSystem(capturedFilePaths, UploadBehavior.MOVE.toLegacyLocalBehavior()) + requestUploadOfFilesFromFileSystem(capturedFilePaths) } } }) @@ -640,7 +634,7 @@ class FileDisplayActivity : FileActivity(), } } - private fun requestUploadOfFilesFromFileSystem(filePaths: Array?, behaviour: Int) { + private fun requestUploadOfFilesFromFileSystem(filePaths: Array?) { if (filePaths != null) { val remotePaths = arrayOfNulls(filePaths.size) val remotePathBase = currentDir?.remotePath @@ -661,7 +655,7 @@ class FileDisplayActivity : FileActivity(), } } - private fun requestUploadOfContentFromApps(contentIntent: Intent?, resultCode: Int) { + private fun requestUploadOfContentFromApps(contentIntent: Intent?) { val streamsToUpload = ArrayList() if (contentIntent!!.clipData != null && contentIntent.clipData!!.itemCount > 0) { @@ -920,7 +914,6 @@ class FileDisplayActivity : FileActivity(), val root = storageManager.getRootPersonalFolder() listOfFiles.navigateToFolder(root!!) file = root - startSyncFolderOperation(root, false) } cleanSecondFragment() } @@ -1517,26 +1510,7 @@ class FileDisplayActivity : FileActivity(), } override fun onSavedCertificate() { - startSyncFolderOperation(currentDir, false) - } - - /** - * Starts an operation to refresh the requested folder. - * - * - * The operation is run in a new background thread created on the fly. - * - * - * The refresh updates is a "light sync": properties of regular files in folder are updated (including - * associated shares), but not their contents. Only the contents of files marked to be kept-in-sync are - * synchronized too. - * - * @param folder Folder to refresh. - * @param ignoreETag If 'true', the data from the server will be fetched and synced even if the eTag - * didn't change. - */ - fun startSyncFolderOperation(folder: OCFile?, ignoreETag: Boolean) { - // TODO: SYNC FOLDER + // Nothing to do } private fun requestForDownload(file: OCFile) { @@ -1917,7 +1891,7 @@ class FileDisplayActivity : FileActivity(), } override fun uploadShortcutFileFromApp(shortcutFilePath: Array) { - requestUploadOfFilesFromFileSystem(shortcutFilePath, UploadBehavior.MOVE.toLegacyLocalBehavior()) + requestUploadOfFilesFromFileSystem(shortcutFilePath) } override fun uploadFromFileSystem() { diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/errorhandling/ErrorMessageAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/errorhandling/ErrorMessageAdapter.kt index ac06ea4c962..90242cb1f1f 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/errorhandling/ErrorMessageAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/errorhandling/ErrorMessageAdapter.kt @@ -156,7 +156,6 @@ class ErrorMessageAdapter { */ fun getResultMessage( result: RemoteOperationResult<*>, - operation: RemoteOperation<*>?, resources: Resources ): String { val formatter = Formatter(resources) @@ -184,7 +183,7 @@ class ErrorMessageAdapter { ResultCode.CONFLICT -> formatter.format(R.string.move_file_error) ResultCode.INVALID_COPY_INTO_DESCENDANT -> formatter.format(R.string.copy_file_invalid_into_descendent) - else -> getCommonMessageForResult(operation, result, resources) + else -> getCommonMessageForResult(result, resources) } } @@ -197,7 +196,6 @@ class ErrorMessageAdapter { * @return User message corresponding to 'result'. */ private fun getCommonMessageForResult( - operation: RemoteOperation<*>?, result: RemoteOperationResult<*>, res: Resources ): String { @@ -226,7 +224,7 @@ class ErrorMessageAdapter { ResultCode.ACCOUNT_NOT_THE_SAME -> formatter.format(R.string.auth_account_not_the_same) ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION -> formatter.format(R.string.auth_redirect_non_secure_connection_title) else -> if (result.httpPhrase != null && result.httpPhrase.isNotEmpty()) - result.httpPhrase else getGenericErrorMessageForOperation(operation, result, res) + result.httpPhrase else getGenericErrorMessageForOperation(result, res) } } @@ -238,7 +236,6 @@ class ErrorMessageAdapter { * @return User message corresponding to a generic error of 'operation'. */ private fun getGenericErrorMessageForOperation( - operation: RemoteOperation<*>?, result: RemoteOperationResult<*>, res: Resources ): String { diff --git a/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt b/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt index 543930d9b01..1a1181b3e62 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/usecases/synchronization/SynchronizeFileUseCase.kt @@ -102,7 +102,7 @@ class SynchronizeFileUseCase( } else if (changedLocally) { // 5.3 File has change ONLY locally -> upload new version Timber.i("File ${fileToSynchronize.fileName} has changed locally. Let's upload the new version") - val uuid = requestForUpload(accountName, fileToSynchronize, fileToSynchronize.etag!!) + val uuid = requestForUpload(accountName, fileToSynchronize) return SyncType.UploadEnqueued(uuid) } else { // 5.4 File has not change locally not remotely -> do nothing @@ -121,7 +121,7 @@ class SynchronizeFileUseCase( ) } - private fun requestForUpload(accountName: String, ocFile: OCFile, etagInConflict: String): UUID? { + private fun requestForUpload(accountName: String, ocFile: OCFile): UUID? { return uploadFileInConflictUseCase( UploadFileInConflictUseCase.Params( accountName = accountName, diff --git a/owncloudApp/src/main/java/com/owncloud/android/utils/NotificationUtils.kt b/owncloudApp/src/main/java/com/owncloud/android/utils/NotificationUtils.kt index b7872b282a8..74d72d666dc 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/utils/NotificationUtils.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/utils/NotificationUtils.kt @@ -157,7 +157,7 @@ object NotificationUtils { * @param account account which the file in conflict belongs to */ @JvmStatic - fun notifyConflict(fileInConflict: OCFile, account: Account?, context: Context) { + fun notifyConflict(fileInConflict: OCFile, context: Context) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notificationBuilder = newNotificationBuilder(context, FILE_SYNC_CONFLICT_NOTIFICATION_CHANNEL_ID) notificationBuilder From 94ef60dfa8f750dab95141cb7001571b0d9b0b95 Mon Sep 17 00:00:00 2001 From: joragua Date: Thu, 12 Dec 2024 11:30:58 +0100 Subject: [PATCH 30/31] refactor: rename invalid package declaration --- .../java/com/owncloud/android/extensions/FragmentActivityExt.kt | 2 +- .../com/owncloud/android/presentation/sharing/ShareActivity.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentActivityExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentActivityExt.kt index a063c429968..15f5aca1183 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentActivityExt.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentActivityExt.kt @@ -18,7 +18,7 @@ * along with this program. If not, see //www.gnu.org/licenses/>. */ -package com.owncloud.android.ui.utils +package com.owncloud.android.extensions import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentActivity diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt index 9d009b33bc8..328919f80d4 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/sharing/ShareActivity.kt @@ -47,7 +47,7 @@ import com.owncloud.android.presentation.sharing.sharees.SearchShareesFragment import com.owncloud.android.presentation.sharing.sharees.UsersAndGroupsSearchProvider import com.owncloud.android.presentation.sharing.shares.PublicShareDialogFragment import com.owncloud.android.ui.activity.FileActivity -import com.owncloud.android.ui.utils.showDialogFragment +import com.owncloud.android.extensions.showDialogFragment import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import timber.log.Timber From 1c54683929cd6940bb54a985e8c88a44cb777bc4 Mon Sep 17 00:00:00 2001 From: Jesus Recio Date: Tue, 17 Dec 2024 12:34:25 +0100 Subject: [PATCH 31/31] feat: set up to run detekt over all the modules in parallel --- .github/workflows/detekt.yml | 74 ++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml index efc259ff36b..79445c53c7c 100644 --- a/.github/workflows/detekt.yml +++ b/.github/workflows/detekt.yml @@ -21,6 +21,7 @@ on: push: branches: - feature/detekt + - feature/run_actions_parallel pull_request: branches: - "master" @@ -30,11 +31,9 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "greet" - run: + owncloudApp: # The type of runner that the job will run on runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job steps: - uses: actions/checkout@v4 @@ -50,11 +49,80 @@ jobs: uses: gradle/actions/setup-gradle@v4 - name: module owncloudApp run: ./gradlew detekt + + owncloudDomain: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 - name: module owncloudDomain run: ./gradlew owncloudDomain:detekt + + owncloudData: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 - name: module owncloudData run: ./gradlew owncloudData:detekt + + owncloudComLibrary: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 - name: module owncloudComLibrary run: ./gradlew owncloudComLibrary:detekt + + + owncloudTestUtil: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 - name: module owncloudTestUtil run: ./gradlew owncloudTestUtil:detekt