Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
Tobias Kaminsky 2022-10-15 02:32:08 +02:00
commit 469b4e8033
369 changed files with 4494 additions and 4060 deletions

View file

@ -31,7 +31,7 @@ jobs:
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v2 uses: actions/setup-java@v3
with: with:
distribution: "temurin" distribution: "temurin"
java-version: 11 java-version: 11

View file

@ -3,7 +3,7 @@ import org.gradle.internal.jvm.Jvm
buildscript { buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.3.0' classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.hiya:jacoco-android:0.2' classpath 'com.hiya:jacoco-android:0.2'
classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.12' classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.12'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
@ -112,7 +112,7 @@ android {
buildTypes { buildTypes {
debug { debug {
testCoverageEnabled (project.hasProperty('coverage')) testCoverageEnabled(project.hasProperty('coverage'))
} }
} }
@ -218,7 +218,7 @@ dependencies {
// dependencies for app building // dependencies for app building
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
// implementation project('nextcloud-android-library') // implementation project('nextcloud-android-library')
implementation ("com.github.nextcloud:android-library:$androidLibraryVersion") { implementation("com.github.nextcloud:android-library:$androidLibraryVersion") {
exclude group: 'org.ogce', module: 'xpp3' // unused in Android and brings wrong Junit version exclude group: 'org.ogce', module: 'xpp3' // unused in Android and brings wrong Junit version
} }
@ -296,8 +296,8 @@ dependencies {
implementation "io.noties:prism4j:$prismVersion" implementation "io.noties:prism4j:$prismVersion"
kapt "io.noties:prism4j-bundler:$prismVersion" kapt "io.noties:prism4j-bundler:$prismVersion"
implementation ('org.mnode.ical4j:ical4j:3.0.0') { implementation('org.mnode.ical4j:ical4j:3.0.0') {
['org.apache.commons','commons-logging'].each { ['org.apache.commons', 'commons-logging'].each {
exclude group: "$it" exclude group: "$it"
} }
} }
@ -352,10 +352,12 @@ dependencies {
// upon each update first test: new registration, receive push // upon each update first test: new registration, receive push
gplayImplementation "com.google.firebase:firebase-messaging:23.0.7" gplayImplementation "com.google.firebase:firebase-messaging:23.0.7"
implementation 'com.github.nextcloud.android-common:ui:0.2.0'
} }
configurations.all { configurations.all {
resolutionStrategy{ resolutionStrategy {
cacheChangingModulesFor 0, 'seconds' cacheChangingModulesFor 0, 'seconds'
force 'org.objenesis:objenesis:2.6' force 'org.objenesis:objenesis:2.6'
eachDependency { details -> eachDependency { details ->
@ -400,7 +402,7 @@ shot {
showOnlyFailingTestsInReports = ciBuild showOnlyFailingTestsInReports = ciBuild
// CI environment renders some shadows slightly different from local VMs // CI environment renders some shadows slightly different from local VMs
// Add a 0.5% tolerance to account for that // Add a 0.5% tolerance to account for that
tolerance = ciBuild ? 0.5: 0 tolerance = ciBuild ? 0.5 : 0
} }
jacoco { jacoco {
@ -413,7 +415,7 @@ spotbugs {
reportLevel = "medium" reportLevel = "medium"
} }
tasks.withType(SpotBugsTask){task -> tasks.withType(SpotBugsTask) { task ->
String variantNameCap = task.name.replace("spotbugs", "") String variantNameCap = task.name.replace("spotbugs", "")
String variantName = variantNameCap.substring(0, 1).toLowerCase() + variantNameCap.substring(1) String variantName = variantNameCap.substring(0, 1).toLowerCase() + variantNameCap.substring(1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -0,0 +1,139 @@
/*
*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2022 Tobias Kaminsky
* Copyright (C) 2022 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.ui
import android.graphics.BitmapFactory
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.test.espresso.intent.rule.IntentsTestRule
import com.nextcloud.client.TestActivity
import com.owncloud.android.AbstractIT
import com.owncloud.android.R
import com.owncloud.android.utils.BitmapUtils
import com.owncloud.android.utils.ScreenshotTest
import org.junit.Rule
import org.junit.Test
class BitmapIT : AbstractIT() {
@get:Rule
val testActivityRule = IntentsTestRule(TestActivity::class.java, true, false)
@Test
@ScreenshotTest
fun roundBitmap() {
val file = getFile("christine.jpg")
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
val activity = testActivityRule.launchActivity(null)
val imageView = ImageView(activity).apply {
setImageBitmap(bitmap)
}
val bitmap2 = BitmapFactory.decodeFile(file.absolutePath)
val imageView2 = ImageView(activity).apply {
setImageBitmap(BitmapUtils.roundBitmap(bitmap2))
}
val linearLayout = LinearLayout(activity).apply {
orientation = LinearLayout.VERTICAL
setBackgroundColor(context.getColor(R.color.grey_200))
}
linearLayout.addView(imageView, 200, 200)
linearLayout.addView(imageView2, 200, 200)
activity.addView(linearLayout)
screenshot(activity)
}
// @Test
// @ScreenshotTest
// fun glideSVG() {
// val activity = testActivityRule.launchActivity(null)
// val accountProvider = UserAccountManagerImpl.fromContext(activity)
// val clientFactory = ClientFactoryImpl(activity)
//
// val linearLayout = LinearLayout(activity).apply {
// orientation = LinearLayout.VERTICAL
// setBackgroundColor(context.getColor(R.color.grey_200))
// }
//
// val file = getFile("christine.jpg")
// val bitmap = BitmapFactory.decodeFile(file.absolutePath)
//
// ImageView(activity).apply {
// setImageBitmap(bitmap)
// linearLayout.addView(this, 50, 50)
// }
//
// downloadIcon(
// client.baseUri.toString() + "/apps/files/img/app.svg",
// activity,
// linearLayout,
// accountProvider,
// clientFactory
// )
//
// downloadIcon(
// client.baseUri.toString() + "/core/img/actions/group.svg",
// activity,
// linearLayout,
// accountProvider,
// clientFactory
// )
//
// activity.addView(linearLayout)
//
// longSleep()
//
// screenshot(activity)
// }
//
// private fun downloadIcon(
// url: String,
// activity: TestActivity,
// linearLayout: LinearLayout,
// accountProvider: UserAccountManager,
// clientFactory: ClientFactory
// ) {
// val view = ImageView(activity).apply {
// linearLayout.addView(this, 50, 50)
// }
// val target = object : SimpleTarget<Drawable>() {
// override fun onResourceReady(resource: Drawable?, glideAnimation: GlideAnimation<in Drawable>?) {
// view.setColorFilter(targetContext.getColor(R.color.dark), PorterDuff.Mode.SRC_ATOP)
// view.setImageDrawable(resource)
// }
// }
//
// testActivityRule.runOnUiThread {
// DisplayUtils.downloadIcon(
// accountProvider,
// clientFactory,
// activity,
// url,
// target,
// R.drawable.ic_user
// )
// }
// }
}

View file

@ -22,6 +22,7 @@ package com.owncloud.android.ui.activity;
*/ */
import com.owncloud.android.AbstractIT; import com.owncloud.android.AbstractIT;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.utils.ScreenshotTest; import com.owncloud.android.utils.ScreenshotTest;
@ -128,6 +129,10 @@ public class FolderPickerActivityIT extends AbstractIT {
OCFile origin = new OCFile("/test/file.txt"); OCFile origin = new OCFile("/test/file.txt");
sut.setFile(origin); sut.setFile(origin);
sut.runOnUiThread(() -> {
sut.findViewById(R.id.folder_picker_btn_choose).requestFocus();
});
waitForIdleSync();
screenshot(sut); screenshot(sut);
} }
} }

View file

@ -30,6 +30,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.nextcloud.android.lib.resources.profile.Action; import com.nextcloud.android.lib.resources.profile.Action;
import com.nextcloud.android.lib.resources.profile.HoverCard; import com.nextcloud.android.lib.resources.profile.HoverCard;
@ -57,6 +59,7 @@ import com.owncloud.android.lib.resources.users.Status;
import com.owncloud.android.lib.resources.users.StatusType; import com.owncloud.android.lib.resources.users.StatusType;
import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetActions; import com.owncloud.android.ui.fragment.OCFileListBottomSheetActions;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialogFragment; import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialogFragment;
import com.owncloud.android.ui.fragment.ProfileBottomSheetDialog; import com.owncloud.android.ui.fragment.ProfileBottomSheetDialog;
import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.MimeTypeUtil;
@ -402,7 +405,21 @@ public class DialogFragmentIT extends AbstractIT {
user, user,
ocFile); ocFile);
showDialog(fda, sut); sut.show(fda.getSupportFragmentManager(), "");
getInstrumentation().waitForIdleSync();
shortSleep();
((BottomSheetDialog) sut.requireDialog()).getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);
getInstrumentation().waitForIdleSync();
shortSleep();
ViewGroup viewGroup = sut.requireDialog().getWindow().findViewById(android.R.id.content);
hideCursors(viewGroup);
screenshot(Objects.requireNonNull(sut.requireDialog().getWindow()).getDecorView());
} }
@Test @Test
@ -438,8 +455,7 @@ public class DialogFragmentIT extends AbstractIT {
ProfileBottomSheetDialog sut = new ProfileBottomSheetDialog(fda, ProfileBottomSheetDialog sut = new ProfileBottomSheetDialog(fda,
user, user,
hoverCard, hoverCard,
fda.themeColorUtils, fda.viewThemeUtils);
fda.themeDrawableUtils);
fda.runOnUiThread(sut::show); fda.runOnUiThread(sut::show);

View file

@ -40,9 +40,7 @@
<uses-permission <uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" /> tools:ignore="ScopedStorage" />
<uses-permission <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
@ -151,6 +149,13 @@
<activity <activity
android:name=".ui.activity.SyncedFoldersActivity" android:name=".ui.activity.SyncedFoldersActivity"
android:exported="false" /> android:exported="false" />
<activity
android:name="com.nextcloud.client.widget.DashboardWidgetConfigurationActivity"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<receiver <receiver
android:name="com.nextcloud.client.jobs.MediaFoldersDetectionWork$NotificationReceiver" android:name="com.nextcloud.client.jobs.MediaFoldersDetectionWork$NotificationReceiver"
@ -158,6 +163,17 @@
<receiver <receiver
android:name="com.nextcloud.client.jobs.NotificationWork$NotificationReceiver" android:name="com.nextcloud.client.jobs.NotificationWork$NotificationReceiver"
android:exported="false" /> android:exported="false" />
<receiver
android:name="com.nextcloud.client.widget.DashboardWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/dashboard_widget_info" />
</receiver>
<activity <activity
android:name=".ui.activity.UploadFilesActivity" android:name=".ui.activity.UploadFilesActivity"
@ -199,7 +215,7 @@
<activity <activity
android:name=".ui.activity.SettingsActivity" android:name=".ui.activity.SettingsActivity"
android:exported="false" android:exported="false"
android:theme="@style/Theme.ownCloud" /> android:theme="@style/PreferenceTheme" />
<activity <activity
android:name=".ui.preview.PreviewImageActivity" android:name=".ui.preview.PreviewImageActivity"
android:exported="false" android:exported="false"
@ -220,7 +236,6 @@
android:name="android.accounts.AccountAuthenticator" android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" /> android:resource="@xml/authenticator" />
</service> </service>
<service <service
android:name=".syncadapter.FileSyncService" android:name=".syncadapter.FileSyncService"
android:exported="true" android:exported="true"
@ -233,6 +248,10 @@
android:name="android.content.SyncAdapter" android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter_files" /> android:resource="@xml/syncadapter_files" />
</service> </service>
<service
android:name="com.nextcloud.client.widget.DashboardWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS"
android:exported="true" />
<provider <provider
android:name=".providers.FileContentProvider" android:name=".providers.FileContentProvider"
@ -304,16 +323,12 @@
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/exposed_filepaths" /> android:resource="@xml/exposed_filepaths" />
</provider> </provider>
<provider <provider
android:name=".providers.DiskLruImageCacheFileProvider" android:name=".providers.DiskLruImageCacheFileProvider"
android:authorities="@string/image_cache_provider_authority" android:authorities="@string/image_cache_provider_authority"
android:exported="true"
android:grantUriPermissions="true" android:grantUriPermissions="true"
android:permission="android.permission.MANAGE_DOCUMENTS" android:permission="android.permission.MANAGE_DOCUMENTS"></provider> <!-- Disable WorkManager initialization. Whoever designed this, should pay closer attention -->
android:exported="true">
</provider>
<!-- Disable WorkManager initialization. Whoever designed this, should pay closer attention -->
<!-- to "best before" dates in his fridge. --> <!-- to "best before" dates in his fridge. -->
<!-- disable default provider --> <!-- disable default provider -->
<provider <provider
@ -327,8 +342,6 @@
tools:node="remove" /> tools:node="remove" />
</provider> </provider>
<activity <activity
android:name=".authentication.AuthenticatorActivity" android:name=".authentication.AuthenticatorActivity"
android:configChanges="orientation|screenSize|keyboardHidden" android:configChanges="orientation|screenSize|keyboardHidden"
@ -341,7 +354,6 @@
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".authentication.DeepLinkLoginActivity" android:name=".authentication.DeepLinkLoginActivity"
android:clearTaskOnLaunch="true" android:clearTaskOnLaunch="true"
@ -391,11 +403,9 @@
<activity <activity
android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity" android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity"
android:exported="false" /> android:exported="false" />
<activity <activity
android:name="com.nextcloud.client.logger.ui.LogsActivity" android:name="com.nextcloud.client.logger.ui.LogsActivity"
android:exported="false" /> android:exported="false" />
<activity <activity
android:name="com.nextcloud.client.errorhandling.ShowErrorActivity" android:name="com.nextcloud.client.errorhandling.ShowErrorActivity"
android:excludeFromRecents="true" android:excludeFromRecents="true"
@ -465,7 +475,6 @@
android:label="@string/manage_space_title" android:label="@string/manage_space_title"
android:theme="@style/Theme.ownCloud" /> android:theme="@style/Theme.ownCloud" />
<service <service
android:name=".services.AccountManagerService" android:name=".services.AccountManagerService"
android:enabled="true" android:enabled="true"
@ -476,12 +485,10 @@
android:name=".ui.activity.SsoGrantPermissionActivity" android:name=".ui.activity.SsoGrantPermissionActivity"
android:exported="true" android:exported="true"
android:theme="@style/Theme.ownCloud.Dialog.NoTitle" /> android:theme="@style/Theme.ownCloud.Dialog.NoTitle" />
<activity <activity
android:name="com.nextcloud.client.etm.EtmActivity" android:name="com.nextcloud.client.etm.EtmActivity"
android:exported="false" android:exported="false"
android:theme="@style/Theme.ownCloud.Toolbar" /> android:theme="@style/Theme.ownCloud.Toolbar" />
<activity <activity
android:name=".ui.preview.PreviewBitmapActivity" android:name=".ui.preview.PreviewBitmapActivity"
android:exported="false" android:exported="false"

View file

@ -106,11 +106,10 @@ public class PatchMethod extends PostMethod {
// as bytes allows us to keep the current charset without worrying about how // as bytes allows us to keep the current charset without worrying about how
// this charset will effect the encoding of the form url encoded string. // this charset will effect the encoding of the form url encoded string.
String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet()); String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet());
ByteArrayRequestEntity entity = new ByteArrayRequestEntity( return new ByteArrayRequestEntity(
EncodingUtil.getAsciiBytes(content), EncodingUtil.getAsciiBytes(content),
FORM_URL_ENCODED_CONTENT_TYPE FORM_URL_ENCODED_CONTENT_TYPE
); );
return entity;
} else { } else {
return super.generateRequestEntity(); return super.generateRequestEntity();
} }

View file

@ -64,13 +64,14 @@ import com.owncloud.android.ui.activities.data.activities.RemoteActivitiesReposi
import com.owncloud.android.ui.activities.data.files.FilesRepository; import com.owncloud.android.ui.activities.data.files.FilesRepository;
import com.owncloud.android.ui.activities.data.files.FilesServiceApiImpl; import com.owncloud.android.ui.activities.data.files.FilesServiceApiImpl;
import com.owncloud.android.ui.activities.data.files.RemoteFilesRepository; import com.owncloud.android.ui.activities.data.files.RemoteFilesRepository;
import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ViewThemeUtils;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import java.io.File; import java.io.File;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@ -229,11 +230,11 @@ class AppModule {
@Singleton @Singleton
AppNotificationManager notificationsManager(Context context, AppNotificationManager notificationsManager(Context context,
NotificationManager platformNotificationsManager, NotificationManager platformNotificationsManager,
ThemeColorUtils themeColorUtils) { Provider<ViewThemeUtils> viewThemeUtilsProvider) {
return new AppNotificationManagerImpl(context, return new AppNotificationManagerImpl(context,
context.getResources(), context.getResources(),
platformNotificationsManager, platformNotificationsManager,
themeColorUtils); viewThemeUtilsProvider.get());
} }
@Provides @Provides

View file

@ -29,6 +29,9 @@ import com.nextcloud.client.media.PlayerService;
import com.nextcloud.client.migrations.Migrations; import com.nextcloud.client.migrations.Migrations;
import com.nextcloud.client.onboarding.FirstRunActivity; import com.nextcloud.client.onboarding.FirstRunActivity;
import com.nextcloud.client.onboarding.WhatsNewActivity; import com.nextcloud.client.onboarding.WhatsNewActivity;
import com.nextcloud.client.widget.DashboardWidgetConfigurationActivity;
import com.nextcloud.client.widget.DashboardWidgetProvider;
import com.nextcloud.client.widget.DashboardWidgetService;
import com.nextcloud.ui.ChooseAccountDialogFragment; import com.nextcloud.ui.ChooseAccountDialogFragment;
import com.nextcloud.ui.SetStatusDialogFragment; import com.nextcloud.ui.SetStatusDialogFragment;
import com.owncloud.android.MainApp; import com.owncloud.android.MainApp;
@ -100,16 +103,19 @@ import com.owncloud.android.ui.fragment.FeatureFragment;
import com.owncloud.android.ui.fragment.FileDetailActivitiesFragment; import com.owncloud.android.ui.fragment.FileDetailActivitiesFragment;
import com.owncloud.android.ui.fragment.FileDetailFragment; import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.fragment.FileDetailSharingFragment; import com.owncloud.android.ui.fragment.FileDetailSharingFragment;
import com.owncloud.android.ui.fragment.FileDetailsSharingProcessFragment;
import com.owncloud.android.ui.fragment.GalleryFragment; import com.owncloud.android.ui.fragment.GalleryFragment;
import com.owncloud.android.ui.fragment.GalleryFragmentBottomSheetDialog;
import com.owncloud.android.ui.fragment.LocalFileListFragment; import com.owncloud.android.ui.fragment.LocalFileListFragment;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialogFragment;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog; import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialogFragment;
import com.owncloud.android.ui.fragment.OCFileListFragment; import com.owncloud.android.ui.fragment.OCFileListFragment;
import com.owncloud.android.ui.fragment.SharedListFragment; import com.owncloud.android.ui.fragment.SharedListFragment;
import com.owncloud.android.ui.fragment.UnifiedSearchFragment; import com.owncloud.android.ui.fragment.UnifiedSearchFragment;
import com.owncloud.android.ui.fragment.contactsbackup.BackupFragment; import com.owncloud.android.ui.fragment.contactsbackup.BackupFragment;
import com.owncloud.android.ui.fragment.contactsbackup.BackupListFragment; import com.owncloud.android.ui.fragment.contactsbackup.BackupListFragment;
import com.owncloud.android.ui.preview.FileDownloadFragment; import com.owncloud.android.ui.preview.FileDownloadFragment;
import com.owncloud.android.ui.preview.PreviewBitmapActivity;
import com.owncloud.android.ui.preview.PreviewImageActivity; import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment;
@ -251,6 +257,9 @@ abstract class ComponentsModule {
@ContributesAndroidInjector @ContributesAndroidInjector
abstract FileDetailActivitiesFragment fileDetailActivitiesFragment(); abstract FileDetailActivitiesFragment fileDetailActivitiesFragment();
@ContributesAndroidInjector
abstract FileDetailsSharingProcessFragment fileDetailsSharingProcessFragment();
@ContributesAndroidInjector @ContributesAndroidInjector
abstract FileDetailSharingFragment fileDetailSharingFragment(); abstract FileDetailSharingFragment fileDetailSharingFragment();
@ -341,6 +350,9 @@ abstract class ComponentsModule {
@ContributesAndroidInjector @ContributesAndroidInjector
abstract FileSyncService fileSyncService(); abstract FileSyncService fileSyncService();
@ContributesAndroidInjector
abstract DashboardWidgetService dashboardWidgetService();
@ContributesAndroidInjector @ContributesAndroidInjector
abstract PreviewPdfFragment previewPDFFragment(); abstract PreviewPdfFragment previewPDFFragment();
@ -430,4 +442,16 @@ abstract class ComponentsModule {
@ContributesAndroidInjector @ContributesAndroidInjector
abstract SyncFileNotEnoughSpaceDialogFragment syncFileNotEnoughSpaceDialogFragment(); abstract SyncFileNotEnoughSpaceDialogFragment syncFileNotEnoughSpaceDialogFragment();
@ContributesAndroidInjector
abstract DashboardWidgetConfigurationActivity dashboardWidgetConfigurationActivity();
@ContributesAndroidInjector
abstract DashboardWidgetProvider dashboardWidgetProvider();
@ContributesAndroidInjector
abstract GalleryFragmentBottomSheetDialog galleryFragmentBottomSheetDialog();
@ContributesAndroidInjector
abstract PreviewBitmapActivity previewBitmapActivity();
} }

View file

@ -20,112 +20,39 @@
*/ */
package com.nextcloud.client.di package com.nextcloud.client.di
import android.content.Context import com.nextcloud.android.common.ui.theme.MaterialSchemes
import com.owncloud.android.utils.theme.ThemeAvatarUtils import com.owncloud.android.utils.theme.MaterialSchemesProvider
import com.owncloud.android.utils.theme.ThemeBarUtils import com.owncloud.android.utils.theme.MaterialSchemesProviderImpl
import com.owncloud.android.utils.theme.ThemeButtonUtils
import com.owncloud.android.utils.theme.ThemeCheckableUtils
import com.owncloud.android.utils.theme.ThemeColorUtils import com.owncloud.android.utils.theme.ThemeColorUtils
import com.owncloud.android.utils.theme.ThemeDrawableUtils
import com.owncloud.android.utils.theme.ThemeFabUtils
import com.owncloud.android.utils.theme.ThemeLayoutUtils
import com.owncloud.android.utils.theme.ThemeMenuUtils
import com.owncloud.android.utils.theme.ThemeSnackbarUtils
import com.owncloud.android.utils.theme.ThemeTextInputUtils
import com.owncloud.android.utils.theme.ThemeTextUtils
import com.owncloud.android.utils.theme.ThemeToolbarUtils
import com.owncloud.android.utils.theme.ThemeUtils import com.owncloud.android.utils.theme.ThemeUtils
import dagger.Binds
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
internal class ThemeModule { internal abstract class ThemeModule {
@Provides
@Singleton
fun themeColorUtils(): ThemeColorUtils {
return ThemeColorUtils()
}
@Provides @Binds
@Singleton abstract fun bindMaterialSchemesProvider(provider: MaterialSchemesProviderImpl): MaterialSchemesProvider
fun themeFabUtils(themeColorUtils: ThemeColorUtils?, themeDrawableUtils: ThemeDrawableUtils?): ThemeFabUtils {
return ThemeFabUtils(themeColorUtils, themeDrawableUtils)
}
@Provides companion object {
@Singleton
fun themeLayoutUtils(themeColorUtils: ThemeColorUtils?): ThemeLayoutUtils {
return ThemeLayoutUtils(themeColorUtils)
}
@Provides @Provides
@Singleton @Singleton
fun themeToolbarUtils( fun themeColorUtils(): ThemeColorUtils {
themeColorUtils: ThemeColorUtils?, return ThemeColorUtils()
themeDrawableUtils: ThemeDrawableUtils?, }
themeTextInputUtils: ThemeTextInputUtils?
): ThemeToolbarUtils {
return ThemeToolbarUtils(themeColorUtils, themeDrawableUtils, themeTextInputUtils)
}
@Provides @Provides
@Singleton @Singleton
fun themeDrawableUtils(context: Context?): ThemeDrawableUtils { fun themeUtils(): ThemeUtils {
return ThemeDrawableUtils(context) return ThemeUtils()
} }
@Provides @Provides
@Singleton fun provideMaterialSchemes(materialSchemesProvider: MaterialSchemesProvider): MaterialSchemes {
fun themeUtils(): ThemeUtils { return materialSchemesProvider.getMaterialSchemesForCurrentUser()
return ThemeUtils() }
}
@Provides
@Singleton
fun themeMenuUtils(): ThemeMenuUtils {
return ThemeMenuUtils()
}
@Provides
@Singleton
fun themeSnackbarUtils(): ThemeSnackbarUtils {
return ThemeSnackbarUtils()
}
@Provides
@Singleton
fun themeTextUtils(): ThemeTextUtils {
return ThemeTextUtils()
}
@Provides
@Singleton
fun themeButtonUtils(): ThemeButtonUtils {
return ThemeButtonUtils()
}
@Provides
@Singleton
fun themeBarUtils(): ThemeBarUtils {
return ThemeBarUtils()
}
@Provides
@Singleton
fun themeTextInputUtils(): ThemeTextInputUtils {
return ThemeTextInputUtils()
}
@Provides
@Singleton
fun themeCheckableUtils(): ThemeCheckableUtils {
return ThemeCheckableUtils()
}
@Provides
@Singleton
fun themeAvatarUtils(): ThemeAvatarUtils {
return ThemeAvatarUtils()
} }
} }

View file

@ -40,9 +40,7 @@ import com.nextcloud.client.preferences.AppPreferences
import com.owncloud.android.datamodel.ArbitraryDataProvider import com.owncloud.android.datamodel.ArbitraryDataProvider
import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.datamodel.SyncedFolderProvider
import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.datamodel.UploadsStorageManager
import com.owncloud.android.utils.theme.ThemeButtonUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import com.owncloud.android.utils.theme.ThemeColorUtils
import com.owncloud.android.utils.theme.ThemeSnackbarUtils
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider import javax.inject.Provider
@ -67,9 +65,7 @@ class BackgroundJobFactory @Inject constructor(
private val notificationManager: NotificationManager, private val notificationManager: NotificationManager,
private val eventBus: EventBus, private val eventBus: EventBus,
private val deckApi: DeckApi, private val deckApi: DeckApi,
private val themeColorUtils: ThemeColorUtils, private val viewThemeUtils: Provider<ViewThemeUtils>
private val themeSnackbarUtils: ThemeSnackbarUtils,
private val themeButtonUtils: ThemeButtonUtils
) : WorkerFactory() { ) : WorkerFactory() {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@ -113,7 +109,7 @@ class BackgroundJobFactory @Inject constructor(
context, context,
accountManager.user, accountManager.user,
contentResolver, contentResolver,
themeColorUtils, viewThemeUtils.get(),
params params
) )
} }
@ -212,9 +208,7 @@ class BackgroundJobFactory @Inject constructor(
accountManager, accountManager,
preferences, preferences,
clock, clock,
themeColorUtils, viewThemeUtils.get()
themeSnackbarUtils,
themeButtonUtils
) )
} }
@ -225,7 +219,7 @@ class BackgroundJobFactory @Inject constructor(
notificationManager, notificationManager,
accountManager, accountManager,
deckApi, deckApi,
themeColorUtils viewThemeUtils.get()
) )
} }

View file

@ -44,14 +44,14 @@ import com.owncloud.android.ui.dialog.SendShareDialog
import com.owncloud.android.ui.notifications.NotificationUtils import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.utils.FileExportUtils import com.owncloud.android.utils.FileExportUtils
import com.owncloud.android.utils.FileStorageUtils import com.owncloud.android.utils.FileStorageUtils
import com.owncloud.android.utils.theme.ThemeColorUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import java.security.SecureRandom import java.security.SecureRandom
class FilesExportWork( class FilesExportWork(
private val appContext: Context, private val appContext: Context,
private val user: User, private val user: User,
private val contentResolver: ContentResolver, private val contentResolver: ContentResolver,
private val themeColorUtils: ThemeColorUtils, private val viewThemeUtils: ViewThemeUtils,
params: WorkerParameters params: WorkerParameters
) : Worker(appContext, params) { ) : Worker(appContext, params) {
@ -153,11 +153,12 @@ class FilesExportWork(
) )
.setSmallIcon(R.drawable.notification_icon) .setSmallIcon(R.drawable.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(appContext.resources, R.drawable.notification_icon)) .setLargeIcon(BitmapFactory.decodeResource(appContext.resources, R.drawable.notification_icon))
.setColor(themeColorUtils.primaryColor(appContext))
.setSubText(user.accountName) .setSubText(user.accountName)
.setContentText(message) .setContentText(message)
.setAutoCancel(true) .setAutoCancel(true)
viewThemeUtils.androidx.themeNotificationCompatBuilder(appContext, notificationBuilder)
val actionIntent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).apply { val actionIntent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).apply {
flags = FLAG_ACTIVITY_NEW_TASK flags = FLAG_ACTIVITY_NEW_TASK
} }

View file

@ -55,9 +55,7 @@ import com.owncloud.android.ui.activity.ManageAccountsActivity.PENDING_FOR_REMOV
import com.owncloud.android.ui.activity.SyncedFoldersActivity import com.owncloud.android.ui.activity.SyncedFoldersActivity
import com.owncloud.android.ui.notifications.NotificationUtils import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.utils.SyncedFolderUtils import com.owncloud.android.utils.SyncedFolderUtils
import com.owncloud.android.utils.theme.ThemeButtonUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import com.owncloud.android.utils.theme.ThemeColorUtils
import com.owncloud.android.utils.theme.ThemeSnackbarUtils
import java.util.Random import java.util.Random
@Suppress("LongParameterList") // dependencies injection @Suppress("LongParameterList") // dependencies injection
@ -69,9 +67,7 @@ class MediaFoldersDetectionWork constructor(
private val userAccountManager: UserAccountManager, private val userAccountManager: UserAccountManager,
private val preferences: AppPreferences, private val preferences: AppPreferences,
private val clock: Clock, private val clock: Clock,
private val themeColorUtils: ThemeColorUtils, private val viewThemeUtils: ViewThemeUtils
private val themeSnackbarUtils: ThemeSnackbarUtils,
private val themeButtonUtils: ThemeButtonUtils
) : Worker(context, params) { ) : Worker(context, params) {
companion object { companion object {
@ -97,14 +93,14 @@ class MediaFoldersDetectionWork constructor(
1, 1,
null, null,
true, true,
themeSnackbarUtils viewThemeUtils
) )
val videoMediaFolders = MediaProvider.getVideoFolders( val videoMediaFolders = MediaProvider.getVideoFolders(
contentResolver, contentResolver,
1, 1,
null, null,
true, true,
themeSnackbarUtils viewThemeUtils
) )
val imageMediaFolderPaths: MutableList<String> = ArrayList() val imageMediaFolderPaths: MutableList<String> = ArrayList()
val videoMediaFolderPaths: MutableList<String> = ArrayList() val videoMediaFolderPaths: MutableList<String> = ArrayList()
@ -222,13 +218,15 @@ class MediaFoldersDetectionWork constructor(
) )
.setSmallIcon(R.drawable.notification_icon) .setSmallIcon(R.drawable.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon)) .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
.setColor(themeColorUtils.primaryColor(context))
.setSubText(user.accountName) .setSubText(user.accountName)
.setContentTitle(contentTitle) .setContentTitle(contentTitle)
.setContentText(subtitle) .setContentText(subtitle)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setAutoCancel(true) .setAutoCancel(true)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
viewThemeUtils.androidx.themeNotificationCompatBuilder(context, notificationBuilder)
val disableDetection = Intent(context, NotificationReceiver::class.java) val disableDetection = Intent(context, NotificationReceiver::class.java)
disableDetection.putExtra(NOTIFICATION_ID, notificationId) disableDetection.putExtra(NOTIFICATION_ID, notificationId)
disableDetection.action = DISABLE_DETECTION_CLICK disableDetection.action = DISABLE_DETECTION_CLICK

View file

@ -54,7 +54,7 @@ import com.owncloud.android.ui.activity.FileDisplayActivity
import com.owncloud.android.ui.activity.NotificationsActivity import com.owncloud.android.ui.activity.NotificationsActivity
import com.owncloud.android.ui.notifications.NotificationUtils import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.utils.PushUtils import com.owncloud.android.utils.PushUtils
import com.owncloud.android.utils.theme.ThemeColorUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import org.apache.commons.httpclient.HttpMethod import org.apache.commons.httpclient.HttpMethod
import org.apache.commons.httpclient.HttpStatus import org.apache.commons.httpclient.HttpStatus
@ -76,7 +76,7 @@ class NotificationWork constructor(
private val notificationManager: NotificationManager, private val notificationManager: NotificationManager,
private val accountManager: UserAccountManager, private val accountManager: UserAccountManager,
private val deckApi: DeckApi, private val deckApi: DeckApi,
private val themeColorUtils: ThemeColorUtils private val viewThemeUtils: ViewThemeUtils
) : Worker(context, params) { ) : Worker(context, params) {
companion object { companion object {
@ -168,7 +168,6 @@ class NotificationWork constructor(
val notificationBuilder = NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_PUSH) val notificationBuilder = NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_PUSH)
.setSmallIcon(R.drawable.notification_icon) .setSmallIcon(R.drawable.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon)) .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
.setColor(themeColorUtils.primaryColor(user.toPlatformAccount(), false, context))
.setShowWhen(true) .setShowWhen(true)
.setSubText(user.accountName) .setSubText(user.accountName)
.setContentTitle(notification.getSubject()) .setContentTitle(notification.getSubject())
@ -177,6 +176,9 @@ class NotificationWork constructor(
.setAutoCancel(true) .setAutoCancel(true)
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE) .setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
viewThemeUtils.androidx.themeNotificationCompatBuilder(context, notificationBuilder)
// Remove // Remove
if (notification.getActions().isEmpty()) { if (notification.getActions().isEmpty()) {
val disableDetection = Intent(context, NotificationReceiver::class.java) val disableDetection = Intent(context, NotificationReceiver::class.java)
@ -223,14 +225,17 @@ class NotificationWork constructor(
NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_PUSH) NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_PUSH)
.setSmallIcon(R.drawable.notification_icon) .setSmallIcon(R.drawable.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon)) .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
.setColor(themeColorUtils.primaryColor(user.toPlatformAccount(), false, context))
.setShowWhen(true) .setShowWhen(true)
.setSubText(user.accountName) .setSubText(user.accountName)
.setContentTitle(context.getString(R.string.new_notification)) .setContentTitle(context.getString(R.string.new_notification))
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setAutoCancel(true) .setAutoCancel(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentIntent(pendingIntent).build() .setContentIntent(pendingIntent)
.also {
viewThemeUtils.androidx.themeNotificationCompatBuilder(context, it)
}
.build()
) )
val notificationManager = NotificationManagerCompat.from(context) val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(notification.getNotificationId(), notificationBuilder.build()) notificationManager.notify(notification.getNotificationId(), notificationBuilder.build())

View file

@ -33,7 +33,7 @@ import com.nextcloud.client.di.ViewModelFactory
import com.owncloud.android.R import com.owncloud.android.R
import com.owncloud.android.databinding.LogsActivityBinding import com.owncloud.android.databinding.LogsActivityBinding
import com.owncloud.android.ui.activity.ToolbarActivity import com.owncloud.android.ui.activity.ToolbarActivity
import com.owncloud.android.utils.theme.ThemeBarUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import javax.inject.Inject import javax.inject.Inject
class LogsActivity : ToolbarActivity() { class LogsActivity : ToolbarActivity() {
@ -42,7 +42,8 @@ class LogsActivity : ToolbarActivity() {
protected lateinit var viewModelFactory: ViewModelFactory protected lateinit var viewModelFactory: ViewModelFactory
@Inject @Inject
protected lateinit var themeBarUtils: ThemeBarUtils lateinit var viewThemeUtils: ViewThemeUtils
private lateinit var vm: LogsViewModel private lateinit var vm: LogsViewModel
private lateinit var binding: LogsActivityBinding private lateinit var binding: LogsActivityBinding
private lateinit var logsAdapter: LogsAdapter private lateinit var logsAdapter: LogsAdapter
@ -67,7 +68,7 @@ class LogsActivity : ToolbarActivity() {
} }
findViewById<ProgressBar>(R.id.logs_loading_progress).apply { findViewById<ProgressBar>(R.id.logs_loading_progress).apply {
themeBarUtils.themeProgressBar(context, this, themeColorUtils) viewThemeUtils.platform.themeHorizontalProgressBar(this)
} }
logsAdapter = LogsAdapter(this) logsAdapter = LogsAdapter(this)
@ -81,17 +82,18 @@ class LogsActivity : ToolbarActivity() {
setupToolbar() setupToolbar()
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.apply { themeToolbarUtils.setColoredTitle(this, getString(R.string.logs_title), baseContext) }
themeToolbarUtils.tintBackButton(supportActionBar, baseContext) supportActionBar?.let {
viewThemeUtils.files.themeActionBar(this, it, R.string.logs_title)
}
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.activity_logs, menu) menuInflater.inflate(R.menu.activity_logs, menu)
(menu.findItem(R.id.action_search).actionView as SearchView).apply { (menu.findItem(R.id.action_search).actionView as SearchView).apply {
setOnQueryTextListener(searchBoxListener) setOnQueryTextListener(searchBoxListener)
viewThemeUtils.androidx.themeToolbarSearchView(this)
themeToolbarUtils.themeSearchView(this, context)
} }
return super.onCreateOptionsMenu(menu) return super.onCreateOptionsMenu(menu)
} }

