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

This commit is contained in:
Tobias Kaminsky 2023-10-14 03:36:02 +02:00
commit fb84d03690
22 changed files with 113 additions and 90 deletions

View file

@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
- name: set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
- name: Set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -32,7 +32,7 @@ jobs:
with:
swap-size-gb: 10
- name: Initialize CodeQL
uses: github/codeql-action/init@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1
uses: github/codeql-action/init@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
with:
languages: ${{ matrix.language }}
- name: Set up JDK 17
@ -46,4 +46,4 @@ jobs:
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
./gradlew assembleDebug
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1
uses: github/codeql-action/analyze@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2

View file

@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
- name: Set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
- name: set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
with:
distribution: "temurin"

View file

@ -37,6 +37,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1
uses: github/codeql-action/upload-sarif@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
with:
sarif_file: results.sarif

View file

@ -40,7 +40,7 @@ jobs:
~/.android/adb*
key: avd-${{ matrix.api-level }}
- uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
- uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Set up JDK 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
distribution: "temurin"
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: 180 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -79,6 +79,7 @@ class FileDetailFragmentStaticServerIT : AbstractIT() {
waitForIdleSync()
shortSleep()
shortSleep()
shortSleep()
screenshot(sut)
}

View file

@ -26,6 +26,7 @@ package com.nextcloud.client.preferences;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import com.google.gson.Gson;
import com.nextcloud.appReview.AppReviewShownModel;
@ -437,7 +438,14 @@ public final class AppPreferencesImpl implements AppPreferences {
@Override
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

View file

@ -138,7 +138,7 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
@Override
public void onResume() {
super.onResume();
keyboardUtils.showKeyboardForEditText(binding.filename);
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.filename);
}
@NonNull

View file

@ -119,7 +119,7 @@ class ChooseTemplateDialogFragment : DialogFragment(), View.OnClickListener, Tem
override fun onResume() {
super.onResume()
keyboardUtils.showKeyboardForEditText(binding.filename)
keyboardUtils.showKeyboardForEditText(dialog?.window, binding.filename)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

View file

@ -116,7 +116,7 @@ public class CreateFolderDialogFragment
super.onResume();
bindButton();
keyboardUtils.showKeyboardForEditText(binding.userInput);
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
}
@NonNull

View file

@ -90,7 +90,7 @@ public class NoteDialogFragment extends DialogFragment implements DialogInterfac
@Override
public void onResume() {
super.onResume();
keyboardUtils.showKeyboardForEditText(binding.noteText);
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.noteText);
}
@NonNull

View file

@ -34,8 +34,8 @@ import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
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.common.collect.Sets;
import com.nextcloud.client.di.Injectable;
@ -65,7 +65,7 @@ import androidx.fragment.app.DialogFragment;
* Triggers the rename operation when name is confirmed.
*/
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_PARENT_FOLDER = "PARENT_FOLDER";
@ -76,8 +76,8 @@ public class RenameFileDialogFragment
private EditBoxDialogBinding binding;
private OCFile mTargetFile;
private Button positiveButton;
private MaterialButton positiveButton;
private Set<String> fileNames;
/**
* Public factory method to create new RenameFileDialogFragment instances.
@ -97,20 +97,13 @@ public class RenameFileDialogFragment
@Override
public void onStart() {
super.onStart();
AlertDialog alertDialog = (AlertDialog) getDialog();
if (alertDialog != null) {
positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
viewThemeUtils.platform.colorTextButtons(positiveButton,
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
}
initAlertDialog();
}
@Override
public void onResume() {
super.onResume();
keyboardUtils.showKeyboardForEditText(binding.userInput);
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
}
@NonNull
@ -133,62 +126,46 @@ public class RenameFileDialogFragment
OCFile parentFolder = requireArguments().getParcelable(ARG_PARENT_FOLDER);
List<OCFile> folderContent = fileDataStorageManager.getFolderContent(parentFolder, false);
Set<String> fileNames = Sets.newHashSetWithExpectedSize(folderContent.size());
fileNames = Sets.newHashSetWithExpectedSize(folderContent.size());
for (OCFile file : folderContent) {
fileNames.add(file.getFileName());
}
// Add TextChangedListener to handle showing/hiding the input warning message
binding.userInput.addTextChangedListener(new TextWatcher() {
@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);
}
}
});
binding.userInput.addTextChangedListener(this);
// Build the dialog
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
builder.setView(view)
.setPositiveButton(R.string.file_rename, this)
.setNeutralButton(R.string.common_cancel, this)
.setTitle(R.string.rename_dialog_title);
MaterialAlertDialogBuilder builder = buildMaterialAlertDialog(view);
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.userInputContainer.getContext(), builder);
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
public void onClick(DialogInterface dialog, int which) {
@ -219,4 +196,41 @@ public class RenameFileDialogFragment
super.onDestroyView();
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) {
}
}

View file

@ -83,7 +83,7 @@ public class RenamePublicShareDialogFragment
@Override
public void onResume() {
super.onResume();
keyboardUtils.showKeyboardForEditText(binding.userInput);
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.userInput);
}
@NonNull

View file

@ -99,7 +99,7 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
@Override
public void onResume() {
super.onResume();
keyboardUtils.showKeyboardForEditText(binding.sharePassword);
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.sharePassword);
}
/**

View file

@ -1,7 +1,9 @@
/*
* Nextcloud Android client application
*
* @author ZetaTom
* @author Álvaro Brey
* Copyright (C) 2023 ZetaTom
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
@ -22,26 +24,18 @@
package com.owncloud.android.utils
import android.content.Context
import android.view.inputmethod.InputMethodManager
import android.view.Window
import android.widget.EditText
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import javax.inject.Inject
class KeyboardUtils @Inject constructor() {
fun showKeyboardForEditText(editText: EditText) {
fun showKeyboardForEditText(window: Window?, editText: EditText) {
if (window != null) {
editText.requestFocus()
// needs 100ms delay to account for focus animations
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)
WindowCompat.getInsetsController(window, editText).show(WindowInsetsCompat.Type.ime())
}
}, SHOW_INPUT_DELAY_MILLIS)
}
companion object {
private const val SHOW_INPUT_DELAY_MILLIS = 100L
}
}

View file

@ -251,9 +251,9 @@
<string name="e2e_not_yet_setup">Celovito šifriranje E2E ni še nastavljeno.</string>
<string name="e2e_offline">Opravila ni mogoče izvesti brez vzpostavljene internetne povezave</string>
<string name="ecosystem_apps_display_more">Več</string>
<string name="ecosystem_apps_display_notes">Opombe</string>
<string name="ecosystem_apps_display_talk">Pogovor</string>
<string name="ecosystem_apps_notes">Nextcloud Notes</string>
<string name="ecosystem_apps_display_notes">Beležke</string>
<string name="ecosystem_apps_display_talk">Pogovor Talk</string>
<string name="ecosystem_apps_notes">Nextcloud Beležke</string>
<string name="encrypted">Nastavi kot šifrirano</string>
<string name="end_to_end_encryption_confirm_button">Nastavitev šifriranja</string>
<string name="end_to_end_encryption_decrypting">Poteka odšifriranje…</string>
@ -413,6 +413,8 @@
<string name="icon_for_empty_list">Ikona za prazen seznam</string>
<string name="icon_of_dashboard_widget">Ikona gradnika nadzorne plošče</string>
<string name="icon_of_widget_entry">Ikona vnosa gradnikov</string>
<string name="image_editor_unable_to_edit_image">Slike ni mogoče urediti.</string>
<string name="image_preview_filedetails">Podrobnosti datoteke</string>
<string name="image_preview_unit_fnumber">ƒ/%s</string>
<string name="image_preview_unit_iso">ISO %s</string>
<string name="image_preview_unit_megapixel">%s MP</string>
@ -584,6 +586,7 @@
<string name="prefs_instant_behaviour_dialogTitle">Izvorna datoteka bo…</string>
<string name="prefs_instant_behaviour_title">Izvorna datoteka bo…</string>
<string name="prefs_instant_upload_path_use_subfolders_title">Uporabi podmape</string>
<string name="prefs_instant_upload_subfolder_rule_title">Možnosti podmape</string>
<string name="prefs_keys_exist">Dodaj celovito šifriranje E2E na to napravo</string>
<string name="prefs_license">Dovoljenje</string>
<string name="prefs_lock">Koda PIN programa</string>
@ -597,6 +600,7 @@
<string name="prefs_recommend">Priporoči prijatelju</string>
<string name="prefs_remove_e2e">Krajevno odstrani šifriranje</string>
<string name="prefs_setup_e2e">Nastavi celovito šifriranje E2E</string>
<string name="prefs_show_ecosystem_apps">Pokaži preklopnika programov</string>
<string name="prefs_show_hidden_files">Pokaži skrite datoteke</string>
<string name="prefs_sourcecode">Pridobi izvorno kodo</string>
<string name="prefs_storage_path">Mapa podatkovne shrambe</string>
@ -768,6 +772,8 @@
<string name="stream_not_possible_headline">Notranji pretok ni mogoč</string>
<string name="stream_not_possible_message">Poskusite prejeti predstavno vsebino, ali pa uporabiti zunanji program.</string>
<string name="strict_mode">Strogi način: povezave HTTP niso dovoljene!</string>
<string name="sub_folder_rule_day">Leto/Mesec/Dan</string>
<string name="sub_folder_rule_month">Leto/Mesec</string>
<string name="sub_folder_rule_year">Leto</string>
<string name="subject_shared_with_you">\"%1$s\" vam je oddan v souporabo</string>
<string name="subject_user_shared_with_you">Uporabnik %1$s je omogočil souporabo \"%2$s\"</string>