mirror of
https://github.com/nextcloud/android.git
synced 2024-11-26 07:05:49 +03:00
Merge pull request #5328 from nextcloud/fix/not-enough-space-dialog
Added "not enough space dialog"
This commit is contained in:
commit
0936945b3c
9 changed files with 269 additions and 8 deletions
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Tobias Kaminsky
|
||||||
|
* Copyright (C) 2020 Tobias Kaminsky
|
||||||
|
* Copyright (C) 2020 Nextcloud GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.owncloud.android.ui.dialog;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
|
||||||
|
import com.facebook.testing.screenshot.Screenshot;
|
||||||
|
import com.owncloud.android.AbstractIT;
|
||||||
|
import com.owncloud.android.datamodel.OCFile;
|
||||||
|
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import androidx.test.espresso.intent.rule.IntentsTestRule;
|
||||||
|
import androidx.test.rule.GrantPermissionRule;
|
||||||
|
|
||||||
|
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||||
|
|
||||||
|
public class SyncFileNotEnoughSpaceDialogFragmentTest extends AbstractIT {
|
||||||
|
@Rule public IntentsTestRule<FileDisplayActivity> activityRule = new IntentsTestRule<>(FileDisplayActivity.class,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GrantPermissionRule permissionRule = GrantPermissionRule.grant(
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showNotEnoughSpaceDialogForFolder() {
|
||||||
|
FileDisplayActivity test = activityRule.launchActivity(null);
|
||||||
|
OCFile ocFile = new OCFile("/Document/");
|
||||||
|
ocFile.setFileLength(5000000);
|
||||||
|
|
||||||
|
SyncFileNotEnoughSpaceDialogFragment dialog = SyncFileNotEnoughSpaceDialogFragment.newInstance(ocFile, 1000);
|
||||||
|
dialog.show(test.getListOfFilesFragment().getFragmentManager(), "1");
|
||||||
|
|
||||||
|
getInstrumentation().waitForIdleSync();
|
||||||
|
|
||||||
|
Screenshot.snap(dialog.getDialog().getWindow().getDecorView()).record();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showNotEnoughSpaceDialogForFile() {
|
||||||
|
FileDisplayActivity test = activityRule.launchActivity(null);
|
||||||
|
OCFile ocFile = new OCFile("/Video.mp4");
|
||||||
|
ocFile.setFileLength(1000000);
|
||||||
|
|
||||||
|
SyncFileNotEnoughSpaceDialogFragment dialog = SyncFileNotEnoughSpaceDialogFragment.newInstance(ocFile, 2000);
|
||||||
|
dialog.show(test.getListOfFilesFragment().getFragmentManager(), "2");
|
||||||
|
|
||||||
|
getInstrumentation().waitForIdleSync();
|
||||||
|
|
||||||
|
Screenshot.snap(dialog.getDialog().getWindow().getDecorView()).record();
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ public class ConfirmationDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
final static String ARG_MESSAGE_RESOURCE_ID = "resource_id";
|
final static String ARG_MESSAGE_RESOURCE_ID = "resource_id";
|
||||||
final static String ARG_MESSAGE_ARGUMENTS = "string_array";
|
final static String ARG_MESSAGE_ARGUMENTS = "string_array";
|
||||||
private static final String ARG_TITLE_ID = "title_id";
|
final static String ARG_TITLE_ID = "title_id";
|
||||||
|
|
||||||
final static String ARG_POSITIVE_BTN_RES = "positive_btn_res";
|
final static String ARG_POSITIVE_BTN_RES = "positive_btn_res";
|
||||||
final static String ARG_NEUTRAL_BTN_RES = "neutral_btn_res";
|
final static String ARG_NEUTRAL_BTN_RES = "neutral_btn_res";
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Kilian Périsset
|
||||||
|
* Copyright (C) 2020 Infomaniak Network SA
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License (GPLv3),
|
||||||
|
* 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.Intent;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.storage.StorageManager;
|
||||||
|
|
||||||
|
import com.owncloud.android.R;
|
||||||
|
import com.owncloud.android.datamodel.OCFile;
|
||||||
|
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
|
||||||
|
import com.owncloud.android.ui.fragment.OCFileListFragment;
|
||||||
|
import com.owncloud.android.utils.DisplayUtils;
|
||||||
|
import com.owncloud.android.utils.ThemeUtils;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialog requiring confirmation when a file/folder is too "big" to be synchronized/downloaded on device.
|
||||||
|
*/
|
||||||
|
public class SyncFileNotEnoughSpaceDialogFragment extends ConfirmationDialogFragment implements
|
||||||
|
ConfirmationDialogFragmentListener {
|
||||||
|
|
||||||
|
private static final String ARG_PASSED_FILE = "fragment_parent_caller";
|
||||||
|
private static final int REQUEST_CODE_STORAGE = 20;
|
||||||
|
|
||||||
|
private OCFile targetFile;
|
||||||
|
|
||||||
|
public static SyncFileNotEnoughSpaceDialogFragment newInstance(OCFile file, long availableDeviceSpace) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
SyncFileNotEnoughSpaceDialogFragment frag = new SyncFileNotEnoughSpaceDialogFragment();
|
||||||
|
String properFileSize = DisplayUtils.bytesToHumanReadable(file.getFileLength());
|
||||||
|
String properDiskAvailableSpace = DisplayUtils.bytesToHumanReadable(availableDeviceSpace);
|
||||||
|
|
||||||
|
// Defining title, message and resources
|
||||||
|
args.putInt(ARG_TITLE_ID, R.string.sync_not_enough_space_dialog_title);
|
||||||
|
args.putInt(ARG_MESSAGE_RESOURCE_ID, R.string.sync_not_enough_space_dialog_placeholder);
|
||||||
|
args.putStringArray(ARG_MESSAGE_ARGUMENTS,
|
||||||
|
new String[] {
|
||||||
|
file.getFileName(),
|
||||||
|
properFileSize,
|
||||||
|
properDiskAvailableSpace});
|
||||||
|
args.putParcelable(ARG_PASSED_FILE, file);
|
||||||
|
|
||||||
|
// Defining buttons
|
||||||
|
if (file.isFolder()) {
|
||||||
|
args.putInt(ARG_POSITIVE_BTN_RES, R.string.sync_not_enough_space_dialog_action_choose);
|
||||||
|
}
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
|
||||||
|
args.putInt(ARG_NEGATIVE_BTN_RES, R.string.sync_not_enough_space_dialog_action_free_space);
|
||||||
|
}
|
||||||
|
args.putInt(ARG_NEUTRAL_BTN_RES, R.string.common_cancel);
|
||||||
|
|
||||||
|
frag.setArguments(args);
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
int color = ThemeUtils.primaryAccentColor(getActivity());
|
||||||
|
AlertDialog alertDialog = (AlertDialog) getDialog();
|
||||||
|
|
||||||
|
if (alertDialog != null) {
|
||||||
|
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(color);
|
||||||
|
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(color);
|
||||||
|
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
Bundle arguments = getArguments();
|
||||||
|
|
||||||
|
if (arguments == null) {
|
||||||
|
throw new IllegalArgumentException("Arguments may not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
targetFile = arguments.getParcelable(ARG_PASSED_FILE);
|
||||||
|
setOnConfirmationListener(this);
|
||||||
|
|
||||||
|
return super.onCreateDialog(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Only if file is a folder), will access the destination folder to allow user to choose what to synchronize
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onConfirmation(String callerTag) {
|
||||||
|
OCFileListFragment frag = (OCFileListFragment) getTargetFragment();
|
||||||
|
if (frag != null && targetFile != null) {
|
||||||
|
frag.onItemClicked(targetFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will abort/cancel the process (is neutral to "hack" android button position ._.)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onNeutral(String callerTag) {
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will access to storage manager in order to empty useless files
|
||||||
|
*/
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
|
||||||
|
@Override
|
||||||
|
public void onCancel(String callerTag) {
|
||||||
|
Intent storageIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
|
||||||
|
startActivityForResult(storageIntent, REQUEST_CODE_STORAGE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,12 +83,14 @@ import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
|
||||||
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
|
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
|
||||||
import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
|
import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
|
||||||
import com.owncloud.android.ui.dialog.SetupEncryptionDialogFragment;
|
import com.owncloud.android.ui.dialog.SetupEncryptionDialogFragment;
|
||||||
|
import com.owncloud.android.ui.dialog.SyncFileNotEnoughSpaceDialogFragment;
|
||||||
import com.owncloud.android.ui.events.ChangeMenuEvent;
|
import com.owncloud.android.ui.events.ChangeMenuEvent;
|
||||||
import com.owncloud.android.ui.events.CommentsEvent;
|
import com.owncloud.android.ui.events.CommentsEvent;
|
||||||
import com.owncloud.android.ui.events.DummyDrawerEvent;
|
import com.owncloud.android.ui.events.DummyDrawerEvent;
|
||||||
import com.owncloud.android.ui.events.EncryptionEvent;
|
import com.owncloud.android.ui.events.EncryptionEvent;
|
||||||
import com.owncloud.android.ui.events.FavoriteEvent;
|
import com.owncloud.android.ui.events.FavoriteEvent;
|
||||||
import com.owncloud.android.ui.events.SearchEvent;
|
import com.owncloud.android.ui.events.SearchEvent;
|
||||||
|
import com.owncloud.android.ui.helpers.FileOperationsHelper;
|
||||||
import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
|
import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
|
||||||
import com.owncloud.android.ui.preview.PreviewImageFragment;
|
import com.owncloud.android.ui.preview.PreviewImageFragment;
|
||||||
import com.owncloud.android.ui.preview.PreviewMediaFragment;
|
import com.owncloud.android.ui.preview.PreviewMediaFragment;
|
||||||
|
@ -107,6 +109,7 @@ import org.parceler.Parcels;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -165,6 +168,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
||||||
private static final String DIALOG_CREATE_DOCUMENT = "DIALOG_CREATE_DOCUMENT";
|
private static final String DIALOG_CREATE_DOCUMENT = "DIALOG_CREATE_DOCUMENT";
|
||||||
|
|
||||||
private static final int SINGLE_SELECTION = 1;
|
private static final int SINGLE_SELECTION = 1;
|
||||||
|
private static final int NOT_ENOUGH_SPACE_FRAG_REQUEST_CODE = 2;
|
||||||
|
|
||||||
@Inject AppPreferences preferences;
|
@Inject AppPreferences preferences;
|
||||||
@Inject UserAccountManager accountManager;
|
@Inject UserAccountManager accountManager;
|
||||||
|
@ -1114,7 +1118,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
||||||
}
|
}
|
||||||
case R.id.action_download_file:
|
case R.id.action_download_file:
|
||||||
case R.id.action_sync_file: {
|
case R.id.action_sync_file: {
|
||||||
mContainerActivity.getFileOperationsHelper().syncFiles(checkedFiles);
|
syncAndCheckFiles(checkedFiles);
|
||||||
exitSelectionMode();
|
exitSelectionMode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1720,6 +1724,32 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
||||||
&& event.getUnsetType() != null;
|
&& event.getUnsetType() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void syncAndCheckFiles(Collection<OCFile> files) {
|
||||||
|
for (OCFile file : files) {
|
||||||
|
// Get the remaining space on device (after file download)
|
||||||
|
long availableSpaceOnDevice = FileOperationsHelper.getAvailableSpaceOnDevice();
|
||||||
|
|
||||||
|
// Determine if space is enough to download the file
|
||||||
|
boolean isSpaceEnough = availableSpaceOnDevice > file.getFileLength();
|
||||||
|
|
||||||
|
if (isSpaceEnough) {
|
||||||
|
mContainerActivity.getFileOperationsHelper().syncFile(file);
|
||||||
|
} else {
|
||||||
|
showSpaceErrorDialog(file, availableSpaceOnDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showSpaceErrorDialog(OCFile file, long availableSpaceOnDevice) {
|
||||||
|
SyncFileNotEnoughSpaceDialogFragment dialog =
|
||||||
|
SyncFileNotEnoughSpaceDialogFragment.newInstance(file, availableSpaceOnDevice);
|
||||||
|
dialog.setTargetFragment(this, NOT_ENOUGH_SPACE_FRAG_REQUEST_CODE);
|
||||||
|
|
||||||
|
if (getFragmentManager() != null) {
|
||||||
|
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoading() {
|
public boolean isLoading() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import android.content.pm.ResolveInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.StatFs;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -747,12 +748,6 @@ public class FileOperationsHelper {
|
||||||
sendShareFile(file, !file.canReshare());
|
sendShareFile(file, !file.canReshare());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void syncFiles(Collection<OCFile> files) {
|
|
||||||
for (OCFile file : files) {
|
|
||||||
syncFile(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendCachedImage(OCFile file, String packageName, String activityName) {
|
public void sendCachedImage(OCFile file, String packageName, String activityName) {
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
Context context = MainApp.getAppContext();
|
Context context = MainApp.getAppContext();
|
||||||
|
@ -1043,5 +1038,18 @@ public class FileOperationsHelper {
|
||||||
return new SimpleDateFormat("yyyy-MM-dd_HHmmss", Locale.US).format(new Date()) + ".jpg";
|
return new SimpleDateFormat("yyyy-MM-dd_HHmmss", Locale.US).format(new Date()) + ".jpg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Long getAvailableSpaceOnDevice() {
|
||||||
|
StatFs stat = new StatFs(MainApp.getStoragePath());
|
||||||
|
long availableBytesOnDevice;
|
||||||
|
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
|
availableBytesOnDevice = stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
|
||||||
|
} else {
|
||||||
|
availableBytesOnDevice = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableBytesOnDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -674,6 +674,10 @@ Attention la suppression est irréversible.</string>
|
||||||
<string name="sync_foreign_files_forgotten_explanation">Depuis la version 1.3.16, les fichiers envoyés depuis cet appareil sont copiés dans le dossier local %1$s pour éviter une perte de données lorsqu\'un même fichier est synchronisé avec plusieurs comptes.\n\nEn raison de cette modification, tous les fichiers envoyés avec des versions antérieures de cette application ont été copiés dans le dossier %2$s. Cependant, une erreur a empêché l\'achèvement de cette opération pendant la synchronisation du compte. Vous pouvez soit laisser les fichiers tels quels et supprimer le lien vers %3$s, soit déplacer les fichiers dans le dossier %1$s et garder le lien vers %4$s.\n\nCi-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxquels ils étaient liés.</string>
|
<string name="sync_foreign_files_forgotten_explanation">Depuis la version 1.3.16, les fichiers envoyés depuis cet appareil sont copiés dans le dossier local %1$s pour éviter une perte de données lorsqu\'un même fichier est synchronisé avec plusieurs comptes.\n\nEn raison de cette modification, tous les fichiers envoyés avec des versions antérieures de cette application ont été copiés dans le dossier %2$s. Cependant, une erreur a empêché l\'achèvement de cette opération pendant la synchronisation du compte. Vous pouvez soit laisser les fichiers tels quels et supprimer le lien vers %3$s, soit déplacer les fichiers dans le dossier %1$s et garder le lien vers %4$s.\n\nCi-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxquels ils étaient liés.</string>
|
||||||
<string name="sync_foreign_files_forgotten_ticker">Certains fichiers locaux ont été ignorés</string>
|
<string name="sync_foreign_files_forgotten_ticker">Certains fichiers locaux ont été ignorés</string>
|
||||||
<string name="sync_in_progress">Récupération de la version la plus récente du fichier.</string>
|
<string name="sync_in_progress">Récupération de la version la plus récente du fichier.</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_action_choose">Choisir quels fichiers synchroniser</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_action_free_space">Libérer de l\'espace</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_placeholder">%1$s est trop volumineux (%2$s) par rapport à l\'espace disponible sur votre appareil (%3$s).</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_title">Plus assez d\'espace disponible</string>
|
||||||
<string name="sync_status_button">Bouton de statut de la synchronisation</string>
|
<string name="sync_status_button">Bouton de statut de la synchronisation</string>
|
||||||
<string name="sync_string_files">Fichiers</string>
|
<string name="sync_string_files">Fichiers</string>
|
||||||
<string name="synced_folder_settings_button">Bouton des paramètres</string>
|
<string name="synced_folder_settings_button">Bouton des paramètres</string>
|
||||||
|
|
|
@ -913,4 +913,10 @@
|
||||||
<string name="edit_rich_workspace">edit folder info</string>
|
<string name="edit_rich_workspace">edit folder info</string>
|
||||||
<string name="create_new">Create new</string>
|
<string name="create_new">Create new</string>
|
||||||
<string name="editor_placeholder" translatable="false">%1$s %2$s</string>
|
<string name="editor_placeholder" translatable="false">%1$s %2$s</string>
|
||||||
|
|
||||||
|
<string name="sync_not_enough_space_dialog_action_choose">Choose what to sync</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_action_free_space">Free up space</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_placeholder">%1$s is %2$s, but there is only %3$s
|
||||||
|
available on device.</string>
|
||||||
|
<string name="sync_not_enough_space_dialog_title">Not enough space</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue