Merge remote-tracking branch 'origin/feature/use-m3-files-export-notification' into feature/use-m3-files-export-notification

# Conflicts:
#	app/src/main/java/com/nextcloud/client/jobs/FilesExportWork.kt
This commit is contained in:
alperozturk 2023-10-20 13:40:24 +02:00
commit 5ec7f8df52
No known key found for this signature in database
GPG key ID: 4E577DC593B59BDF
32 changed files with 254 additions and 1082 deletions

View file

@ -33,7 +33,7 @@ jobs:
echo "pr=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
echo "repo=${{ github.event.pull_request.head.repo.full_name }}" >> "$GITHUB_OUTPUT"
fi
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
repository: ${{ steps.get-vars.outputs.repo }}
ref: ${{ steps.get-vars.outputs.branch }}

View file

@ -26,7 +26,7 @@ jobs:
language: [ 'java' ]
steps:
- name: Checkout repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Set Swap Space
uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0
with:

View file

@ -18,5 +18,5 @@ jobs:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # v1.1.0

View file

@ -24,7 +24,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
persist-credentials: false

View file

@ -15,11 +15,17 @@ height="80">](https://f-droid.org/packages/com.nextcloud.client/)
## How to contribute :rocket:
If you want to [contribute](https://nextcloud.com/contribute/) to Nextcloud, you are very welcome:
If you want to [contribute](https://nextcloud.com/contribute/) to the Nextcloud Android client app, there are many ways to help whether or not you are a coder:
* our forum at https://help.nextcloud.com
* for translations of the app on [Transifex](https://app.transifex.com/nextcloud/nextcloud/android/)
* opening issues and PRs (including a corresponding issue)
* helping out other users on our forum at https://help.nextcloud.com
* providing translations of the app on [Transifex](https://app.transifex.com/nextcloud/nextcloud/android/)
* reporting problems / suggesting enhancements by [opening new issues](https://github.com/nextcloud/android/issues/new/choose)
* implementing proposed bug fixes and enhancement ideas by submitting PRs (associated with a corresponding issue preferably)
* reviewing [pull requests](https://github.com/nextcloud/android/pulls) and providing feedback on code, implementation, and functionality
* installing and testing [pull request builds](https://github.com/nextcloud/android/pulls), [daily/dev builds](https://github.com/nextcloud/android#development-version-hammer), or [RCs/release candidate builds](https://github.com/nextcloud/android/releases)
* enhancing Admin, User, or Developer [documentation](https://github.com/nextcloud/documentation/)
* hitting hard on the latest stable release by testing fundamental features and evaluating the user experience
* proactively getting familiar with [how to gather debug logs](https://github.com/nextcloud/android#getting-debug-info-via-logcat-mag) from your devices (so that you are prepared to provide a detailed report if you encounter a problem with the app in the future)
## Contribution Guidelines & License :scroll:
@ -38,7 +44,7 @@ More information on how to contribute: <https://nextcloud.com/contribute/>
## Start contributing :hammer\_and\_wrench:
Make sure you read [SETUP.md](https://github.com/nextcloud/android/blob/master/SETUP.md) and [CONTRIBUTING.md](https://github.com/nextcloud/android/blob/master/CONTRIBUTING.md) before you start working on this project. But basically: fork this repository and contribute back using pull requests to the master branch.
Easy starting points are also reviewing [pull requests](https://github.com/nextcloud/android/pulls) and working on [starter issues](https://github.com/nextcloud/android/issues?q=is%3Aopen+is%3Aissue+label%3A%22starter+issue%22).
Easy starting points are also reviewing [pull requests](https://github.com/nextcloud/android/pulls) and working on [starter issues](https://github.com/nextcloud/android/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
### Getting debug info via logcat :mag:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 6.5 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: 5.5 KiB

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -73,14 +73,19 @@ class FileDetailFragmentStaticServerIT : AbstractIT() {
@Test
@ScreenshotTest
fun showFileDetailDetailsFragment() {
val sut = testActivityRule.launchActivity(null)
sut.addFragment(ImageDetailFragment.newInstance(oCFile, user))
val activity = testActivityRule.launchActivity(null)
val sut = ImageDetailFragment.newInstance(oCFile, user)
activity.addFragment(sut)
shortSleep()
shortSleep()
waitForIdleSync()
shortSleep()
shortSleep()
shortSleep()
screenshot(sut)
activity.runOnUiThread {
sut.hideMap()
}
screenshot(activity)
}
@Test
@ -182,6 +187,7 @@ class FileDetailFragmentStaticServerIT : AbstractIT() {
waitForIdleSync()
activity.runOnUiThread {
sut.fileDetailActivitiesFragment.disableLoadingActivities()
sut
.fileDetailActivitiesFragment
.setErrorContent(targetContext.resources.getString(R.string.file_detail_activity_error))

View file

@ -92,7 +92,6 @@ import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
import com.owncloud.android.ui.dialog.LoadingDialog;
import com.owncloud.android.ui.dialog.LocalStoragePathPickerDialogFragment;
import com.owncloud.android.ui.dialog.MultipleAccountsDialog;
import com.owncloud.android.ui.dialog.NoteDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
import com.owncloud.android.ui.dialog.RenamePublicShareDialogFragment;
@ -404,9 +403,6 @@ abstract class ComponentsModule {
@ContributesAndroidInjector
abstract Migrations migrations();
@ContributesAndroidInjector
abstract NoteDialogFragment noteDialogFragment();
@ContributesAndroidInjector
abstract NotificationWork notificationWork();

View file

@ -30,6 +30,7 @@ import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.nextcloud.android.common.ui.theme.utils.ColorRole
@ -260,6 +261,11 @@ class ImageDetailFragment : Fragment(), Injectable {
binding.imageLocationMapCopyright.text = binding.imageLocationMap.tileProvider.tileSource.copyrightNotice
}
@VisibleForTesting
fun hideMap() {
binding.imageLocationMap.visibility = View.GONE
}
@SuppressLint("SimpleDateFormat")
private fun gatherMetadata() {
val fileSize = DisplayUtils.bytesToHumanReadable(file.fileLength)

View file

@ -25,6 +25,7 @@ package com.owncloud.android.ui.dialog;
import android.app.Dialog;
import android.os.Bundle;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.nextcloud.client.account.User;
import com.nextcloud.client.di.Injectable;
@ -59,7 +60,11 @@ public class AccountRemovalConfirmationDialog extends DialogFragment implements
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
user = getArguments().getParcelable(KEY_USER);
Bundle arguments = getArguments();
if (arguments != null) {
user = arguments.getParcelable(KEY_USER);
}
}
@Override
@ -67,9 +72,18 @@ public class AccountRemovalConfirmationDialog extends DialogFragment implements
super.onStart();
AlertDialog alertDialog = (AlertDialog) getDialog();
if (alertDialog != null) {
viewThemeUtils.platform.colorTextButtons(alertDialog.getButton(AlertDialog.BUTTON_POSITIVE),
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
MaterialButton positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
if (positiveButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
}
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
if (negativeButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
}
}
}
@NonNull
@ -82,7 +96,7 @@ public class AccountRemovalConfirmationDialog extends DialogFragment implements
.setPositiveButton(R.string.common_ok,
(dialogInterface, i) -> backgroundJobManager.startAccountRemovalJob(user.getAccountName(),
false))
.setNeutralButton(R.string.common_cancel, null);
.setNegativeButton(R.string.common_cancel, null);
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(requireActivity(), builder);

View file

@ -35,6 +35,7 @@ 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.account.CurrentAccountProvider;
@ -99,7 +100,7 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
private RichDocumentsTemplateAdapter adapter;
private OCFile parentFolder;
private OwnCloudClient client;
private Button positiveButton;
private MaterialButton positiveButton;
private DialogFragment waitDialog;
public enum Type {
@ -126,11 +127,18 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
AlertDialog alertDialog = (AlertDialog) getDialog();
positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
viewThemeUtils.platform.colorTextButtons(positiveButton,
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
positiveButton.setOnClickListener(this);
positiveButton.setEnabled(false);
if (alertDialog != null) {
positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
if (negativeButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
}
positiveButton.setOnClickListener(this);
positiveButton.setEnabled(false);
}
checkEnablingCreateButton();
}
@ -205,12 +213,14 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
}
});
int titleTextId = getTitle(type);
// Build the dialog
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.setView(view)
.setPositiveButton(R.string.create, null)
.setNeutralButton(R.string.common_cancel, null)
.setTitle(getTitle(type));
.setNegativeButton(R.string.common_cancel, null)
.setTitle(titleTextId);
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(activity, builder);

View file

@ -31,6 +31,7 @@ import android.view.View;
import android.widget.Button;
import android.widget.TextView;
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;
@ -71,7 +72,7 @@ public class CreateFolderDialogFragment
private OCFile mParentFolder;
private Button positiveButton;
private MaterialButton positiveButton;
private EditBoxDialogBinding binding;
@ -101,13 +102,11 @@ public class CreateFolderDialogFragment
private void bindButton() {
Dialog dialog = getDialog();
if (dialog instanceof AlertDialog) {
AlertDialog alertDialog = (AlertDialog) dialog;
positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
viewThemeUtils.platform.colorTextButtons(positiveButton,
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
if (dialog instanceof AlertDialog alertDialog) {
positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
}
}
@ -186,17 +185,25 @@ public class CreateFolderDialogFragment
});
// Build the dialog
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
builder.setView(view)
.setPositiveButton(R.string.folder_confirm_create, this)
.setNeutralButton(R.string.common_cancel, this)
.setTitle(R.string.uploader_info_dirname);
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.folder_confirm_create, this)
.setNegativeButton(R.string.common_cancel, this)
.setTitle(R.string.uploader_info_dirname);
return builder;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {

View file

@ -30,6 +30,7 @@ import android.os.Bundle;
import android.text.format.DateUtils;
import android.widget.DatePicker;
import com.google.android.material.button.MaterialButton;
import com.nextcloud.client.di.Injectable;
import com.owncloud.android.R;
import com.owncloud.android.utils.theme.ViewThemeUtils;
@ -81,12 +82,24 @@ public class ExpirationDatePickerDialogFragment
public void onStart() {
super.onStart();
final Dialog currentDialog = getDialog();
if (currentDialog != null) {
final DatePickerDialog dialog = (DatePickerDialog) currentDialog;
viewThemeUtils.platform.colorTextButtons(dialog.getButton(DatePickerDialog.BUTTON_NEUTRAL),
dialog.getButton(DatePickerDialog.BUTTON_NEGATIVE),
dialog.getButton(DatePickerDialog.BUTTON_POSITIVE));
MaterialButton positiveButton = (MaterialButton) dialog.getButton(DatePickerDialog.BUTTON_POSITIVE);
if (positiveButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
}
MaterialButton negativeButton = (MaterialButton) dialog.getButton(DatePickerDialog.BUTTON_NEGATIVE);
if (negativeButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
}
MaterialButton neutralButton = (MaterialButton) dialog.getButton(DatePickerDialog.BUTTON_NEUTRAL);
if (neutralButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(neutralButton);
}
}
}
@ -118,7 +131,7 @@ public class ExpirationDatePickerDialogFragment
//show unset button only when date is already selected
if (chosenDateInMillis > 0) {
dialog.setButton(
Dialog.BUTTON_NEUTRAL,
Dialog.BUTTON_NEGATIVE,
getText(R.string.share_via_link_unset_password),
(dialog1, which) -> {
if (onExpiryDateListener != null) {

View file

@ -1,144 +0,0 @@
/*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2018 Tobias Kaminsky
* Copyright (C) 2018 Nextcloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.dialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.nextcloud.client.di.Injectable;
import com.owncloud.android.R;
import com.owncloud.android.databinding.NoteDialogBinding;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.ui.activity.ComponentsGetter;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.KeyboardUtils;
import com.owncloud.android.utils.theme.ViewThemeUtils;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
/**
* Dialog to input a multiline note for a share
*/
public class NoteDialogFragment extends DialogFragment implements DialogInterface.OnClickListener, Injectable {
private static final String ARG_SHARE = "SHARE";
@Inject ViewThemeUtils viewThemeUtils;
@Inject KeyboardUtils keyboardUtils;
private OCShare share;
private NoteDialogBinding binding;
public static NoteDialogFragment newInstance(OCShare share) {
NoteDialogFragment frag = new NoteDialogFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_SHARE, share);
frag.setArguments(args);
return frag;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() == null) {
throw new IllegalArgumentException("Arguments may not be null");
}
share = getArguments().getParcelable(ARG_SHARE);
}
@Override
public void onStart() {
super.onStart();
AlertDialog alertDialog = (AlertDialog) getDialog();
viewThemeUtils.platform.colorTextButtons(alertDialog.getButton(AlertDialog.BUTTON_POSITIVE),
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
}
@Override
public void onResume() {
super.onResume();
keyboardUtils.showKeyboardForEditText(requireDialog().getWindow(), binding.noteText);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Inflate the layout for the dialog
LayoutInflater inflater = requireActivity().getLayoutInflater();
binding = NoteDialogBinding.inflate(inflater, null, false);
View view = binding.getRoot();
// Setup layout
binding.noteText.setText(share.getNote());
viewThemeUtils.material.colorTextInputLayout(binding.noteContainer);
// Build the dialog
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(binding.noteContainer.getContext());
builder.setView(view)
.setPositiveButton(R.string.note_confirm, this)
.setNeutralButton(R.string.common_cancel, this)
.setTitle(R.string.send_note);
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.noteContainer.getContext(), builder);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
ComponentsGetter componentsGetter = (ComponentsGetter) getActivity();
if (componentsGetter != null) {
String note = "";
if (binding.noteText.getText() != null) {
note = binding.noteText.getText().toString().trim();
}
componentsGetter.getFileOperationsHelper().updateNoteToShare(share, note);
} else {
DisplayUtils.showSnackMessage(requireActivity(), R.string.note_could_not_sent);
}
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View file

@ -23,6 +23,7 @@ import android.app.Dialog;
import android.os.Bundle;
import android.view.ActionMode;
import com.google.android.material.button.MaterialButton;
import com.nextcloud.client.di.Injectable;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
@ -96,15 +97,20 @@ public class RemoveFilesDialogFragment extends ConfirmationDialogFragment implem
R.string.confirmation_remove_files_alert;
}
int localRemoveButton = (containsFolder || containsDown) ? R.string.confirmation_remove_local : -1;
args.putInt(ARG_MESSAGE_RESOURCE_ID, messageStringId);
if (files.size() == SINGLE_SELECTION) {
args.putStringArray(ARG_MESSAGE_ARGUMENTS, new String[]{files.get(0).getFileName()});
args.putStringArray(ARG_MESSAGE_ARGUMENTS, new String[] { files.get(0).getFileName() } );
}
args.putInt(ARG_POSITIVE_BTN_RES, R.string.file_delete);
args.putInt(ARG_NEUTRAL_BTN_RES, R.string.file_keep);
args.putInt(ARG_NEGATIVE_BTN_RES, localRemoveButton);
if (containsFolder || containsDown) {
args.putInt(ARG_NEGATIVE_BTN_RES, R.string.confirmation_remove_local);
args.putInt(ARG_NEUTRAL_BTN_RES, R.string.file_keep);
} else {
args.putInt(ARG_NEGATIVE_BTN_RES, R.string.file_keep);
}
args.putParcelableArrayList(ARG_TARGET_FILES, files);
frag.setArguments(args);
@ -131,9 +137,16 @@ public class RemoveFilesDialogFragment extends ConfirmationDialogFragment implem
AlertDialog alertDialog = (AlertDialog) getDialog();
if (alertDialog != null) {
viewThemeUtils.platform.colorTextButtons(alertDialog.getButton(AlertDialog.BUTTON_POSITIVE),
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE),
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
MaterialButton positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
MaterialButton neutralButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL);
if (neutralButton != null) {
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(neutralButton);
}
}
}
@ -141,10 +154,14 @@ public class RemoveFilesDialogFragment extends ConfirmationDialogFragment implem
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
mTargetFiles = getArguments().getParcelableArrayList(ARG_TARGET_FILES);
Bundle arguments = getArguments();
if (arguments == null) {
return dialog;
}
mTargetFiles = arguments.getParcelableArrayList(ARG_TARGET_FILES);
setOnConfirmationListener(this);
return dialog;
}
@ -154,9 +171,7 @@ public class RemoveFilesDialogFragment extends ConfirmationDialogFragment implem
*/
@Override
public void onConfirmation(String callerTag) {
ComponentsGetter cg = (ComponentsGetter) getActivity();
cg.getFileOperationsHelper().removeFiles(mTargetFiles, false, false);
finishActionMode();
removeFiles(false);
}
/**
@ -164,8 +179,14 @@ public class RemoveFilesDialogFragment extends ConfirmationDialogFragment implem
*/
@Override
public void onCancel(String callerTag) {
removeFiles(true);
}
private void removeFiles(boolean onlyLocalCopy) {
ComponentsGetter cg = (ComponentsGetter) getActivity();
cg.getFileOperationsHelper().removeFiles(mTargetFiles, true, false);
if (cg != null) {
cg.getFileOperationsHelper().removeFiles(mTargetFiles, onlyLocalCopy, false);
}
finishActionMode();
}

View file

@ -28,6 +28,7 @@ import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.nextcloud.client.di.Injectable;
import com.owncloud.android.R;
@ -52,8 +53,6 @@ public class RenamePublicShareDialogFragment
private static final String ARG_PUBLIC_SHARE = "PUBLIC_SHARE";
public static final String RENAME_PUBLIC_SHARE_FRAGMENT = "RENAME_PUBLIC_SHARE_FRAGMENT";
@Inject ViewThemeUtils viewThemeUtils;
@Inject KeyboardUtils keyboardUtils;
@ -75,8 +74,10 @@ public class RenamePublicShareDialogFragment
AlertDialog alertDialog = (AlertDialog) getDialog();
if (alertDialog != null) {
viewThemeUtils.platform.colorTextButtons(alertDialog.getButton(AlertDialog.BUTTON_POSITIVE),
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL));
MaterialButton positiveButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
MaterialButton negativeButton = (MaterialButton) alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton);
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton);
}
}
@ -104,7 +105,7 @@ public class RenamePublicShareDialogFragment
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(view.getContext());
builder.setView(view)
.setPositiveButton(R.string.file_rename, this)
.setNeutralButton(R.string.common_cancel, this)
.setNegativeButton(R.string.common_cancel, this)
.setTitle(R.string.public_share_name);
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.userInput.getContext(), builder);

View file

@ -1,329 +0,0 @@
/**
* ownCloud Android client application
*
* @author David A. Velasco
* Copyright (C) 2015 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.dialog;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import com.owncloud.android.R;
import com.owncloud.android.databinding.SslValidatorLayoutBinding;
import com.owncloud.android.lib.common.network.CertificateCombinedException;
import com.owncloud.android.lib.common.network.NetworkUtils;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
/**
* Dialog to request the user about a certificate that could not be validated with the certificates store in the system.
*/
public class SslValidatorDialog extends Dialog {
private final static String TAG = SslValidatorDialog.class.getSimpleName();
private OnSslValidatorListener mListener;
private CertificateCombinedException mException;
private SslValidatorLayoutBinding binding;
/**
* Creates a new SslValidatorDialog to ask the user if an untrusted certificate from a server should
* be trusted.
*
* @param context Android context where the dialog will live.
* @param result Result of a failed remote operation.
* @param listener Object to notice when the server certificate was added to the local certificates store.
* @return A new SslValidatorDialog instance. NULL if the operation can not be recovered
* by setting the certificate as reliable.
*/
public static SslValidatorDialog newInstance(Context context, RemoteOperationResult result, OnSslValidatorListener listener) {
if (result != null && result.isSslRecoverableException()) {
return new SslValidatorDialog(context, listener);
} else {
return null;
}
}
/**
* Private constructor.
*
* Instances have to be created through static {@link SslValidatorDialog#newInstance}.
*
* @param context Android context where the dialog will live
* @param listener Object to notice when the server certificate was added to the local certificates store.
*/
private SslValidatorDialog(Context context, OnSslValidatorListener listener) {
super(context);
mListener = listener;
}
/**
* {@inheritDoc}
*/
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
binding = SslValidatorLayoutBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.ok.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
saveServerCert();
dismiss();
if (mListener != null) {
mListener.onSavedCertificate();
} else {
Log_OC.d(TAG, "Nobody there to notify the certificate was saved");
}
} catch (GeneralSecurityException | IOException e) {
dismiss();
if (mListener != null) {
mListener.onFailedSavingCertificate();
}
Log_OC.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
}
}
});
binding.cancel.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
cancel();
}
});
binding.detailsBtn.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
View detailsScroll = findViewById(R.id.details_scroll);
if (detailsScroll.getVisibility() == View.VISIBLE) {
detailsScroll.setVisibility(View.GONE);
((Button) v).setText(R.string.ssl_validator_btn_details_see);
} else {
detailsScroll.setVisibility(View.VISIBLE);
((Button) v).setText(R.string.ssl_validator_btn_details_hide);
}
}
});
}
public void updateResult(RemoteOperationResult result) {
if (result.isSslRecoverableException()) {
mException = (CertificateCombinedException) result.getException();
/// clean
binding.reasonCertNotTrusted.setVisibility(View.GONE);
binding.reasonCertExpired.setVisibility(View.GONE);
binding.reasonCertNotYetValid.setVisibility(View.GONE);
binding.reasonHostnameNotVerified.setVisibility(View.GONE);
binding.detailsScroll.setVisibility(View.GONE);
/// refresh
if (mException.getCertPathValidatorException() != null) {
binding.reasonCertNotTrusted.setVisibility(View.VISIBLE);
}
if (mException.getCertificateExpiredException() != null) {
binding.reasonCertExpired.setVisibility(View.VISIBLE);
}
if (mException.getCertificateNotYetValidException() != null) {
binding.reasonCertNotYetValid.setVisibility(View.VISIBLE);
}
if (mException.getSslPeerUnverifiedException() != null ) {
binding.reasonHostnameNotVerified.setVisibility(View.VISIBLE);
}
showCertificateData(mException.getServerCertificate());
}
}
private void showCertificateData(X509Certificate cert) {
if (cert != null) {
showSubject(cert.getSubjectX500Principal());
showIssuer(cert.getIssuerX500Principal());
showValidity(cert.getNotBefore(), cert.getNotAfter());
showSignature(cert);
} else {
// this should not happen, TODO
Log_OC.d("certNull", "This should not happen");
}
}
private void showSignature(X509Certificate cert) {
binding.valueSignature.setText(getHex(cert.getSignature()));
binding.valueSignatureAlgorithm.setText(cert.getSigAlgName());
}
public String getHex(final byte [] raw) {
if (raw == null) {
return null;
}
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
final int hiVal = (b & 0xF0) >> 4;
final int loVal = b & 0x0F;
hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7))));
hex.append((char) ('0' + (loVal + (loVal / 10 * 7))));
}
return hex.toString();
}
@SuppressWarnings("deprecation")
private void showValidity(Date notBefore, Date notAfter) {
binding.valueValidityFrom.setText(notBefore.toLocaleString());
binding.valueValidityTo.setText(notAfter.toLocaleString());
}
private void showSubject(X500Principal subject) {
Map<String, String> s = parsePrincipal(subject);
if (s.get("CN") != null) {
binding.valueSubjectCN.setText(s.get("CN"));
binding.valueSubjectCN.setVisibility(View.VISIBLE);
} else {
binding.valueSubjectCN.setVisibility(View.GONE);
}
if (s.get("O") != null) {
binding.valueSubjectO.setText(s.get("O"));
binding.valueSubjectO.setVisibility(View.VISIBLE);
} else {
binding.valueSubjectO.setVisibility(View.GONE);
}
if (s.get("OU") != null) {
binding.valueSubjectOU.setText(s.get("OU"));
binding.valueSubjectOU.setVisibility(View.VISIBLE);
} else {
binding.valueSubjectOU.setVisibility(View.GONE);
}
if (s.get("C") != null) {
binding.valueSubjectC.setText(s.get("C"));
binding.valueSubjectC.setVisibility(View.VISIBLE);
} else {
binding.valueSubjectC.setVisibility(View.GONE);
}
if (s.get("ST") != null) {
binding.valueSubjectST.setText(s.get("ST"));
binding.valueSubjectST.setVisibility(View.VISIBLE);
} else {
binding.valueSubjectST.setVisibility(View.GONE);
}
if (s.get("L") != null) {
binding.valueSubjectL.setText(s.get("L"));
binding.valueSubjectL.setVisibility(View.VISIBLE);
} else {
binding.valueSubjectL.setVisibility(View.GONE);
}
}
private void showIssuer(X500Principal issuer) {
Map<String, String> s = parsePrincipal(issuer);
if (s.get("CN") != null) {
binding.valueIssuerCN.setText(s.get("CN"));
binding.valueIssuerCN.setVisibility(View.VISIBLE);
} else {
binding.valueIssuerCN.setVisibility(View.GONE);
}
if (s.get("O") != null) {
binding.valueIssuerO.setText(s.get("O"));
binding.valueIssuerO.setVisibility(View.VISIBLE);
} else {
binding.valueIssuerO.setVisibility(View.GONE);
}
if (s.get("OU") != null) {
binding.valueIssuerOU.setText(s.get("OU"));
binding.valueIssuerOU.setVisibility(View.VISIBLE);
} else {
binding.valueIssuerOU.setVisibility(View.GONE);
}
if (s.get("C") != null) {
binding.valueIssuerC.setText(s.get("C"));
binding.valueIssuerC.setVisibility(View.VISIBLE);
} else {
binding.valueIssuerC.setVisibility(View.GONE);
}
if (s.get("ST") != null) {
binding.valueIssuerST.setText(s.get("ST"));
binding.valueIssuerST.setVisibility(View.VISIBLE);
} else {
binding.valueIssuerST.setVisibility(View.GONE);
}
if (s.get("L") != null) {
binding.valueIssuerL.setText(s.get("L"));
binding.valueIssuerL.setVisibility(View.VISIBLE);
} else {
binding.valueIssuerL.setVisibility(View.GONE);
}
}
private Map<String, String> parsePrincipal(X500Principal principal) {
Map<String, String> result = new HashMap<>();
String toParse = principal.getName();
String[] pieces = toParse.split(",");
String[] tokens = {"CN", "O", "OU", "C", "ST", "L"};
for (String piece : pieces) {
for (String token : tokens) {
if (piece.startsWith(token + "=")) {
result.put(token, piece.substring(token.length() + 1));
}
}
}
return result;
}
private void saveServerCert() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
if (mException.getServerCertificate() != null) {
// TODO make this asynchronously, it can take some time
NetworkUtils.addCertToKnownServersStore(mException.getServerCertificate(), getContext());
}
}
public interface OnSslValidatorListener {
public void onSavedCertificate();
public void onFailedSavingCertificate();
}
}

View file

@ -24,15 +24,14 @@ import android.app.Dialog
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.nextcloud.client.di.Injectable
import com.owncloud.android.R
import com.owncloud.android.databinding.StoragePermissionDialogBinding
import com.owncloud.android.utils.theme.ViewThemeUtils
import kotlinx.parcelize.Parcelize
import javax.inject.Inject
@ -43,10 +42,7 @@ import javax.inject.Inject
* Allows choosing "full access" (MANAGE_ALL_FILES) or "read-only media" (READ_EXTERNAL_STORAGE)
*/
@RequiresApi(Build.VERSION_CODES.R)
class StoragePermissionDialogFragment :
DialogFragment(), Injectable {
private lateinit var binding: StoragePermissionDialogBinding
class StoragePermissionDialogFragment : DialogFragment(), Injectable {
private var permissionRequired = false
@ -64,51 +60,48 @@ class StoragePermissionDialogFragment :
super.onStart()
dialog?.let {
val alertDialog = it as AlertDialog
viewThemeUtils.platform.colorTextButtons(alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE))
val positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE) as MaterialButton
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(positiveButton)
val negativeButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE) as MaterialButton
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(negativeButton)
val neutralButton = alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL) as MaterialButton
viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(neutralButton)
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Inflate the layout for the dialog
val inflater = requireActivity().layoutInflater
binding = StoragePermissionDialogBinding.inflate(inflater, null, false)
val view: View = binding.root
val title = when {
permissionRequired -> R.string.file_management_permission
else -> R.string.file_management_permission_optional
}
val explanationResource = when {
permissionRequired -> R.string.file_management_permission_text
else -> R.string.file_management_permission_optional_text
}
binding.storagePermissionExplanation.text = getString(explanationResource, getString(R.string.app_name))
val message = getString(explanationResource, getString(R.string.app_name))
// Setup layout
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.btnFullAccess)
binding.btnFullAccess.setOnClickListener {
setResult(Result.FULL_ACCESS)
dismiss()
}
viewThemeUtils.platform.colorTextButtons(binding.btnReadOnly)
binding.btnReadOnly.setOnClickListener {
setResult(Result.MEDIA_READ_ONLY)
dismiss()
}
// Build the dialog
val titleResource = when {
permissionRequired -> R.string.file_management_permission
else -> R.string.file_management_permission_optional
}
val builder = MaterialAlertDialogBuilder(binding.btnReadOnly.context)
.setTitle(titleResource)
.setView(view)
.setNegativeButton(R.string.common_cancel) { _, _ ->
val dialogBuilder = MaterialAlertDialogBuilder(requireContext())
.setTitle(title)
.setMessage(message)
.setPositiveButton(R.string.storage_permission_full_access) { _, _ ->
setResult(Result.FULL_ACCESS)
dismiss()
}
.setNegativeButton(R.string.storage_permission_media_read_only) { _, _ ->
setResult(Result.MEDIA_READ_ONLY)
dismiss()
}
.setNeutralButton(R.string.common_cancel) { _, _ ->
setResult(Result.CANCEL)
dismiss()
}
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.btnReadOnly.context, builder)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(requireContext(), dialogBuilder)
return builder.create()
return dialogBuilder.create()
}
private fun setResult(result: Result) {

View file

@ -285,6 +285,10 @@ public class FileDetailActivitiesFragment extends Fragment implements
return;
}
if (!isLoadingActivities) {
return;
}
Thread t = new Thread(() -> {
try {
ownCloudClient = clientFactory.create(user);
@ -455,6 +459,11 @@ public class FileDetailActivitiesFragment extends Fragment implements
return false;
}
@VisibleForTesting
public void disableLoadingActivities() {
isLoadingActivities = false;
}
private static class SubmitCommentTask extends AsyncTask<Void, Void, Boolean> {
private final String message;

View file

@ -1,443 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2015 ownCloud Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2,
as published by the Free Software Foundation.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/standard_padding">
<TextView
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_header"
android:paddingBottom="@dimen/standard_padding"
android:textStyle="bold"
android:textColor="@color/text_color"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/reason_cert_not_trusted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingStart="@dimen/standard_half_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/ssl_validator_reason_cert_not_trusted"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/reason_cert_expired"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingStart="@dimen/standard_half_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/ssl_validator_reason_cert_expired"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/reason_cert_not_yet_valid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingStart="@dimen/standard_half_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/ssl_validator_reason_cert_not_yet_valid"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/reason_hostname_not_verified"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingStart="@dimen/standard_half_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/ssl_validator_reason_hostname_not_verified"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<ScrollView
android:id="@+id/details_scroll"
android:visibility="gone"
android:padding="@dimen/standard_half_padding"
android:layout_width="wrap_content"
android:layout_height="@dimen/scroll_view_height">
<LinearLayout
android:id="@+id/details_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:orientation="vertical" >
<TextView
android:id="@+id/label_subject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text="@string/ssl_validator_label_subject"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/label_subject_CN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_CN"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_subject_CN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_subject_O"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_O"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_subject_O"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_subject_OU"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_OU"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_subject_OU"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_subject_ST"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_ST"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_subject_ST"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_subject_C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_C"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_subject_C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_subject_L"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_L"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_subject_L"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_issuer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text="@string/ssl_validator_label_issuer"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/label_issuer_CN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_CN"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_issuer_CN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_issuer_O"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_O"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_issuer_O"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_issuer_OU"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_OU"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_issuer_OU"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_issuer_ST"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_ST"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_issuer_ST"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_issuer_C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_C"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_issuer_C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_issuer_L"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_L"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_issuer_L"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_validity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text="@string/ssl_validator_label_validity"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/label_validity_from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_validity_from"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_validity_from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_validity_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_validity_to"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_validity_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/label_signature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text="@string/ssl_validator_label_signature"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/label_signature_algorithm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ssl_validator_label_signature_algorithm"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_signature_algorithm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/value_signature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/alternate_half_padding"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
</LinearLayout>
</ScrollView>
<TextView
android:id="@+id/question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/standard_padding"
android:text="@string/ssl_validator_question"
android:textAppearance="?android:attr/textAppearanceMedium"
>
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<com.google.android.material.button.MaterialButton
android:id="@+id/cancel"
style="@style/Button.Borderless"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/common_no" />
<com.google.android.material.button.MaterialButton
android:id="@+id/details_btn"
style="@style/Button.Borderless"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/ssl_validator_btn_details_see" />
<com.google.android.material.button.MaterialButton
android:id="@+id/ok"
style="@style/Button.Borderless"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/common_yes" />
</LinearLayout>
</LinearLayout>

View file

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud Android client application
~
~ @author Álvaro Brey Vilas
~ Copyright (C) 2022 Álvaro Brey Vilas
~ Copyright (C) 2022 Nextcloud GmbH
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU 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 General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:paddingHorizontal="?dialogPreferredPadding">
<TextView
android:id="@+id/storage_permission_explanation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/file_management_permission_optional_text" />
<com.google.android.material.button.MaterialButton
android:layout_marginTop="@dimen/standard_padding"
android:id="@+id/btn_full_access"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/storage_permission_full_access"
android:theme="@style/Button.Primary"
app:cornerRadius="@dimen/button_corner_radius"
app:layout_constraintTop_toBottomOf="@id/storage_permission_explanation" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_read_only"
style="@style/OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/storage_permission_media_read_only"
app:cornerRadius="@dimen/button_corner_radius"
app:layout_constraintTop_toBottomOf="@id/btn_full_access" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -32,9 +32,11 @@
<string name="activity_icon">アクティビティ</string>
<string name="add_another_public_share_link">別のリンクを作成</string>
<string name="add_new_public_share">新規公開共有リンクを追加</string>
<string name="add_new_secure_file_drop">新しいセキュアなファイルドロップを追加</string>
<string name="add_to_cloud">%1$s に追加</string>
<string name="advanced_settings">高度な設定</string>
<string name="allow_resharing">再共有を許可</string>
<string name="app_widget_description">ダッシュボードから一つのウィジェットを表示</string>
<string name="appbar_search_in">%s の中を検索</string>
<string name="associated_account_not_found">関連付けられたアカウントが見つかりません!</string>
<string name="auth_access_failed">アクセスに失敗しました: %1$s</string>
@ -87,11 +89,14 @@
<string name="calendars">カレンダー</string>
<string name="certificate_load_problem">証明書の読み込みに問題がありました。</string>
<string name="changelog_dev_version">開発バージョンの変更履歴</string>
<string name="check_back_later_or_reload">後で確認するか、再読込をしてください</string>
<string name="checkbox">チェックボックス</string>
<string name="choose_local_folder">ローカルフォルダーを選択…</string>
<string name="choose_location">場所を選択</string>
<string name="choose_remote_folder">リモートフォルダを選択…</string>
<string name="choose_template_helper_text">テンプレートを選択してファイル名を入力してください。</string>
<string name="choose_which_file">保存するファイルを選択</string>
<string name="choose_widget">ウィジェットを選択</string>
<string name="clear_notifications_failed">通知の削除に失敗</string>
<string name="clear_status_message">メッセージを消去</string>
<string name="clear_status_message_after">ステータスメッセージの有効期限</string>
@ -152,6 +157,7 @@
<string name="conflict_local_file">ローカルファイル</string>
<string name="conflict_message_description">両方のバージョンを選択した場合、ローカルファイルはファイル名に数字が追加されます。</string>
<string name="conflict_server_file">サーバーファイル</string>
<string name="contact_backup_title">連絡先のバックアップ</string>
<string name="contactlist_item_icon">連絡先リストのユーザーアイコン</string>
<string name="contactlist_no_permission">許可がありません、インポートできません。</string>
<string name="contacts">連絡先</string>
@ -197,13 +203,20 @@
<string name="did_not_check_for_dupes">重複をチェックしませんでした</string>
<string name="digest_algorithm_not_available">このスマートフォンでは、ダイジェストアルゴリズムが利用できません。</string>
<string name="direct_login_failed">ダイレクトリンクからのログインに失敗しました!</string>
<string name="direct_login_text">%1$s で %2$s へログインする</string>
<string name="disable_new_media_folder_detection_notifications">無効</string>
<string name="dismiss">閉じる</string>
<string name="dismiss_notification_description">通知を閉じる</string>
<string name="dnd">取り込み中</string>
<string name="document_scan_export_dialog_images">複数の画像</string>
<string name="document_scan_export_dialog_pdf">PDFファイル</string>
<string name="document_scan_export_dialog_title">エクスポートする種類を選択</string>
<string name="document_scan_pdf_generation_failed">PDFの生成に失敗しました</string>
<string name="document_scan_pdf_generation_in_progress">PDFを生成中...</string>
<string name="done">完了</string>
<string name="dontClear">消去しない</string>
<string name="download_cannot_create_file">ローカルファイルが作成できません</string>
<string name="download_download_invalid_local_file_name">ローカルファイルに対して無効なファイル名</string>
<string name="download_latest_dev_version">最新の開発バージョンをダウンロード</string>
<string name="downloader_download_failed_content">%1$sをダウンロードできませんでした</string>
<string name="downloader_download_failed_credentials_error">ダウンロード失敗、要 再ログイン</string>
@ -233,10 +246,14 @@
<string name="drawer_quota">%2$s 中%1$s が使われています。</string>
<string name="drawer_quota_unlimited">%1$s使用中</string>
<string name="drawer_synced_folders">自動アップロード</string>
<string name="e2e_not_yet_setup">E2E暗号化が未設定</string>
<string name="e2e_offline">インターネット接続なしには不可能です</string>
<string name="ecosystem_apps_display_more">さらに表示</string>
<string name="ecosystem_apps_display_notes">ノート</string>
<string name="ecosystem_apps_display_talk">トーク</string>
<string name="ecosystem_apps_more">もっと Nextcloud アプリを見る</string>
<string name="ecosystem_apps_notes">Nextcloud ノート</string>
<string name="ecosystem_apps_talk">Nextcloud Talk</string>
<string name="encrypted">暗号化設定</string>
<string name="end_to_end_encryption_confirm_button">暗号化を設定する</string>
<string name="end_to_end_encryption_decrypting">復号化中…</string>
@ -266,7 +283,9 @@
<string name="error_report_issue_text">問題を報告しますか? (GitHubのアカウントが必要です)</string>
<string name="error_retrieving_file">ファイルの取得中にエラーが発生しました</string>
<string name="error_retrieving_templates">テンプレートの取得中にエラーが発生しました</string>
<string name="error_showing_encryption_dialog">暗号化設定ダイアログの表示エラー</string>
<string name="error_starting_direct_camera_upload">カメラ起動エラー</string>
<string name="error_starting_doc_scan">文書スキャンの開始エラー</string>
<string name="etm_accounts">アカウント</string>
<string name="etm_background_job_name">ジョブの名前</string>
<string name="etm_background_job_progress">進捗状況</string>
@ -297,6 +316,7 @@
<string name="failed_update_ui">UIの更新に失敗しました</string>
<string name="favorite">お気に入りに追加</string>
<string name="favorite_icon">お気に入り</string>
<string name="file_already_exists">ファイル名が既に存在します</string>
<string name="file_delete">削除</string>
<string name="file_detail_activity_error">ファイルのアクティビティ取得エラー</string>
<string name="file_details_no_content">詳細のロードに失敗しました</string>
@ -362,6 +382,7 @@
<string name="filename_hint">ファイル名</string>
<string name="first_run_1_text">あなたのデータをセキュアなままコントロールしましょう</string>
<string name="first_run_2_text">セキュアなコラボレーションとファイル交換</string>
<string name="first_run_3_text">使いやすいWebメールやカレンダーや &amp; 連絡先</string>
<string name="first_run_4_text">画面共有やオンラインミーティングやウェブ会議</string>
<string name="folder_already_exists">フォルダーはすでに存在します</string>
<string name="folder_confirm_create">作成</string>
@ -388,6 +409,18 @@
<string name="hint_password">パスワード</string>
<string name="host_not_available">サーバーが利用できません</string>
<string name="host_your_own_server">自分のサーバーをホストする</string>
<string name="icon_of_dashboard_widget">ダッシュボードウィジェットのアイコン</string>
<string name="image_editor_file_edited_suffix">編集された</string>
<string name="image_editor_flip_horizontal">左右反転</string>
<string name="image_editor_flip_vertical">上下反転</string>
<string name="image_editor_rotate_ccw">反時計回りに回す</string>
<string name="image_editor_rotate_cw">時計回りに回す</string>
<string name="image_editor_unable_to_edit_image">画像の編集が不可能です</string>
<string name="image_preview_filedetails">ファイルの詳細</string>
<string name="image_preview_unit_iso">ISO %s</string>
<string name="image_preview_unit_megapixel">%s MP</string>
<string name="image_preview_unit_millimetres">%s mm</string>
<string name="image_preview_unit_seconds">%s 秒</string>
<string name="in_folder">フォルダー%1$sの中で</string>
<string name="instant_upload_existing">既存のファイルもアップロード</string>
<string name="instant_upload_on_charging">充電中のみアップロード</string>
@ -408,12 +441,14 @@
<string name="local_file_not_found_message">ローカルファイルシステムにファイルが見つかりません</string>
<string name="local_folder_friendly_path">%1$s/%2$s</string>
<string name="local_folder_list_empty">これ以上フォルダーがありません。</string>
<string name="locate_folder">フォルダーの配置</string>
<string name="lock_expiration_info">有効期限: %1$s</string>
<string name="lock_file">ファイルをロック</string>
<string name="locked_by">%1$sによりロック</string>
<string name="locked_by_app">%1$sアプリによりロック</string>
<string name="log_send_mail_subject">%1$s アンドロイドアプリログ</string>
<string name="log_send_no_mail_app">ログを送信するためのアプリが見つかりません。メールクライアントをインストールしてください。</string>
<string name="logged_in_as">%1$sとしてログインしました</string>
<string name="login">ログイン</string>
<string name="login_url_helper_text">%1$sをWeb画面でブラウザーで開くときのURL</string>
<string name="logs_menu_delete">ログを消去</string>
@ -465,6 +500,8 @@
<string name="no_browser_available">リンクを処理するアプリがありません</string>
<string name="no_calendar_exists">カレンダーがありません</string>
<string name="no_email_app_available">メールアドレスの利用可能なアプリはありません</string>
<string name="no_items">アイテムがありません</string>
<string name="no_map_app_availble">マップを処理するアプリケーションがありません</string>
<string name="no_mutliple_accounts_allowed">利用できるアカウントは1つだけです</string>
<string name="no_pdf_app_available">PDFを処理するアプリケーションがありません</string>
<string name="no_send_app">選択されたファイルの送信で利用可能なアプリがありません</string>
@ -503,11 +540,13 @@
<string name="pass_code_removed">パスコードを削除しました</string>
<string name="pass_code_stored">パスコードを保存しました</string>
<string name="pass_code_wrong">パスコードが正しくありません</string>
<string name="pdf_password_protected">パスワード保護されたPDFファイルを開くことは出来ません。外部ビューワを使ってください</string>
<string name="pdf_zoom_tip">ズームするにはページをタップ</string>
<string name="permission_allow">許可</string>
<string name="permission_deny">拒否</string>
<string name="permission_storage_access">ファイルをダウンロードとアップロードする追加の権限が必要です。</string>
<string name="picture_set_as_no_app">画像を設定するアプリが見つかりませんでした</string>
<string name="pin_home">ホームスクリーンにピン留めする</string>
<string name="placeholder_fileSize">389 KB</string>
<string name="placeholder_filename">placeholder.txt</string>
<string name="placeholder_media_time">12:23:45</string>
@ -537,6 +576,7 @@
<string name="prefs_category_more">もっと見る</string>
<string name="prefs_daily_backup_summary">カレンダーと連絡先を毎日バックアップ</string>
<string name="prefs_daily_contact_backup_summary">連絡先のデイリーバックアップ</string>
<string name="prefs_e2e_active">End-to-end 暗号化を設定中!</string>
<string name="prefs_e2e_mnemonic">E2Eニーモニック</string>
<string name="prefs_e2e_no_device_credentials">ニーモニックを表示するには、デバイスクレデンシャルを有効にしてください。</string>
<string name="prefs_enable_media_scan_notifications">メディアのスキャン結果通知を表示する</string>
@ -546,7 +586,9 @@
<string name="prefs_imprint">インプリント</string>
<string name="prefs_instant_behaviour_dialogTitle">元のファイルの扱い…</string>
<string name="prefs_instant_behaviour_title">元のファイルになります…</string>
<string name="prefs_instant_upload_path_use_date_subfolders_summary">日付を基にしたサブフォルダーに保存</string>
<string name="prefs_instant_upload_path_use_subfolders_title">サブフォルダーを利用</string>
<string name="prefs_keys_exist">このクライアントに End-to-End 暗号化を追加</string>
<string name="prefs_license">ライセンス</string>
<string name="prefs_lock">アプリパスコード</string>
<string name="prefs_lock_device_credentials_enabled">デバイスの資格情報が有効です</string>
@ -557,6 +599,7 @@
<string name="prefs_lock_using_passcode">パスコード</string>
<string name="prefs_manage_accounts">アカウント管理</string>
<string name="prefs_recommend">友達にすすめる</string>
<string name="prefs_setup_e2e">end-to-end 暗号化を設定</string>
<string name="prefs_show_hidden_files">隠しファイルを表示</string>
<string name="prefs_sourcecode">ソースコードを入手</string>
<string name="prefs_storage_path">データ保存フォルダー</string>
@ -580,6 +623,7 @@
<string name="recommend_subject">デバイスで %1$s をお試しください</string>
<string name="recommend_text">あなたのデバイスで %1$s を使用してください。\nダウンロードはこちらです: %2$s</string>
<string name="recommend_urls">%1$s または %2$s</string>
<string name="refresh_content">コンテンツを更新</string>
<string name="reload">再読み込み</string>
<string name="remote">(リモート)</string>
<string name="remote_file_fetch_failed">ファイルが見つかりません!</string>
@ -600,6 +644,7 @@
<string name="retrieving_file">ファイルを取得中...</string>
<string name="richdocuments_failed_to_load_document">ドキュメントのロードに失敗しました。</string>
<string name="scanQR_description">QRコードを用いてログイン</string>
<string name="scan_page">ページをスキャン</string>
<string name="screenshot_01_gridView_heading">あなたのデータを保護</string>
<string name="screenshot_01_gridView_subline">自己ホスト型の生産性</string>
<string name="screenshot_02_listView_heading">閲覧と共有</string>
@ -614,6 +659,7 @@
<string name="screenshot_06_davdroid_subline">DAVx5で同期</string>
<string name="search_error">検索結果の取得中にエラーが発生しました</string>
<string name="select_all">すべて選択</string>
<string name="select_media_folder">メディア用のフォルダーの設定</string>
<string name="select_one_template">テンプレートを選択してください</string>
<string name="select_template">テンプレートを選択する</string>
<string name="send">送信</string>
@ -649,6 +695,7 @@
<string name="share_password_title">パスワード保護</string>
<string name="share_permission_can_edit">編集可能</string>
<string name="share_permission_file_drop">ファイルを転送</string>
<string name="share_permission_secure_file_drop">セキュアなファイルドロップ</string>
<string name="share_permission_view_only">閲覧のみ</string>
<string name="share_permissions">共有権限</string>
<string name="share_remote_clarification">%1$s (リモート)</string>
@ -668,6 +715,8 @@
<string name="shared_icon_shared_via_link">リンク経由で共有</string>
<string name="shared_with_you_by">%1$sと共有中</string>
<string name="sharee_add_failed">共有を追加できませんでした</string>
<string name="show_images">写真を表示</string>
<string name="show_video">動画を表示</string>
<string name="signup_with_provider">他のサービスでサインアップ</string>
<string name="single_sign_on_request_token" formatted="true">%1$s があなたのNextcloudアカウント %2$s にアクセスできるようにしますか?</string>
<string name="sort_by">ソート</string>
@ -722,9 +771,13 @@
<string name="stream_not_possible_headline">内部ストリーミングは不可能</string>
<string name="stream_not_possible_message">代わりにメディアをダウンロードするか、外部アプリを使用してください。</string>
<string name="strict_mode">ストリクトモードHTTP接続が許可されていません</string>
<string name="sub_folder_rule_day">念/月/日</string>
<string name="sub_folder_rule_month">年/月</string>
<string name="sub_folder_rule_year"></string>
<string name="subject_shared_with_you">\"%1$s\" があなたに共有されました</string>
<string name="subject_user_shared_with_you">%1$s は \"%2$s\" をあなたと共有しました</string>
<string name="subtitle_photos_only">写真のみ</string>
<string name="subtitle_videos_only">動画のみ</string>
<string name="suggest">提案</string>
<string name="sync_conflicts_in_favourites_ticker">競合が見つかりました</string>
<string name="sync_current_folder_was_removed">フォルダー %1$s はもう存在しません</string>
@ -758,6 +811,7 @@
<string name="thumbnail">サムネイル</string>
<string name="thumbnail_for_existing_file_description">既存ファイルのサムネイル</string>
<string name="thumbnail_for_new_file_desc">新規ファイルのサムネイル</string>
<string name="timeout_richDocuments">ローディング中 期待した時間より長くかかっています</string>
<string name="today">今日</string>
<string name="trashbin_activity_title">ゴミ箱</string>
<string name="trashbin_empty_headline">削除されたファイルはありません</string>
@ -872,6 +926,7 @@
<string name="whats_new_skip">スキップ</string>
<string name="whats_new_title">%1$sの新機能</string>
<string name="whats_your_status">あなたのステータスは?</string>
<string name="widgets_not_available">ウィジェットは %1$s 25 以上でのみ利用可能です </string>
<string name="widgets_not_available_title">利用できません</string>
<string name="write_email">メールを送信</string>
<string name="wrong_storage_path">データ保存フォルダーが存在しません!</string>
@ -894,6 +949,18 @@
<plurals name="found_n_duplicates">
<item quantity="other">重複する応募が%d件見つかりました。</item>
</plurals>
<plurals name="export_successful">
<item quantity="other">エクスポートされた %d ファイル</item>
</plurals>
<plurals name="export_failed">
<item quantity="other">%dファイルのエクスポートに失敗しました</item>
</plurals>
<plurals name="export_partially_failed">
<item quantity="other">エラーのため、%d ファイルはエクスポートされ、他のファイルはスキップされました</item>
</plurals>
<plurals name="export_start">
<item quantity="other">%dファイルがエクスポートされます。詳細は通知を確認してください。</item>
</plurals>
<plurals name="file_list__footer__folder">
<item quantity="other">%1$d フォルダ</item>
</plurals>

View file

@ -79,7 +79,6 @@
<dimen name="search_users_groups_layout_list_view_margin">20dp</dimen>
<dimen name="share_file_layout_text_size">12sp</dimen>
<dimen name="ssl_untrusted_cert_layout_padding">20dp</dimen>
<dimen name="scroll_view_height">180dp</dimen>
<dimen name="upload_list_item_frame_layout_width">60dp</dimen>
<dimen name="upload_list_item_text_size">12sp</dimen>
<dimen name="uploader_list_item_layout_image_margin">12dp</dimen>

View file

@ -800,8 +800,6 @@
<string name="permission_deny">Deny</string>
<string name="permission_allow">Allow</string>
<string name="share_send_note">Note to recipient</string>
<string name="note_confirm">Send</string>
<string name="send_note">Send note to recipient</string>
<string name="note_could_not_sent">Could not send note</string>
<string name="hint_note">Note</string>
<string name="no_browser_available">No app available to handle links</string>

View file

@ -128,7 +128,7 @@ else
# check for NotNull
if [[ $(grep org.jetbrains.annotations app/src/main/* -irl | wc -l) -gt 0 ]] ; then
notNull="org.jetbrains.annotations.NotNull is used. Please use androidx.annotation.NonNull instead.<br><br>"
notNull="org.jetbrains.annotations.* is used. Please use androidx.annotation.* instead.<br><br>"
fi
bodyContent="$codacyResult $lintResult $spotbugsResult $checkLibraryMessage $lintMessage $spotbugsMessage $gplayLimitation $notNull"