mirror of
https://github.com/nextcloud/android.git
synced 2024-11-29 18:59:18 +03:00
Merge master
Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
commit
8a60b0e0f1
30 changed files with 135 additions and 118 deletions
2
.github/workflows/assembleFlavors.yml
vendored
2
.github/workflows/assembleFlavors.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
||||||
- name: set up JDK 17
|
- name: set up JDK 17
|
||||||
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
|
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: 17
|
java-version: 17
|
||||||
|
|
2
.github/workflows/check.yml
vendored
2
.github/workflows/check.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
|
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: 17
|
java-version: 17
|
||||||
|
|
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
|
@ -32,7 +32,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
swap-size-gb: 10
|
swap-size-gb: 10
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
|
uses: github/codeql-action/init@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
|
@ -46,4 +46,4 @@ jobs:
|
||||||
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
|
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
|
||||||
./gradlew assembleDebug
|
./gradlew assembleDebug
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
|
uses: github/codeql-action/analyze@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3
|
||||||
|
|
2
.github/workflows/detectWrongSettings.yml
vendored
2
.github/workflows/detectWrongSettings.yml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
|
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: 17
|
java-version: 17
|
||||||
|
|
2
.github/workflows/qa.yml
vendored
2
.github/workflows/qa.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
|
||||||
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
|
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
|
||||||
- name: set up JDK 17
|
- name: set up JDK 17
|
||||||
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
|
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
|
||||||
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
|
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|
2
.github/workflows/scorecard.yml
vendored
2
.github/workflows/scorecard.yml
vendored
|
@ -37,6 +37,6 @@ jobs:
|
||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
|
uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|
2
.github/workflows/screenShotTest.yml
vendored
2
.github/workflows/screenShotTest.yml
vendored
|
@ -40,7 +40,7 @@ jobs:
|
||||||
~/.android/adb*
|
~/.android/adb*
|
||||||
key: avd-${{ matrix.api-level }}
|
key: avd-${{ matrix.api-level }}
|
||||||
|
|
||||||
- uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
|
- uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: 17
|
java-version: 17
|
||||||
|
|
2
.github/workflows/unit-tests.yml
vendored
2
.github/workflows/unit-tests.yml
vendored
|
@ -20,7 +20,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
|
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
|
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: 17
|
java-version: 17
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
@ -314,7 +314,7 @@ public abstract class AbstractIT {
|
||||||
return currentActivity;
|
return currentActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void shortSleep() {
|
protected static void shortSleep() {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
|
|
@ -135,10 +135,20 @@ public abstract class AbstractOnServerIT extends AbstractIT {
|
||||||
.isSuccess());
|
.isSuccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(new RemoveFileRemoteOperation(remoteFile.getRemotePath())
|
boolean removeResult = false;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
removeResult = new RemoveFileRemoteOperation(remoteFile.getRemotePath())
|
||||||
.execute(client)
|
.execute(client)
|
||||||
.isSuccess()
|
.isSuccess();
|
||||||
);
|
|
||||||
|
if (removeResult) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
shortSleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(removeResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ import com.owncloud.android.operations.RemoveFileOperation;
|
||||||
import com.owncloud.android.operations.UploadFileOperation;
|
import com.owncloud.android.operations.UploadFileOperation;
|
||||||
import com.owncloud.android.utils.FileStorageUtils;
|
import com.owncloud.android.utils.FileStorageUtils;
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -106,29 +105,6 @@ public class UploadIT extends AbstractOnServerIT {
|
||||||
createDummyFiles();
|
createDummyFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
|
||||||
public void after() {
|
|
||||||
RemoteOperationResult result = new RefreshFolderOperation(getStorageManager().getFileByPath("/"),
|
|
||||||
System.currentTimeMillis() / 1000L,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
getStorageManager(),
|
|
||||||
user,
|
|
||||||
targetContext)
|
|
||||||
.execute(client);
|
|
||||||
|
|
||||||
// cleanup only if folder exists
|
|
||||||
if (result.isSuccess() && getStorageManager().getFileByDecryptedRemotePath(FOLDER) != null) {
|
|
||||||
new RemoveFileOperation(getStorageManager().getFileByDecryptedRemotePath(FOLDER),
|
|
||||||
false,
|
|
||||||
user,
|
|
||||||
false,
|
|
||||||
targetContext,
|
|
||||||
getStorageManager())
|
|
||||||
.execute(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyUpload() {
|
public void testEmptyUpload() {
|
||||||
OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/empty.txt",
|
OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/empty.txt",
|
||||||
|
@ -529,8 +505,8 @@ public class UploadIT extends AbstractOnServerIT {
|
||||||
|
|
||||||
assertNotNull(ocFile);
|
assertNotNull(ocFile);
|
||||||
assertEquals(remotePath, ocFile.getRemotePath());
|
assertEquals(remotePath, ocFile.getRemotePath());
|
||||||
assertEquals(new ImageDimension(451f, 529f), ocFile.getImageDimension());
|
assertEquals(new ImageDimension(300f, 200f), ocFile.getImageDimension());
|
||||||
assertEquals(new GeoLocation(49.99679166666667, 8.67198611111111), ocFile.getGeoLocation());
|
assertEquals(new GeoLocation(64, -46), ocFile.getGeoLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyStoragePath(OCFile file) {
|
private void verifyStoragePath(OCFile file) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
package com.owncloud.android.ui
|
package com.owncloud.android.ui
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import androidx.test.core.app.ActivityScenario
|
import androidx.test.core.app.ActivityScenario
|
||||||
import androidx.test.espresso.Espresso
|
import androidx.test.espresso.Espresso
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
|
@ -28,6 +29,7 @@ import androidx.test.espresso.web.sugar.Web
|
||||||
import androidx.test.espresso.web.webdriver.DriverAtoms
|
import androidx.test.espresso.web.webdriver.DriverAtoms
|
||||||
import androidx.test.espresso.web.webdriver.Locator
|
import androidx.test.espresso.web.webdriver.Locator
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import androidx.test.filters.SdkSuppress
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import com.nextcloud.client.account.UserAccountManager
|
import com.nextcloud.client.account.UserAccountManager
|
||||||
import com.nextcloud.client.account.UserAccountManagerImpl
|
import com.nextcloud.client.account.UserAccountManagerImpl
|
||||||
|
@ -59,6 +61,12 @@ class LoginIT : AbstractIT() {
|
||||||
@Test
|
@Test
|
||||||
@Throws(InterruptedException::class)
|
@Throws(InterruptedException::class)
|
||||||
@Suppress("MagicNumber", "SwallowedException")
|
@Suppress("MagicNumber", "SwallowedException")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CI/CD pipeline is encountering issues related to the Android version for this functionality.
|
||||||
|
* Therefore the test will only be executed on Android versions 10 and above.
|
||||||
|
*/
|
||||||
|
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
|
||||||
fun login() {
|
fun login() {
|
||||||
val arguments = InstrumentationRegistry.getArguments()
|
val arguments = InstrumentationRegistry.getArguments()
|
||||||
val baseUrl = arguments.getString("TEST_SERVER_URL")!!
|
val baseUrl = arguments.getString("TEST_SERVER_URL")!!
|
||||||
|
|
|
@ -26,6 +26,7 @@ package com.nextcloud.client.preferences;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.nextcloud.appReview.AppReviewShownModel;
|
import com.nextcloud.appReview.AppReviewShownModel;
|
||||||
|
@ -437,7 +438,14 @@ public final class AppPreferencesImpl implements AppPreferences {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDarkModeEnabled() {
|
public boolean isDarkModeEnabled() {
|
||||||
return getDarkThemeMode() == DarkMode.DARK;
|
DarkMode mode = getDarkThemeMode();
|
||||||
|
|
||||||
|
if (mode == DarkMode.SYSTEM) {
|
||||||
|
int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||||
|
return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode == DarkMode.DARK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -138,7 +138,7 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
keyboardUtils.showKeyboardForEditText(binding.filename);
|
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
@ -119,7 +119,7 @@ class ChooseTemplateDialogFragment : DialogFragment(), View.OnClickListener, Tem
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
keyboardUtils.showKeyboardForEditText(binding.filename)
|
keyboardUtils.showKeyboardForEditText(dialog?.window, binding.filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class CreateFolderDialogFragment
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
bindButton();
|
bindButton();
|
||||||
keyboardUtils.showKeyboardForEditText(binding.userInput);
|
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class NoteDialogFragment extends DialogFragment implements DialogInterfac
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
keyboardUtils.showKeyboardForEditText(binding.noteText);
|
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.noteText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
@ -34,8 +34,8 @@ import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.nextcloud.client.di.Injectable;
|
import com.nextcloud.client.di.Injectable;
|
||||||
|
@ -65,7 +65,7 @@ import androidx.fragment.app.DialogFragment;
|
||||||
* Triggers the rename operation when name is confirmed.
|
* Triggers the rename operation when name is confirmed.
|
||||||
*/
|
*/
|
||||||
public class RenameFileDialogFragment
|
public class RenameFileDialogFragment
|
||||||
extends DialogFragment implements DialogInterface.OnClickListener, Injectable {
|
extends DialogFragment implements DialogInterface.OnClickListener, TextWatcher, Injectable {
|
||||||
|
|
||||||
private static final String ARG_TARGET_FILE = "TARGET_FILE";
|
private static final String ARG_TARGET_FILE = "TARGET_FILE";
|
||||||
private static final String ARG_PARENT_FOLDER = "PARENT_FOLDER";
|
private static final String ARG_PARENT_FOLDER = "PARENT_FOLDER";
|
||||||
|
@ -76,8 +76,8 @@ public class RenameFileDialogFragment
|
||||||
|
|
||||||
private EditBoxDialogBinding binding;
|
private EditBoxDialogBinding binding;
|
||||||
private OCFile mTargetFile;
|
private OCFile mTargetFile;
|
||||||
private Button positiveButton;
|
private MaterialButton positiveButton;
|
||||||
|
private Set<String> fileNames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public factory method to create new RenameFileDialogFragment instances.
|
* Public factory method to create new RenameFileDialogFragment instances.
|
||||||
|
@ -97,20 +97,13 @@ public class RenameFileDialogFragment
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
initAlertDialog();
|
||||||
AlertDialog alertDialog = (AlertDialog) getDialog();
|
|
||||||
|
|
||||||
if (alertDialog != null) {
|
|
||||||
positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
|
||||||
viewThemeUtils.platform.colorTextButtons(positiveButton,
|
|
||||||
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
keyboardUtils.showKeyboardForEditText(binding.userInput);
|
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -133,62 +126,46 @@ public class RenameFileDialogFragment
|
||||||
|
|
||||||
OCFile parentFolder = requireArguments().getParcelable(ARG_PARENT_FOLDER);
|
OCFile parentFolder = requireArguments().getParcelable(ARG_PARENT_FOLDER);
|
||||||
List<OCFile> folderContent = fileDataStorageManager.getFolderContent(parentFolder, false);
|
List<OCFile> folderContent = fileDataStorageManager.getFolderContent(parentFolder, false);
|
||||||
Set<String> fileNames = Sets.newHashSetWithExpectedSize(folderContent.size());
|
fileNames = Sets.newHashSetWithExpectedSize(folderContent.size());
|
||||||
|
|
||||||
for (OCFile file : folderContent) {
|
for (OCFile file : folderContent) {
|
||||||
fileNames.add(file.getFileName());
|
fileNames.add(file.getFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add TextChangedListener to handle showing/hiding the input warning message
|
// Add TextChangedListener to handle showing/hiding the input warning message
|
||||||
binding.userInput.addTextChangedListener(new TextWatcher() {
|
binding.userInput.addTextChangedListener(this);
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When user enters a hidden file name, the 'hidden file' message is shown.
|
|
||||||
* Otherwise, the message is ensured to be hidden.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
String newFileName = "";
|
|
||||||
if (binding.userInput.getText() != null) {
|
|
||||||
newFileName = binding.userInput.getText().toString().trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(newFileName) && newFileName.charAt(0) == '.') {
|
|
||||||
binding.userInputContainer.setError(getText(R.string.hidden_file_name_warning));
|
|
||||||
} else if (TextUtils.isEmpty(newFileName)) {
|
|
||||||
binding.userInputContainer.setError(getString(R.string.filename_empty));
|
|
||||||
positiveButton.setEnabled(false);
|
|
||||||
} else if (fileNames.contains(newFileName)) {
|
|
||||||
binding.userInputContainer.setError(getText(R.string.file_already_exists));
|
|
||||||
positiveButton.setEnabled(false);
|
|
||||||
} else if (binding.userInputContainer.getError() != null) {
|
|
||||||
binding.userInputContainer.setError(null);
|
|
||||||
// Called to remove extra padding
|
|
||||||
binding.userInputContainer.setErrorEnabled(false);
|
|
||||||
positiveButton.setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Build the dialog
|
// Build the dialog
|
||||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
MaterialAlertDialogBuilder builder = buildMaterialAlertDialog(view);
|
||||||
builder.setView(view)
|
|
||||||
.setPositiveButton(R.string.file_rename, this)
|
|
||||||
.setNeutralButton(R.string.common_cancel, this)
|
|
||||||
.setTitle(R.string.rename_dialog_title);
|
|
||||||
|
|
||||||
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.userInputContainer.getContext(), builder);
|
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.userInputContainer.getContext(), builder);
|
||||||
|
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MaterialAlertDialogBuilder buildMaterialAlertDialog(View view) {
|
||||||
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
|
|
||||||
|
builder
|
||||||
|
.setView(view)
|
||||||
|
.setPositiveButton(R.string.file_rename, this)
|
||||||
|
.setNegativeButton(R.string.common_cancel, this)
|
||||||
|
.setTitle(R.string.rename_dialog_title);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAlertDialog() {
|
||||||
|
AlertDialog alertDialog = (AlertDialog) getDialog();
|
||||||
|
|
||||||
|
if (alertDialog != null) {
|
||||||
|
positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
|
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
|
||||||
|
|
||||||
|
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
|
||||||
|
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
@ -219,4 +196,41 @@ public class RenameFileDialogFragment
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
binding = null;
|
binding = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When user enters a hidden file name, the 'hidden file' message is shown.
|
||||||
|
* Otherwise, the message is ensured to be hidden.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
String newFileName = "";
|
||||||
|
if (binding.userInput.getText() != null) {
|
||||||
|
newFileName = binding.userInput.getText().toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(newFileName) && newFileName.charAt(0) == '.') {
|
||||||
|
binding.userInputContainer.setError(getText(R.string.hidden_file_name_warning));
|
||||||
|
} else if (TextUtils.isEmpty(newFileName)) {
|
||||||
|
binding.userInputContainer.setError(getString(R.string.filename_empty));
|
||||||
|
positiveButton.setEnabled(false);
|
||||||
|
} else if (fileNames.contains(newFileName)) {
|
||||||
|
binding.userInputContainer.setError(getText(R.string.file_already_exists));
|
||||||
|
positiveButton.setEnabled(false);
|
||||||
|
} else if (binding.userInputContainer.getError() != null) {
|
||||||
|
binding.userInputContainer.setError(null);
|
||||||
|
// Called to remove extra padding
|
||||||
|
binding.userInputContainer.setErrorEnabled(false);
|
||||||
|
positiveButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class RenamePublicShareDialogFragment
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
keyboardUtils.showKeyboardForEditText(binding.userInput);
|
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
keyboardUtils.showKeyboardForEditText(binding.sharePassword);
|
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.sharePassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Nextcloud Android client application
|
* Nextcloud Android client application
|
||||||
*
|
*
|
||||||
|
* @author ZetaTom
|
||||||
* @author Álvaro Brey
|
* @author Álvaro Brey
|
||||||
|
* Copyright (C) 2023 ZetaTom
|
||||||
* Copyright (C) 2022 Álvaro Brey
|
* Copyright (C) 2022 Álvaro Brey
|
||||||
* Copyright (C) 2022 Nextcloud GmbH
|
* Copyright (C) 2022 Nextcloud GmbH
|
||||||
*
|
*
|
||||||
|
@ -22,26 +24,18 @@
|
||||||
|
|
||||||
package com.owncloud.android.utils
|
package com.owncloud.android.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.view.Window
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class KeyboardUtils @Inject constructor() {
|
class KeyboardUtils @Inject constructor() {
|
||||||
|
|
||||||
fun showKeyboardForEditText(editText: EditText) {
|
fun showKeyboardForEditText(window: Window?, editText: EditText) {
|
||||||
|
if (window != null) {
|
||||||
editText.requestFocus()
|
editText.requestFocus()
|
||||||
// needs 100ms delay to account for focus animations
|
WindowCompat.getInsetsController(window, editText).show(WindowInsetsCompat.Type.ime())
|
||||||
editText.postDelayed({
|
}
|
||||||
val context = editText.context
|
|
||||||
if (context != null) {
|
|
||||||
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
|
||||||
inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
|
|
||||||
}
|
|
||||||
}, SHOW_INPUT_DELAY_MILLIS)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val SHOW_INPUT_DELAY_MILLIS = 100L
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -843,6 +843,7 @@
|
||||||
<string name="trashbin_empty_message">ستتمكن من استعادة الملفات المحذوفة من هنا.</string>
|
<string name="trashbin_empty_message">ستتمكن من استعادة الملفات المحذوفة من هنا.</string>
|
||||||
<string name="trashbin_file_not_deleted">الملف %1$s لا يمكن حذفه!</string>
|
<string name="trashbin_file_not_deleted">الملف %1$s لا يمكن حذفه!</string>
|
||||||
<string name="trashbin_file_not_restored">الملف %1$s لا يمكن إسترجاعه!</string>
|
<string name="trashbin_file_not_restored">الملف %1$s لا يمكن إسترجاعه!</string>
|
||||||
|
<string name="trashbin_file_remove">حذف نهائي</string>
|
||||||
<string name="trashbin_loading_failed">فشل تحميل سلة المحذوفات</string>
|
<string name="trashbin_loading_failed">فشل تحميل سلة المحذوفات</string>
|
||||||
<string name="trashbin_not_emptied">تعذر حذف الملفات نهائياً!</string>
|
<string name="trashbin_not_emptied">تعذر حذف الملفات نهائياً!</string>
|
||||||
<string name="unlock_file">فتح قفل الملف</string>
|
<string name="unlock_file">فتح قفل الملف</string>
|
||||||
|
|
|
@ -836,6 +836,7 @@
|
||||||
<string name="trashbin_empty_message">You will be able to recover deleted files from here.</string>
|
<string name="trashbin_empty_message">You will be able to recover deleted files from here.</string>
|
||||||
<string name="trashbin_file_not_deleted">File %1$s could not be deleted!</string>
|
<string name="trashbin_file_not_deleted">File %1$s could not be deleted!</string>
|
||||||
<string name="trashbin_file_not_restored">File %1$s could not be restored!</string>
|
<string name="trashbin_file_not_restored">File %1$s could not be restored!</string>
|
||||||
|
<string name="trashbin_file_remove">Delete permanently</string>
|
||||||
<string name="trashbin_loading_failed">Loading trash bin failed!</string>
|
<string name="trashbin_loading_failed">Loading trash bin failed!</string>
|
||||||
<string name="trashbin_not_emptied">Files could not be deleted permanently!</string>
|
<string name="trashbin_not_emptied">Files could not be deleted permanently!</string>
|
||||||
<string name="unlock_file">Unlock file</string>
|
<string name="unlock_file">Unlock file</string>
|
||||||
|
|
|
@ -807,6 +807,7 @@
|
||||||
<string name="trashbin_empty_message">Ще можете да възстановите изтритите файлове от тук.</string>
|
<string name="trashbin_empty_message">Ще можете да възстановите изтритите файлове от тук.</string>
|
||||||
<string name="trashbin_file_not_deleted">Файлът %1$s не може да бъде изтрит!</string>
|
<string name="trashbin_file_not_deleted">Файлът %1$s не може да бъде изтрит!</string>
|
||||||
<string name="trashbin_file_not_restored">Файлът %1$s не може да бъде възстановен!</string>
|
<string name="trashbin_file_not_restored">Файлът %1$s не може да бъде възстановен!</string>
|
||||||
|
<string name="trashbin_file_remove">Изтрий завинаги</string>
|
||||||
<string name="trashbin_loading_failed">Зареждането на кошчето е неуспешно!</string>
|
<string name="trashbin_loading_failed">Зареждането на кошчето е неуспешно!</string>
|
||||||
<string name="trashbin_not_emptied">Файловете не могат да бъдат окончателно изтрити!</string>
|
<string name="trashbin_not_emptied">Файловете не могат да бъдат окончателно изтрити!</string>
|
||||||
<string name="unlock_file">Отключване на файл</string>
|
<string name="unlock_file">Отключване на файл</string>
|
||||||
|
|
|
@ -666,6 +666,7 @@
|
||||||
<string name="trashbin_empty_message">Posupl eo deoc\'h adtapout ar restroù lamet adalek al lec\'h mañ</string>
|
<string name="trashbin_empty_message">Posupl eo deoc\'h adtapout ar restroù lamet adalek al lec\'h mañ</string>
|
||||||
<string name="trashbin_file_not_deleted">Ar restr %1$s n\'eo ket evit bezhaãn lamet !</string>
|
<string name="trashbin_file_not_deleted">Ar restr %1$s n\'eo ket evit bezhaãn lamet !</string>
|
||||||
<string name="trashbin_file_not_restored">Ar restr %1$s n\'eo ket evit bezha adlakaet !</string>
|
<string name="trashbin_file_not_restored">Ar restr %1$s n\'eo ket evit bezha adlakaet !</string>
|
||||||
|
<string name="trashbin_file_remove">Lamet da viken</string>
|
||||||
<string name="trashbin_not_emptied">N\'eo ket posupl lemel ar restr da virviken !</string>
|
<string name="trashbin_not_emptied">N\'eo ket posupl lemel ar restr da virviken !</string>
|
||||||
<string name="unlock_file">Dibrennan ar restr</string>
|
<string name="unlock_file">Dibrennan ar restr</string>
|
||||||
<string name="unread_comments">Bez eez eus kemenadennom n\'int ket bet lennet</string>
|
<string name="unread_comments">Bez eez eus kemenadennom n\'int ket bet lennet</string>
|
||||||
|
|
|
@ -796,6 +796,7 @@
|
||||||
<string name="trashbin_empty_message">Des d\'aquí es podran recuperar fitxers suprimits.</string>
|
<string name="trashbin_empty_message">Des d\'aquí es podran recuperar fitxers suprimits.</string>
|
||||||
<string name="trashbin_file_not_deleted">El fitxer %1$s no es pot suprimir!</string>
|
<string name="trashbin_file_not_deleted">El fitxer %1$s no es pot suprimir!</string>
|
||||||
<string name="trashbin_file_not_restored">El fitxer %1$s no es pot restaurar!</string>
|
<string name="trashbin_file_not_restored">El fitxer %1$s no es pot restaurar!</string>
|
||||||
|
<string name="trashbin_file_remove">Suprimeix permanentment</string>
|
||||||
<string name="trashbin_loading_failed">No s\'ha pogut carregar la paperera!</string>
|
<string name="trashbin_loading_failed">No s\'ha pogut carregar la paperera!</string>
|
||||||
<string name="trashbin_not_emptied">Els fitxers no s\'han pogut suprimir permanentment!</string>
|
<string name="trashbin_not_emptied">Els fitxers no s\'han pogut suprimir permanentment!</string>
|
||||||
<string name="unlock_file">Desbloca el fitxer</string>
|
<string name="unlock_file">Desbloca el fitxer</string>
|
||||||
|
|
|
@ -819,6 +819,7 @@ Enheds legitimationsoplysninger er sat op
|
||||||
<string name="trashbin_empty_message">Du vil kunne gendanne slettede filer herfra.</string>
|
<string name="trashbin_empty_message">Du vil kunne gendanne slettede filer herfra.</string>
|
||||||
<string name="trashbin_file_not_deleted">Fil %1$s kunne ikke slettes!</string>
|
<string name="trashbin_file_not_deleted">Fil %1$s kunne ikke slettes!</string>
|
||||||
<string name="trashbin_file_not_restored">Fil %1$s kunne ikke genskabes!</string>
|
<string name="trashbin_file_not_restored">Fil %1$s kunne ikke genskabes!</string>
|
||||||
|
<string name="trashbin_file_remove">Slet permanent</string>
|
||||||
<string name="trashbin_loading_failed">Indlæsning af papirkurv mislykkedes!</string>
|
<string name="trashbin_loading_failed">Indlæsning af papirkurv mislykkedes!</string>
|
||||||
<string name="trashbin_not_emptied">Filer kunne ikke permanent slettes!</string>
|
<string name="trashbin_not_emptied">Filer kunne ikke permanent slettes!</string>
|
||||||
<string name="unlock_file">Lås op filen</string>
|
<string name="unlock_file">Lås op filen</string>
|
||||||
|
|
|
@ -811,6 +811,7 @@
|
||||||
<string name="trashbin_empty_message">Μπορείτε να ανακτήσετε διαγραμμένα αρχεία από εδώ.</string>
|
<string name="trashbin_empty_message">Μπορείτε να ανακτήσετε διαγραμμένα αρχεία από εδώ.</string>
|
||||||
<string name="trashbin_file_not_deleted">Το αρχείο %1$s δεν μπορεί να διαγραφεί!</string>
|
<string name="trashbin_file_not_deleted">Το αρχείο %1$s δεν μπορεί να διαγραφεί!</string>
|
||||||
<string name="trashbin_file_not_restored">Το αρχείο %1$s δεν μπορεί να ανακτηθεί!</string>
|
<string name="trashbin_file_not_restored">Το αρχείο %1$s δεν μπορεί να ανακτηθεί!</string>
|
||||||
|
<string name="trashbin_file_remove">Διαγραφή οριστικά</string>
|
||||||
<string name="trashbin_loading_failed">Αποτυχία φόρτωσης κάδου ανακύκλωσης!</string>
|
<string name="trashbin_loading_failed">Αποτυχία φόρτωσης κάδου ανακύκλωσης!</string>
|
||||||
<string name="trashbin_not_emptied">Τα αρχεία δεν θα διαγραφούν μόνιμα!</string>
|
<string name="trashbin_not_emptied">Τα αρχεία δεν θα διαγραφούν μόνιμα!</string>
|
||||||
<string name="unlock_file">Ξεκλείδωμα αρχείου</string>
|
<string name="unlock_file">Ξεκλείδωμα αρχείου</string>
|
||||||
|
|
Loading…
Reference in a new issue