View file

@ -33,7 +33,7 @@ import com.nextcloud.client.network.ClientFactory
import com.owncloud.android.R import com.owncloud.android.R
import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.ui.notifications.NotificationUtils import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.utils.theme.ThemeColorUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import java.util.Locale import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@ -90,7 +90,7 @@ class PlayerService : Service() {
protected lateinit var clientFactory: ClientFactory protected lateinit var clientFactory: ClientFactory
@Inject @Inject
protected lateinit var themeColorUtils: ThemeColorUtils lateinit var viewThemeUtils: ViewThemeUtils
private lateinit var player: Player private lateinit var player: Player
private lateinit var notificationBuilder: NotificationCompat.Builder private lateinit var notificationBuilder: NotificationCompat.Builder
@ -101,7 +101,7 @@ class PlayerService : Service() {
AndroidInjection.inject(this) AndroidInjection.inject(this)
player = Player(applicationContext, clientFactory, playerListener, audioManager) player = Player(applicationContext, clientFactory, playerListener, audioManager)
notificationBuilder = NotificationCompat.Builder(this) notificationBuilder = NotificationCompat.Builder(this)
notificationBuilder.color = themeColorUtils.primaryColor(this) viewThemeUtils.androidx.themeNotificationCompatBuilder(this, notificationBuilder)
val stop = Intent(this, PlayerService::class.java) val stop = Intent(this, PlayerService::class.java)
stop.action = ACTION_STOP stop.action = ACTION_STOP

View file

@ -37,11 +37,11 @@ import com.owncloud.android.lib.common.accounts.AccountUtils;
import java.io.IOException; import java.io.IOException;
class ClientFactoryImpl implements ClientFactory { public class ClientFactoryImpl implements ClientFactory {
private Context context; private Context context;
ClientFactoryImpl(Context context) { public ClientFactoryImpl(Context context) {
this.context = context; this.context = context;
} }
@ -49,8 +49,8 @@ class ClientFactoryImpl implements ClientFactory {
public OwnCloudClient create(User user) throws CreationException { public OwnCloudClient create(User user) throws CreationException {
try { try {
return OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(user.toOwnCloudAccount(), context); return OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(user.toOwnCloudAccount(), context);
} catch (OperationCanceledException| } catch (OperationCanceledException |
AuthenticatorException| AuthenticatorException |
IOException e) { IOException e) {
throw new CreationException(e); throw new CreationException(e);
} }

View file

@ -16,14 +16,14 @@ import com.owncloud.android.ui.activity.FileDisplayActivity
import com.owncloud.android.ui.notifications.NotificationUtils import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.ui.preview.PreviewImageActivity import com.owncloud.android.ui.preview.PreviewImageActivity
import com.owncloud.android.ui.preview.PreviewImageFragment import com.owncloud.android.ui.preview.PreviewImageFragment
import com.owncloud.android.utils.theme.ThemeColorUtils import com.owncloud.android.utils.theme.ViewThemeUtils
import javax.inject.Inject import javax.inject.Inject
class AppNotificationManagerImpl @Inject constructor( class AppNotificationManagerImpl @Inject constructor(
private val context: Context, private val context: Context,
private val resources: Resources, private val resources: Resources,
private val platformNotificationsManager: NotificationManager, private val platformNotificationsManager: NotificationManager,
private val themeColorUtils: ThemeColorUtils private val viewThemeUtils: ViewThemeUtils
) : AppNotificationManager { ) : AppNotificationManager {
companion object { companion object {
@ -32,12 +32,13 @@ class AppNotificationManagerImpl @Inject constructor(
} }
private fun builder(channelId: String): NotificationCompat.Builder { private fun builder(channelId: String): NotificationCompat.Builder {
val color = themeColorUtils.primaryColor(context, true) val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationCompat.Builder(context, channelId)
NotificationCompat.Builder(context, channelId).setColor(color)
} else { } else {
NotificationCompat.Builder(context).setColor(color) NotificationCompat.Builder(context)
} }
viewThemeUtils.androidx.themeNotificationCompatBuilder(context, builder)
return builder
} }
override fun buildDownloadServiceForegroundNotification(): Notification { override fun buildDownloadServiceForegroundNotification(): Notification {

View file

@ -32,9 +32,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import com.nextcloud.client.account.UserAccountManager; import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.appinfo.AppInfo; import com.nextcloud.client.appinfo.AppInfo;
@ -43,11 +41,11 @@ import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.BuildConfig; import com.owncloud.android.BuildConfig;
import com.owncloud.android.R; import com.owncloud.android.R;
import com.owncloud.android.authentication.AuthenticatorActivity; import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.databinding.FirstRunActivityBinding;
import com.owncloud.android.features.FeatureItem; import com.owncloud.android.features.FeatureItem;
import com.owncloud.android.ui.activity.BaseActivity; import com.owncloud.android.ui.activity.BaseActivity;
import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.adapter.FeaturesViewAdapter; import com.owncloud.android.ui.adapter.FeaturesViewAdapter;
import com.owncloud.android.ui.whatsnew.ProgressIndicator;
import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.DisplayUtils;
import javax.inject.Inject; import javax.inject.Inject;
@ -63,29 +61,30 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
public static final String EXTRA_EXIT = "EXIT"; public static final String EXTRA_EXIT = "EXIT";
public static final int FIRST_RUN_RESULT_CODE = 199; public static final int FIRST_RUN_RESULT_CODE = 199;
private ProgressIndicator progressIndicator;
@Inject UserAccountManager userAccountManager; @Inject UserAccountManager userAccountManager;
@Inject AppPreferences preferences; @Inject AppPreferences preferences;
@Inject AppInfo appInfo; @Inject AppInfo appInfo;
@Inject OnboardingService onboarding; @Inject OnboardingService onboarding;
private FirstRunActivityBinding binding;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
enableAccountHandling = false; enableAccountHandling = false;
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.first_run_activity); this.binding = FirstRunActivityBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation); boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
setSlideshowSize(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE); setSlideshowSize(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
Button loginButton = findViewById(R.id.login);
loginButton.setBackgroundColor(getResources().getColor(R.color.login_btn_tint));
loginButton.setTextColor(getResources().getColor(R.color.primary));
loginButton.setOnClickListener(v -> { binding.login.setBackgroundColor(getResources().getColor(R.color.login_btn_tint));
binding.login.setTextColor(getResources().getColor(R.color.primary));
binding.login.setOnClickListener(v -> {
if (getIntent().getBooleanExtra(EXTRA_ALLOW_CLOSE, false)) { if (getIntent().getBooleanExtra(EXTRA_ALLOW_CLOSE, false)) {
Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class); Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class);
authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, false); authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, false);
@ -95,11 +94,11 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
} }
}); });
Button providerButton = findViewById(R.id.signup);
providerButton.setBackgroundColor(getResources().getColor(R.color.primary)); binding.signup.setBackgroundColor(getResources().getColor(R.color.primary));
providerButton.setTextColor(getResources().getColor(R.color.login_text_color)); binding.signup.setTextColor(getResources().getColor(R.color.login_text_color));
providerButton.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE); binding.signup.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
providerButton.setOnClickListener(v -> { binding.signup.setOnClickListener(v -> {
Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class); Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class);
authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, true); authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, true);
@ -111,16 +110,13 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
} }
}); });
TextView hostOwnServerTextView = findViewById(R.id.host_own_server); binding.hostOwnServer.setTextColor(getResources().getColor(R.color.login_text_color));
hostOwnServerTextView.setTextColor(getResources().getColor(R.color.login_text_color)); binding.hostOwnServer.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
hostOwnServerTextView.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
if(!isProviderOrOwnInstallationVisible) { if (!isProviderOrOwnInstallationVisible) {
hostOwnServerTextView.setOnClickListener(v -> onHostYourOwnServerClick()); binding.hostOwnServer.setOnClickListener(v -> onHostYourOwnServerClick());
} }
progressIndicator = findViewById(R.id.progressIndicator);
ViewPager viewPager = findViewById(R.id.contentPanel);
// Sometimes, accounts are not deleted when you uninstall the application so we'll do it now // Sometimes, accounts are not deleted when you uninstall the application so we'll do it now
if (onboarding.isFirstRun()) { if (onboarding.isFirstRun()) {
@ -128,29 +124,26 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
} }
FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(), getFirstRun()); FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(), getFirstRun());
progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount()); binding.progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount());
viewPager.setAdapter(featuresViewAdapter); binding.contentPanel.setAdapter(featuresViewAdapter);
viewPager.addOnPageChangeListener(this); binding.contentPanel.addOnPageChangeListener(this);
} }
private void setSlideshowSize(boolean isLandscape) { private void setSlideshowSize(boolean isLandscape) {
boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation); boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
LinearLayout buttonLayout = findViewById(R.id.buttonLayout);
LinearLayout.LayoutParams layoutParams; LinearLayout.LayoutParams layoutParams;
buttonLayout.setOrientation(isLandscape ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL); binding.buttonLayout.setOrientation(isLandscape ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
LinearLayout bottomLayout = findViewById(R.id.bottomLayout);
if (isProviderOrOwnInstallationVisible) { if (isProviderOrOwnInstallationVisible) {
layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewGroup.LayoutParams.WRAP_CONTENT);
} else { } else {
layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.convertDpToPixel(isLandscape ? 100f : 150f, this));
DisplayUtils.convertDpToPixel(isLandscape ? 100f : 150f, this));
} }
bottomLayout.setLayoutParams(layoutParams); binding.bottomLayout.setLayoutParams(layoutParams);
} }
@Override @Override
@ -196,7 +189,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
@Override @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
progressIndicator.animateToStep(position + 1); binding.progressIndicator.animateToStep(position + 1);
} }
@Override @Override
@ -235,7 +228,6 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
} }
public static FeatureItem[] getFirstRun() { public static FeatureItem[] getFirstRun() {
return new FeatureItem[]{ return new FeatureItem[]{
new FeatureItem(R.drawable.logo, R.string.first_run_1_text, R.string.empty, true, false), new FeatureItem(R.drawable.logo, R.string.first_run_1_text, R.string.empty, true, false),

Some files were not shown because too many files have changed in this diff Show more