From 80c69a439fad6a2dd98d1ae333634c3402aca197 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 4 Aug 2016 17:19:29 +0200 Subject: [PATCH 01/33] Fix comparator determining order of list of uploads --- .../android/ui/adapter/ExpandableUploadListAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java b/src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java index c8051f8662..5c1b0ffafb 100755 --- a/src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java @@ -98,6 +98,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple if (!upload2.getUploadStatus().equals(UploadStatus.UPLOAD_IN_PROGRESS)) { return -1; } + // both are in progress FileUploader.FileUploaderBinder binder = mParentActivity.getFileUploaderBinder(); if (binder != null) { if (binder.isUploadingNow(upload1)) { @@ -109,7 +110,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple } else if (upload2.getUploadStatus().equals(UploadStatus.UPLOAD_IN_PROGRESS)) { return 1; } - if (upload1.getUploadEndTimestamp() == 0) { + if (upload1.getUploadEndTimestamp() == 0 || upload2.getUploadEndTimestamp() == 0) { return compareUploadId(upload1, upload2); } else { return compareUpdateTime(upload1, upload2); From f6e4a6b60998a821224495d5b3c72b88182fd3b2 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Mon, 8 Aug 2016 19:33:23 +0200 Subject: [PATCH 02/33] generate thumbnails only if mCurrentUpload is not null --- .../android/files/services/FileUploader.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index fa523dd521..d70dec94b0 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -950,17 +950,16 @@ public class FileUploader extends Service } + // generate new Thumbnail + final ThumbnailsCacheManager.ThumbnailGenerationTask task = + new ThumbnailsCacheManager.ThumbnailGenerationTask(mStorageManager, mCurrentAccount); + + Object[] params = new Object[2]; + params[0] = new File(mCurrentUpload.getOriginalStoragePath()); + params[1] = mCurrentUpload.getFile().getRemoteId(); + + task.execute(params); } - - // generate new Thumbnail - final ThumbnailsCacheManager.ThumbnailGenerationTask task = - new ThumbnailsCacheManager.ThumbnailGenerationTask(mStorageManager, mCurrentAccount); - - Object[] params = new Object[2]; - params[0] = new File(mCurrentUpload.getOriginalStoragePath()); - params[1] = mCurrentUpload.getFile().getRemoteId(); - - task.execute(params); } From f890b3553a38296bf0dd12caa9d934997b1d81d4 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Thu, 28 Jul 2016 18:29:49 +0200 Subject: [PATCH 03/33] resume chunked uploads --- src/com/owncloud/android/operations/UploadFileOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/owncloud/android/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index 36c8728898..e49d479590 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -363,7 +363,7 @@ public class UploadFileOperation extends SyncOperation { (new File(mFile.getStoragePath())).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) { mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), - mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict()); + mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), mContext); } else { mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict()); From f81cfb3cfdecd203c8323d9a284f715192a654ea Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 1 Aug 2016 16:25:23 +0200 Subject: [PATCH 04/33] bump Nc Android lib version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f88f80a678..1073f7ed58 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { /// dependencies for app building compile name: 'touch-image-view' - compile 'com.github.nextcloud:android-library:1.0.1' + compile 'com.github.nextcloud:android-library:1.0.2' compile "com.android.support:support-v4:${supportLibraryVersion}" compile "com.android.support:design:${supportLibraryVersion}" compile 'com.jakewharton:disklrucache:2.0.2' From 37295ffecbd613ecbcfbef3c436b4253fc39e3ea Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 1 Aug 2016 16:51:42 +0200 Subject: [PATCH 05/33] update to Nc Android lib 1.0.2 --- src/com/owncloud/android/MainApp.java | 4 +++- src/com/owncloud/android/operations/UploadFileOperation.java | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/MainApp.java b/src/com/owncloud/android/MainApp.java index 02fa5746cf..c9e2342cd0 100644 --- a/src/com/owncloud/android/MainApp.java +++ b/src/com/owncloud/android/MainApp.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; +import android.os.Environment; import com.owncloud.android.authentication.PassCodeManager; import com.owncloud.android.datamodel.ThumbnailsCacheManager; @@ -79,7 +80,8 @@ public class MainApp extends Application { // Set folder for store logs Log_OC.setLogDataFolder(dataFolder); - Log_OC.startLogging(); + //TODO: to be changed/fixed whenever SD card support gets merged. + Log_OC.startLogging(Environment.getExternalStorageDirectory().getAbsolutePath()); Log_OC.d("Debug", "start logging"); } diff --git a/src/com/owncloud/android/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index e49d479590..5518c8e491 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -362,8 +362,8 @@ public class UploadFileOperation extends SyncOperation { if ( mChunked && (new File(mFile.getStoragePath())).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) { - mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), - mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict(), mContext); + mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, mFile.getStoragePath(), + mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict()); } else { mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict()); From 283b5cb77ba3318e0f39f573beebb6ce7f8c51c7 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 9 Aug 2016 00:33:50 +0000 Subject: [PATCH 06/33] [tx-robot] updated from transifex --- res/values-cs-rCZ/strings.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 828e3af1ad..2e355c7a7f 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -457,4 +457,10 @@ správce systému. Opravdu chcete odstranit vybrané položky? Opravdu chcete odstranit vybrané položky a jejich obsah? Hledat - + + vybráno %d + vybráno %d + vybráno %d + + + From 53c360e1497870e08501f95593ef3e19520318b7 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 12 Aug 2016 00:33:49 +0000 Subject: [PATCH 07/33] [tx-robot] updated from transifex --- res/values-de/strings.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 3d39d1a85f..e5cc14a5d4 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -74,7 +74,7 @@ Lade… Es wurde keine App für diesen Dateityp gefunden! Es befinden sich keine Dateien in diesem Ordner. - Es + Keine Uploads verfügbar. Ordner Ordner Datei @@ -93,7 +93,7 @@ Nein OK Upload entfernen - hochladen erneut versuchen + Hochladen erneut versuchen Synchronisation abbrechen Abbrechen Zurück @@ -143,7 +143,7 @@ Herunterladen von %1$s konnte nicht abgeschlossen werden Noch nicht Heruntergeladen Herunterladen fehlgeschlagen, erneute Anmeldung erforderlich - Account auswählen + Konto auswählen Synchronisation fehlgeschlagen Synchronisation fehlgeschlagen, erneute Anmeldung erforderlich. Synchronisation von %1$s konnte nicht abgeschlossen werden @@ -166,7 +166,7 @@ Bitte PIN eingeben Die PIN wird jedes mal beim Start der App abgefragt - Bitte den PIN nochmals eingeben + Bitte Deine PIN nochmals eingeben PIN entfernen Die PINs stimmen nicht überein PIN nicht korrekt @@ -177,17 +177,17 @@ %1$s (playing) %1$s (loading) %1$s Beendet - Keine Meidendatei gefunden - Kein Konto angeben - Datei ist nicht in einem gültigen Account - Codierung wird nicht unterstützt - Fehler beim Lesen der Datei + Keine Mediendatei gefunden + Kein Konto angegeben + Datei ist nicht in einem gültigen Konto + Medien-Codec wird nicht unterstützt + Mediendatei konnte nicht gelesen werden Mediendatei nicht korrekt encodiert Wartezeit beim Abspielversuch abgelaufen Mediendatei konnte nicht gestreamt werden Diese Mediendatei konnte nicht mit dem Standardplayer geöffnet werden Sicherheitsfehler beim Versuch %1$s zu spielen - Eingabefehler beim Versuch %1$s zu spielen + Eingabefehler beim Versuch %1$s wiederzugeben Ein unerwarteter Fehler ist aufgetreten beim Versuch %1$s abzuspielen Zurückspielen Knopf Play-/Pause Knopf From 25a7a20352bb5971e13138c40f0a54931b62fa3e Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2016 16:46:23 +0200 Subject: [PATCH 08/33] Changed the delay to execute the runnable in startSyncFolderOperation, adding 350 ms. --- src/com/owncloud/android/ui/activity/FileDisplayActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index cdedbce4b2..4f1743c966 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -1638,7 +1638,7 @@ public class FileDisplayActivity extends HookActivity // another window floating over } }, - DELAY_TO_REQUEST_OPERATIONS_LATER + DELAY_TO_REQUEST_OPERATIONS_LATER + 350 ); } From 47e12fb278794a9876396611ce76f2312bcfc7eb Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Sun, 14 Aug 2016 21:24:56 +0200 Subject: [PATCH 09/33] CR changes --- .../android/ui/activity/DrawerActivity.java | 17 ++++++++++------- .../ui/activity/FileDisplayActivity.java | 4 +++- .../android/ui/activity/ToolbarActivity.java | 17 ++++++++++------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 965799b554..bab0cde0a3 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -1,20 +1,23 @@ /** - * ownCloud Android client application + * Nextcloud Android client application * * @author Andy Scherzinger + * Copyright (C) 2016 Andy Scherzinger + * Copyright (C) 2016 Nextcloud * Copyright (C) 2016 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 free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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. + * GNU AFFERO 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 . + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see . */ package com.owncloud.android.ui.activity; diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 4f1743c966..d0704bc193 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -122,6 +122,8 @@ public class FileDisplayActivity extends HookActivity public static final int REQUEST_CODE__MOVE_FILES = REQUEST_CODE__LAST_SHARED + 3; public static final int REQUEST_CODE__COPY_FILES = REQUEST_CODE__LAST_SHARED + 4; + protected static final long DELAY_TO_REQUEST_REFRESH_OPERATION_LATER = DELAY_TO_REQUEST_OPERATIONS_LATER + 350; + private static final String TAG = FileDisplayActivity.class.getSimpleName(); private static final String TAG_LIST_OF_FILES = "LIST_OF_FILES"; @@ -1638,7 +1640,7 @@ public class FileDisplayActivity extends HookActivity // another window floating over } }, - DELAY_TO_REQUEST_OPERATIONS_LATER + 350 + DELAY_TO_REQUEST_REFRESH_OPERATION_LATER ); } diff --git a/src/com/owncloud/android/ui/activity/ToolbarActivity.java b/src/com/owncloud/android/ui/activity/ToolbarActivity.java index b8b34378fb..9fdff2c0a1 100644 --- a/src/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/src/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -1,20 +1,23 @@ /** - * ownCloud Android client application + * Nextcloud Android client application * * @author Andy Scherzinger + * Copyright (C) 2016 Andy Scherzinger + * Copyright (C) 2016 Nextcloud * Copyright (C) 2016 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 free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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. + * GNU AFFERO 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 . + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see . */ package com.owncloud.android.ui.activity; From 1c874aafec78a771420badb654c697675065f4b2 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Sun, 14 Aug 2016 22:32:41 +0200 Subject: [PATCH 10/33] add background image to drawer header --- res/drawable-xxxhdpi/background.jpg | Bin 0 -> 85248 bytes res/layout/drawer_header.xml | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 res/drawable-xxxhdpi/background.jpg diff --git a/res/drawable-xxxhdpi/background.jpg b/res/drawable-xxxhdpi/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a44a8163b9550193e7dc37f88e9744ebbafc20e GIT binary patch literal 85248 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 Ck9s-) literal 0 HcmV?d00001 diff --git a/res/layout/drawer_header.xml b/res/layout/drawer_header.xml index 1b573d6333..8721fcdbad 100644 --- a/res/layout/drawer_header.xml +++ b/res/layout/drawer_header.xml @@ -19,15 +19,15 @@ + android:background="@drawable/background" + android:fitsSystemWindows="true"> + android:padding="@dimen/standard_padding"> Date: Mon, 15 Aug 2016 14:21:54 +0200 Subject: [PATCH 11/33] fix NPE (and unnecessary auto-boxing) --- .../ui/activity/UploadFilesActivity.java | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/UploadFilesActivity.java b/src/com/owncloud/android/ui/activity/UploadFilesActivity.java index 14a46bcfbd..7b393f4553 100644 --- a/src/com/owncloud/android/ui/activity/UploadFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/UploadFilesActivity.java @@ -94,11 +94,9 @@ public class UploadFilesActivity extends FileActivity implements super.onCreate(savedInstanceState); if(savedInstanceState != null) { - mCurrentDir = new File(savedInstanceState.getString( - UploadFilesActivity.KEY_DIRECTORY_PATH)); - mSelectAll = savedInstanceState.getBoolean( - UploadFilesActivity.KEY_ALL_SELECTED, false); - + mCurrentDir = new File(savedInstanceState.getString(UploadFilesActivity.KEY_DIRECTORY_PATH, Environment + .getExternalStorageDirectory().getAbsolutePath())); + mSelectAll = savedInstanceState.getBoolean(UploadFilesActivity.KEY_ALL_SELECTED, false); } else { mCurrentDir = Environment.getExternalStorageDirectory(); } @@ -354,8 +352,7 @@ public class UploadFilesActivity extends FileActivity implements ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); } - - + /** * {@inheritDoc} */ @@ -372,7 +369,6 @@ public class UploadFilesActivity extends FileActivity implements return mCurrentDir; } - /** * Performs corresponding action when user presses 'Cancel' or 'Upload' button * @@ -390,7 +386,6 @@ public class UploadFilesActivity extends FileActivity implements } } - /** * Asynchronous task checking if there is space enough to copy all the files chosen * to upload into the ownCloud local folder. @@ -409,7 +404,6 @@ public class UploadFilesActivity extends FileActivity implements mCurrentDialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG); } - /** * Checks the available space * @@ -424,21 +418,23 @@ public class UploadFilesActivity extends FileActivity implements File localFile = new File(localPath); total += localFile.length(); } - return (new Boolean(FileStorageUtils.getUsableSpace(mAccountOnCreation.name) >= total)); + return FileStorageUtils.getUsableSpace(mAccountOnCreation.name) >= total; } /** * Updates the activity UI after the check of space is done. - * + * * If there is not space enough. shows a new dialog to query the user if wants to move the * files instead of copy them. - * + * * @param result 'True' when there is space enough to copy all the selected files. */ @Override protected void onPostExecute(Boolean result) { - mCurrentDialog.dismiss(); - mCurrentDialog = null; + if(mCurrentDialog != null) { + mCurrentDialog.dismiss(); + mCurrentDialog = null; + } if (result) { // return the list of selected files (success) @@ -480,20 +476,17 @@ public class UploadFilesActivity extends FileActivity implements } } - @Override public void onNeutral(String callerTag) { Log_OC.d(TAG, "Phantom neutral button in dialog was clicked; dialog tag is " + callerTag); } - @Override public void onCancel(String callerTag) { /// nothing to do; don't finish, let the user change the selection Log_OC.d(TAG, "Negative button in dialog was clicked; dialog tag is " + callerTag); } - @Override protected void onAccountSet(boolean stateWasRecovered) { super.onAccountSet(stateWasRecovered); From 993264c8b1b2772f19a8c38b4acf3941561d9a81 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Sun, 1 May 2016 10:15:08 +0200 Subject: [PATCH 12/33] wip --- res/values/strings.xml | 1 + .../ReceiveExternalFilesActivity.java | 85 ++++++++++++++++--- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 7620dff3c7..0b68b93c51 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -57,6 +57,7 @@ Files Connect Upload + Create textfile Choose upload folder No account found There are no %1$s accounts on your device. Please set up an account first. diff --git a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 5193c28b43..8f004b76b5 100644 --- a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -40,8 +40,9 @@ import android.os.Bundle; import android.os.Parcelable; import android.support.v4.app.FragmentManager; import android.support.v7.app.ActionBar; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AlertDialog.Builder; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -49,6 +50,7 @@ import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; +import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; @@ -76,6 +78,9 @@ import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.ErrorMessageAdapter; import com.owncloud.android.utils.FileStorageUtils; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; @@ -175,13 +180,6 @@ public class ReceiveExternalFilesActivity extends FileActivity setAccount(accounts[0]); } } - - } else if (getIntent().getStringExtra(Intent.EXTRA_TEXT) != null) { - showErrorDialog( - R.string.uploader_error_message_received_piece_of_text, - R.string.uploader_error_title_no_file_to_upload - ); - } else { showErrorDialog( R.string.uploader_error_message_no_file_to_upload, @@ -342,8 +340,63 @@ public class ReceiveExternalFilesActivity extends FileActivity for (String p : mParents) { mUploadPath += p + OCFile.PATH_SEPARATOR; } - Log_OC.d(TAG, "Uploading file to dir " + mUploadPath); - uploadFiles(); + + if (uploadTextSnippet()){ + LayoutInflater layout = LayoutInflater.from(Uploader.this); + View view = layout.inflate(R.layout.edit_box_dialog, null); + + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( + Uploader.this); + + alertDialogBuilder.setView(view); + + final EditText userInput = (EditText) view.findViewById(R.id.user_input); + userInput.setText(".txt"); + + alertDialogBuilder.setCancelable(false) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog,int id) { + PrintWriter out; + try { + File f = File.createTempFile("owncloud", ".txt"); + out = new PrintWriter(f); + out.println(getIntent().getStringExtra( + Intent.EXTRA_TEXT)); + out.close(); + + FileUploader.UploadRequester requester = + new FileUploader.UploadRequester(); + + requester.uploadNewFile( + getBaseContext(), + getAccount(), + f.getAbsolutePath(), + mFile.getRemotePath() + userInput.getText() + + ".txt", + FileUploader.LOCAL_BEHAVIOUR_COPY, + null, + true, + UploadFileOperation.CREATED_BY_USER + ); + } catch (IOException e) { + e.printStackTrace(); + } + + finish(); + } + }) + .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog,int id) { + dialog.cancel(); + } + }); + + alertDialogBuilder.create().show(); + } else { + + Log_OC.d(TAG, "Uploading file to dir " + mUploadPath); + uploadFiles(); + } break; case R.id.uploader_cancel: @@ -423,6 +476,10 @@ public class ReceiveExternalFilesActivity extends FileActivity Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder); btnChooseFolder.setOnClickListener(this); + if (uploadTextSnippet()){ + btnChooseFolder.setText(R.string.uploader_btn_uploadTextSnippet_text); + } + Button btnNewFolder = (Button) findViewById(R.id.uploader_cancel); btnNewFolder.setOnClickListener(this); @@ -478,7 +535,11 @@ public class ReceiveExternalFilesActivity extends FileActivity } private boolean somethingToUpload() { - return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null); + return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null || uploadTextSnippet()); + } + + private boolean uploadTextSnippet(){ + return getIntent().getStringExtra(Intent.EXTRA_TEXT) != null; } @SuppressLint("NewApi") From 3c715fe4895ade8f3c70d207ba59016392793f91 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Thu, 21 Jul 2016 19:13:23 +0200 Subject: [PATCH 13/33] finish --- .../ui/activity/ReceiveExternalFilesActivity.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 8f004b76b5..7e54d74cf9 100644 --- a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -67,6 +67,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.operations.CreateFolderOperation; import com.owncloud.android.operations.RefreshFolderOperation; +import com.owncloud.android.operations.UploadFileOperation; import com.owncloud.android.syncadapter.FileSyncAdapter; import com.owncloud.android.ui.adapter.UploaderAdapter; import com.owncloud.android.ui.asynctasks.CopyAndUploadContentUrisTask; @@ -342,11 +343,11 @@ public class ReceiveExternalFilesActivity extends FileActivity } if (uploadTextSnippet()){ - LayoutInflater layout = LayoutInflater.from(Uploader.this); + LayoutInflater layout = LayoutInflater.from(getBaseContext()); View view = layout.inflate(R.layout.edit_box_dialog, null); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( - Uploader.this); + this); alertDialogBuilder.setView(view); @@ -367,12 +368,18 @@ public class ReceiveExternalFilesActivity extends FileActivity FileUploader.UploadRequester requester = new FileUploader.UploadRequester(); + // verify if file name has suffix + String filename = userInput.getText().toString(); + + if (!filename.endsWith(".txt")){ + filename += ".txt"; + } + requester.uploadNewFile( getBaseContext(), getAccount(), f.getAbsolutePath(), - mFile.getRemotePath() + userInput.getText() - + ".txt", + mFile.getRemotePath() + filename, FileUploader.LOCAL_BEHAVIOUR_COPY, null, true, From aa98938a553a38908d6438c7baf86cddfecc11f5 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Fri, 22 Jul 2016 15:53:03 +0200 Subject: [PATCH 14/33] textfile --> text file --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 0b68b93c51..10b3b8aa4e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -57,7 +57,7 @@ Files Connect Upload - Create textfile + Create text file Choose upload folder No account found There are no %1$s accounts on your device. Please set up an account first. From 351d7ba7c10adfe031dd2ace263e61cec81327fe Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Fri, 22 Jul 2016 17:15:33 +0200 Subject: [PATCH 15/33] changes due to CR --- .../activity/ReceiveExternalFilesActivity.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 7e54d74cf9..12a1ca28cf 100644 --- a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -40,8 +40,8 @@ import android.os.Bundle; import android.os.Parcelable; import android.support.v4.app.FragmentManager; import android.support.v7.app.ActionBar; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AlertDialog.Builder; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -100,6 +100,7 @@ public class ReceiveExternalFilesActivity extends FileActivity private static final String TAG = ReceiveExternalFilesActivity.class.getSimpleName(); private static final String FTAG_ERROR_FRAGMENT = "ERROR_FRAGMENT"; + public static final String TEXT_FILE_SUFFIX = ".txt"; private AccountManager mAccountManager; private Stack mParents; @@ -352,14 +353,15 @@ public class ReceiveExternalFilesActivity extends FileActivity alertDialogBuilder.setView(view); final EditText userInput = (EditText) view.findViewById(R.id.user_input); - userInput.setText(".txt"); + userInput.setText(TEXT_FILE_SUFFIX); alertDialogBuilder.setCancelable(false) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int id) { PrintWriter out; try { - File f = File.createTempFile("owncloud", ".txt"); + File f = File.createTempFile("nextcloud", + TEXT_FILE_SUFFIX); out = new PrintWriter(f); out.println(getIntent().getStringExtra( Intent.EXTRA_TEXT)); @@ -371,8 +373,8 @@ public class ReceiveExternalFilesActivity extends FileActivity // verify if file name has suffix String filename = userInput.getText().toString(); - if (!filename.endsWith(".txt")){ - filename += ".txt"; + if (!filename.endsWith(TEXT_FILE_SUFFIX)){ + filename += TEXT_FILE_SUFFIX; } requester.uploadNewFile( @@ -386,7 +388,7 @@ public class ReceiveExternalFilesActivity extends FileActivity UploadFileOperation.CREATED_BY_USER ); } catch (IOException e) { - e.printStackTrace(); + Log_OC.w(TAG, e.getMessage()); } finish(); From 3f364ff783cdadae08daaa14cfa0bfcbfc8c8fd4 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Fri, 22 Jul 2016 18:08:12 +0200 Subject: [PATCH 16/33] reformetted two lines --- .../android/ui/activity/ReceiveExternalFilesActivity.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 12a1ca28cf..a5ca029a63 100644 --- a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -360,11 +360,9 @@ public class ReceiveExternalFilesActivity extends FileActivity public void onClick(DialogInterface dialog,int id) { PrintWriter out; try { - File f = File.createTempFile("nextcloud", - TEXT_FILE_SUFFIX); + File f = File.createTempFile("nextcloud", TEXT_FILE_SUFFIX); out = new PrintWriter(f); - out.println(getIntent().getStringExtra( - Intent.EXTRA_TEXT)); + out.println(getIntent().getStringExtra(Intent.EXTRA_TEXT)); out.close(); FileUploader.UploadRequester requester = @@ -402,7 +400,6 @@ public class ReceiveExternalFilesActivity extends FileActivity alertDialogBuilder.create().show(); } else { - Log_OC.d(TAG, "Uploading file to dir " + mUploadPath); uploadFiles(); } From 6bf8b79831f3a1f0d8ea4a700fe1dbb5c9771470 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 16 Aug 2016 10:47:11 +0200 Subject: [PATCH 17/33] gradle update to 2.14.1 and android plugin update to 2.1.3 for security fixes --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- oc_jb_workaround/build.gradle | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 1073f7ed58..fb6cf704ac 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.2' + classpath 'com.android.tools.build:gradle:2.1.3' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e9ce5369f1..1b10fc6958 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Apr 07 22:12:15 CEST 2016 +#Tue Aug 16 10:44:46 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/oc_jb_workaround/build.gradle b/oc_jb_workaround/build.gradle index 91359378cb..5ae8e8ca2c 100644 --- a/oc_jb_workaround/build.gradle +++ b/oc_jb_workaround/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.2' + classpath 'com.android.tools.build:gradle:2.1.3' } } apply plugin: 'com.android.application' From 418790c3fa76024972f117e740381ef7ba8884a2 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 16 Aug 2016 11:28:42 +0200 Subject: [PATCH 18/33] mavenCentral()-->jcenter() --- build.gradle | 4 ++-- oc_jb_workaround/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index fb6cf704ac..6e80c65cc5 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { repositories { - mavenCentral() + jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.3' @@ -21,7 +21,7 @@ ext { } repositories { - mavenCentral() + jcenter() maven { url "https://jitpack.io" } flatDir { diff --git a/oc_jb_workaround/build.gradle b/oc_jb_workaround/build.gradle index 5ae8e8ca2c..d83bc52279 100644 --- a/oc_jb_workaround/build.gradle +++ b/oc_jb_workaround/build.gradle @@ -1,6 +1,6 @@ buildscript { repositories { - mavenCentral() + jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.3' From afd7af872a9625f546515a49d305e5b1b5bddc3d Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 16 Aug 2016 16:13:58 +0200 Subject: [PATCH 19/33] nicer play badge see preview of the readme --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 40afcda8a8..aabaf6e965 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,12 @@ -# [Nextcloud](https://nextcloud.com) Android app +# [Nextcloud](https://nextcloud.com) Android app ![](https://api.travis-ci.org/nextcloud/android.svg?branch=master) -[Download from Google Play](https://play.google.com/store/apps/details?id=com.nextcloud.client) - [Get it on F-Droid](https://f-droid.org/repository/browse/?fdfilter=com.nextcloud) -**Build status:** master ![](https://api.travis-ci.org/nextcloud/android.svg?branch=master) - [![irc](https://img.shields.io/badge/IRC-%23nextcloud%20on%20freenode-orange.svg)](https://webchat.freenode.net/?channels=nextcloud) [![irc](https://img.shields.io/badge/IRC-%23nextcloud--mobile%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-mobile) From c2f351964866404910d4124347ba829609840095 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Wed, 17 Aug 2016 00:33:47 +0000 Subject: [PATCH 20/33] [tx-robot] updated from transifex --- res/values-de-rDE/strings.xml | 4 ++-- res/values-fr/strings.xml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index 4293c65ea6..b6531d82e9 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -177,9 +177,9 @@ %1$s (abspielend) %1$s (lädt) %1$s Wiedergabe beendet - Keine Mediadatei gefunden + Keine Mediendatei gefunden Kein Account angegeben - Datei nicht in einem gültigen Account + Datei ist nicht in einem gültigen Account Nicht unterstützter Media-codec Mediendatei konnte nicht gelesen werden Mediendatei nicht korrekt kodiert diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 89ce1f7a2a..ce71aa23ca 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -13,7 +13,7 @@ Détails Envoyer Trier - Trier + Trier par par ordre alphabétique du plus récent au plus ancien @@ -22,20 +22,20 @@ Tous les fichiers Sur le périphérique Paramètres - Chargements + Téléversements Fermer Ouvrir Général Plus Comptes - Gestion des comptes utilisateur + Gestion des comptes Code de sécurité Téléversement immédiat des photos Téléverser immédiatement les photos prises par la caméra Téléversement immédiat des vidéos Téléverser immédiatement les vidéos prises par la caméra Activer la journalisation - Utilisé pour enregistrer les problèmes dans les logs + Utilisé pour la journalisation des problèmes Historique de la journalisation Cela affiche les logs enregistrés Supprimer l\'historique From e790d4a52073ccfef292f454dc55af5e9221c9a1 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 8 Aug 2016 17:27:47 +0200 Subject: [PATCH 21/33] initial layout changes for in drawer quota display --- res/layout/drawer.xml | 38 ++++++++++++++++++++++++++++++++++++-- res/menu/drawer_menu.xml | 11 +++++++++++ res/values/strings.xml | 1 + 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/res/layout/drawer.xml b/res/layout/drawer.xml index 843a1ebdf3..ff17ea3e5d 100644 --- a/res/layout/drawer.xml +++ b/res/layout/drawer.xml @@ -24,9 +24,43 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" + android:layout_weight="1" android:fitsSystemWindows="true" - app:theme="@style/NavigationView_ItemTextAppearance" app:headerLayout="@layout/drawer_header" - app:menu="@menu/drawer_menu"/> + app:menu="@menu/drawer_menu" + app:theme="@style/NavigationView_ItemTextAppearance"> + + + + + + + + + \ No newline at end of file diff --git a/res/menu/drawer_menu.xml b/res/menu/drawer_menu.xml index 9551b98274..7c6462f8e8 100644 --- a/res/menu/drawer_menu.xml +++ b/res/menu/drawer_menu.xml @@ -67,4 +67,15 @@ android:icon="@drawable/ic_settings" android:title="@string/actionbar_settings"/> + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 10b3b8aa4e..4f6d9d7cf6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -23,6 +23,7 @@ On device Settings Uploads + %1$s%2$s of %3$s%4$s used Close Open General From f8e0ee9ce1a89c3b724c70d794396245fb976fb3 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 8 Aug 2016 18:41:45 +0200 Subject: [PATCH 22/33] initial quota display implementation --- res/values/strings.xml | 2 +- .../android/ui/activity/DrawerActivity.java | 49 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4f6d9d7cf6..259a93884d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -23,7 +23,7 @@ On device Settings Uploads - %1$s%2$s of %3$s%4$s used + %1$s of %2$s used Close Open General diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index bab0cde0a3..e8663796ed 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -38,6 +38,8 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; import android.widget.TextView; import com.owncloud.android.MainApp; @@ -120,6 +122,9 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU * accounts for the (max) three displayed accounts in the drawer header. */ private Account[] mAvatars = new Account[3]; + private LinearLayout mQuotaView; + private ProgressBar mQuotaProgressBar; + private TextView mQuotaTextView; /** * Initializes the drawer, its content and highlights the menu item with the given id. @@ -144,9 +149,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU mAccountChooserToggle = (ImageView) findNavigationViewChildById(R.id.drawer_account_chooser_toogle); mAccountChooserToggle.setImageResource(R.drawable.ic_down); mIsAccountChooserActive = false; - - mAccountMiddleAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle); - mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end); + mAccountMiddleAccountAvatar = (ImageView) findViewById(R.id.drawer_account_middle); + mAccountEndAccountAvatar = (ImageView) findViewById(R.id.drawer_account_end); // on pre lollipop the light theme adds a black tint to icons with white coloring // ruining the generic avatars, so tinting for icons is deactivated pre lollipop @@ -163,6 +167,12 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU toggleAccountList(); } }); + + // Quota UI elements + mQuotaView = (LinearLayout) findNavigationViewChildById(R.id.drawer_quota); + mQuotaProgressBar = (ProgressBar) findNavigationViewChildById(R.id.drawer_quota_ProgressBar); + mQuotaTextView = (TextView) findNavigationViewChildById(R.id.drawer_quota_text); + DisplayUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar); } mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) { @@ -477,6 +487,39 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU } } + /** + * shows or hides the quota UI elements. + * + * @param showQuota show/hide quota information + */ + private void showQuota(boolean showQuota) { + if (showQuota) { + mQuotaView.setVisibility(View.VISIBLE); + } else { + mQuotaView.setVisibility(View.GONE); + } + } + + /** + * configured the quota to be displayed. + * + * @param usedSpace the used space + * @param totalSpace the total space + * @param percent the percentage of space already used + */ + private void setQuotaInformation(long usedSpace, long totalSpace, Double percent) { + int progress = (int) Math.ceil(percent); + mQuotaProgressBar.setProgress(progress); + mQuotaTextView.setText(String.format( + getString(R.string.drawer_quota), + DisplayUtils.bytesToHumanReadable(usedSpace), + DisplayUtils.bytesToHumanReadable(totalSpace))); + + // TODO Think about coloring of the progressbar at certain thresholds + + showQuota(true); + } + /** * checks/highlights the provided menu item if the drawer has been initialized and the menu item exists. * From 3658becdf58c6b5ea1fd12f34d5ce56d878e4fb8 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 9 Aug 2016 00:32:34 +0200 Subject: [PATCH 23/33] view elements fix --- .../owncloud/android/ui/activity/DrawerActivity.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index e8663796ed..33cc82f9ee 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -149,8 +149,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU mAccountChooserToggle = (ImageView) findNavigationViewChildById(R.id.drawer_account_chooser_toogle); mAccountChooserToggle.setImageResource(R.drawable.ic_down); mIsAccountChooserActive = false; - mAccountMiddleAccountAvatar = (ImageView) findViewById(R.id.drawer_account_middle); - mAccountEndAccountAvatar = (ImageView) findViewById(R.id.drawer_account_end); + mAccountMiddleAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle); + mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end); // on pre lollipop the light theme adds a black tint to icons with white coloring // ruining the generic avatars, so tinting for icons is deactivated pre lollipop @@ -169,9 +169,9 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU }); // Quota UI elements - mQuotaView = (LinearLayout) findNavigationViewChildById(R.id.drawer_quota); - mQuotaProgressBar = (ProgressBar) findNavigationViewChildById(R.id.drawer_quota_ProgressBar); - mQuotaTextView = (TextView) findNavigationViewChildById(R.id.drawer_quota_text); + mQuotaView = (LinearLayout) findViewById(R.id.drawer_quota); + mQuotaProgressBar = (ProgressBar) findViewById(R.id.drawer_quota_ProgressBar); + mQuotaTextView = (TextView) findViewById(R.id.drawer_quota_text); DisplayUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar); } From 07c3ebdf84bff52292562b9c1b1cc1dc0429ab73 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 9 Aug 2016 10:58:13 +0200 Subject: [PATCH 24/33] update to Nc Android library 1.0.4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6e80c65cc5..b62cc2eab7 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { /// dependencies for app building compile name: 'touch-image-view' - compile 'com.github.nextcloud:android-library:1.0.2' + compile 'com.github.nextcloud:android-library:1.0.4' compile "com.android.support:support-v4:${supportLibraryVersion}" compile "com.android.support:design:${supportLibraryVersion}" compile 'com.jakewharton:disklrucache:2.0.2' From 217658740f7ab945eb09ecb3a5aeecc9037f7e56 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 9 Aug 2016 19:09:00 +0200 Subject: [PATCH 25/33] get and show quota information --- .../android/ui/activity/DrawerActivity.java | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 33cc82f9ee..dd85aa68da 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -47,7 +47,10 @@ import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudAccount; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.users.RemoteGetUserQuotaOperation; import com.owncloud.android.ui.TextDrawable; import com.owncloud.android.utils.DisplayUtils; @@ -459,6 +462,9 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU DisplayUtils.setAvatar(account, this, mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager(), findNavigationViewChildById(R.id.drawer_current_account)); + + // check and show quota info if available + getUserQuota(); } } @@ -505,11 +511,10 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU * * @param usedSpace the used space * @param totalSpace the total space - * @param percent the percentage of space already used + * @param relative the percentage of space already used */ - private void setQuotaInformation(long usedSpace, long totalSpace, Double percent) { - int progress = (int) Math.ceil(percent); - mQuotaProgressBar.setProgress(progress); + private void setQuotaInformation(long usedSpace, long totalSpace, int relative) { + mQuotaProgressBar.setProgress(relative); mQuotaTextView.setText(String.format( getString(R.string.drawer_quota), DisplayUtils.bytesToHumanReadable(usedSpace), @@ -535,6 +540,43 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU } } + /** + * Retrieves and shows the user quota if available + */ + private void getUserQuota() { + // set user space information + Thread t = new Thread(new Runnable() { + public void run() { + + RemoteOperation getQuotaInfoOperation = new RemoteGetUserQuotaOperation(); + RemoteOperationResult result = getQuotaInfoOperation.execute( + AccountUtils.getCurrentOwnCloudAccount(DrawerActivity.this), DrawerActivity.this); + + if (result.isSuccess() && result.getData() != null) { + RemoteGetUserQuotaOperation.Quota quota = (RemoteGetUserQuotaOperation.Quota) result.getData().get + (0); + + final long used = quota.getUsed(); + final long total = quota.getTotal(); + final int relative = (int) Math.ceil(quota.getRelative()); + + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mQuotaView != null) { + setQuotaInformation(used,total,relative); + } else { + showQuota(false); + } + } + }); + } + } + }); + + t.start(); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); From 2c941a574996fbbb6be8798b19d7c9b215c2fffe Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 10 Aug 2016 12:22:48 +0200 Subject: [PATCH 26/33] minor code refactoring extracting setup code into dedicated methods --- .../android/ui/activity/DrawerActivity.java | 84 ++++++++++++------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index dd85aa68da..7cee535fb0 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -149,35 +149,22 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU mNavigationView = (NavigationView) findViewById(R.id.nav_view); if (mNavigationView != null) { - mAccountChooserToggle = (ImageView) findNavigationViewChildById(R.id.drawer_account_chooser_toogle); - mAccountChooserToggle.setImageResource(R.drawable.ic_down); - mIsAccountChooserActive = false; - mAccountMiddleAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle); - mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end); + setupDrawerHeader(); - // on pre lollipop the light theme adds a black tint to icons with white coloring - // ruining the generic avatars, so tinting for icons is deactivated pre lollipop - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - mNavigationView.setItemIconTintList(null); - } + setupDrawerMenu(mNavigationView); - setupDrawerContent(mNavigationView); - - findNavigationViewChildById(R.id.drawer_active_user) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - toggleAccountList(); - } - }); - - // Quota UI elements - mQuotaView = (LinearLayout) findViewById(R.id.drawer_quota); - mQuotaProgressBar = (ProgressBar) findViewById(R.id.drawer_quota_ProgressBar); - mQuotaTextView = (TextView) findViewById(R.id.drawer_quota_text); - DisplayUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar); + setupQuotaElement(); } + setupDrawerToggle(); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + /** + * initializes and sets up the drawer toggle. + */ + private void setupDrawerToggle() { mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) { /** Called when a drawer has settled in a completely closed state. */ @@ -201,7 +188,35 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU // Set the drawer toggle as the DrawerListener mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerToggle.setDrawerIndicatorEnabled(true); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + /** + * initializes and sets up the drawer header. + */ + private void setupDrawerHeader() { + mAccountChooserToggle = (ImageView) findNavigationViewChildById(R.id.drawer_account_chooser_toogle); + mAccountChooserToggle.setImageResource(R.drawable.ic_down); + mIsAccountChooserActive = false; + mAccountMiddleAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle); + mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end); + + findNavigationViewChildById(R.id.drawer_active_user) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + toggleAccountList(); + } + }); + } + + /** + * setup quota elements of the drawer. + */ + private void setupQuotaElement() { + mQuotaView = (LinearLayout) findViewById(R.id.drawer_quota); + mQuotaProgressBar = (ProgressBar) findViewById(R.id.drawer_quota_ProgressBar); + mQuotaTextView = (TextView) findViewById(R.id.drawer_quota_text); + DisplayUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar); } /** @@ -209,7 +224,14 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU * * @param navigationView the drawers navigation view */ - protected void setupDrawerContent(NavigationView navigationView) { + protected void setupDrawerMenu(NavigationView navigationView) { + // on pre lollipop the light theme adds a black tint to icons with white coloring + // ruining the generic avatars, so tinting for icons is deactivated pre lollipop + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + navigationView.setItemIconTintList(null); + } + + // setup actions for drawer menu items navigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override @@ -259,9 +281,9 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU // handle correct state if (mIsAccountChooserActive) { - mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, true); + navigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, true); } else { - mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, false); + navigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, false); } } @@ -464,7 +486,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU findNavigationViewChildById(R.id.drawer_current_account)); // check and show quota info if available - getUserQuota(); + getAndDisplayUserQuota(); } } @@ -543,7 +565,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU /** * Retrieves and shows the user quota if available */ - private void getUserQuota() { + private void getAndDisplayUserQuota() { // set user space information Thread t = new Thread(new Runnable() { public void run() { From 5280d66139c3198c592890479bf90e5ec5ccfb9f Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 10 Aug 2016 14:55:13 +0200 Subject: [PATCH 27/33] colorize quota progress bar depending on thresholds met, reformattings --- res/values/colors.xml | 6 ++ .../android/ui/activity/DrawerActivity.java | 16 +++- .../owncloud/android/utils/DisplayUtils.java | 75 +++++++++++++------ 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/res/values/colors.xml b/res/values/colors.xml index 201060c8c6..3252a60f75 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -52,4 +52,10 @@ #201D2D44 #40162233 + + + @color/color_accent + #fdd835 + #e57373 + \ No newline at end of file diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 7cee535fb0..77b9ba37be 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -125,8 +125,20 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU * accounts for the (max) three displayed accounts in the drawer header. */ private Account[] mAvatars = new Account[3]; + + /** + * container layout of the quota view. + */ private LinearLayout mQuotaView; + + /** + * progress bar of the quota view. + */ private ProgressBar mQuotaProgressBar; + + /** + * text view of the quota view. + */ private TextView mQuotaTextView; /** @@ -537,13 +549,13 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU */ private void setQuotaInformation(long usedSpace, long totalSpace, int relative) { mQuotaProgressBar.setProgress(relative); + DisplayUtils.colorHorizontalProgressBar(mQuotaProgressBar, DisplayUtils.getRelativeInfoColor(this, relative)); + mQuotaTextView.setText(String.format( getString(R.string.drawer_quota), DisplayUtils.bytesToHumanReadable(usedSpace), DisplayUtils.bytesToHumanReadable(totalSpace))); - // TODO Think about coloring of the progressbar at certain thresholds - showQuota(true); } diff --git a/src/com/owncloud/android/utils/DisplayUtils.java b/src/com/owncloud/android/utils/DisplayUtils.java index c9a81a9a61..949ea69ba2 100644 --- a/src/com/owncloud/android/utils/DisplayUtils.java +++ b/src/com/owncloud/android/utils/DisplayUtils.java @@ -64,16 +64,16 @@ import java.util.Map; */ public class DisplayUtils { private static final String TAG = DisplayUtils.class.getSimpleName(); - - private static final String OWNCLOUD_APP_NAME = "ownCloud"; - + private static final String[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; private static final int[] sizeScales = { 0, 0, 1, 1, 1, 2, 2, 2, 2 }; + public static final int RELATIVE_THRESHOLD_WARNING = 90; + public static final int RELATIVE_THRESHOLD_CRITICAL = 95; private static Map mimeType2HumanReadable; static { - mimeType2HumanReadable = new HashMap(); + mimeType2HumanReadable = new HashMap<>(); // images mimeType2HumanReadable.put("image/jpeg", "JPEG image"); mimeType2HumanReadable.put("image/jpg", "JPEG image"); @@ -155,9 +155,9 @@ public class DisplayUtils { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { // Find host name after '//' or '@' int hostStart = 0; - if (urlNoDots.indexOf("//") != -1) { + if (urlNoDots.contains("//")) { hostStart = url.indexOf("//") + "//".length(); - } else if (url.indexOf("@") != -1) { + } else if (url.contains("@")) { hostStart = url.indexOf("@") + "@".length(); } @@ -207,17 +207,33 @@ public class DisplayUtils { DateUtils.WEEK_IN_MILLIS, 0); } - @SuppressWarnings("deprecation") - public static CharSequence getRelativeDateTimeString ( - Context c, long time, long minResolution, long transitionResolution, int flags - ){ - + /** + * determines the info level color based on certain thresholds + * {@link #RELATIVE_THRESHOLD_WARNING} and {@link #RELATIVE_THRESHOLD_CRITICAL}. + * + * @param context the app's context + * @param relative relative value for which the info level color should be looked up + * @return info level color + */ + public static int getRelativeInfoColor(Context context, int relative) { + if (relative < RELATIVE_THRESHOLD_WARNING) { + return context.getResources().getColor(R.color.infolevel_info); + } else if (relative >= RELATIVE_THRESHOLD_WARNING && relative < RELATIVE_THRESHOLD_CRITICAL) { + return context.getResources().getColor(R.color.infolevel_warning); + } else { + return context.getResources().getColor(R.color.infolevel_critical); + } + } + + public static CharSequence getRelativeDateTimeString( + Context c, long time, long minResolution, long transitionResolution, int flags) { + CharSequence dateString = ""; - + // in Future - if (time > System.currentTimeMillis()){ + if (time > System.currentTimeMillis()) { return DisplayUtils.unixTimeToHumanReadable(time); - } + } // < 60 seconds -> seconds ago else if ((System.currentTimeMillis() - time) < 60 * 1000) { return c.getString(R.string.file_list_seconds_ago); @@ -238,8 +254,9 @@ public class DisplayUtils { } /** - * Update the passed path removing the last "/" if it is not the root folder - * @param path + * Update the passed path removing the last "/" if it is not the root folder. + * + * @param path the path to be trimmed */ public static String getPathWithoutLastSlash(String path) { @@ -250,12 +267,11 @@ public class DisplayUtils { return path; } - /** - * Gets the screen size in pixels in a backwards compatible way + * Gets the screen size in pixels in a backwards compatible way. * - * @param caller Activity calling; needed to get access to the {@link android.view.WindowManager} - * @return Size in pixels of the screen, or default {@link Point} if caller is null + * @param caller Activity calling; needed to get access to the {@link android.view.WindowManager} + * @return Size in pixels of the screen, or default {@link Point} if caller is null */ public static Point getScreenSize(Activity caller) { Point size = new Point(); @@ -277,7 +293,18 @@ public class DisplayUtils { */ public static void colorPreLollipopHorizontalProgressBar(ProgressBar progressBar) { if (progressBar != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - int color = progressBar.getResources().getColor(R.color.color_accent); + colorHorizontalProgressBar(progressBar, progressBar.getResources().getColor(R.color.color_accent)); + } + } + + /** + * sets the coloring of the given progress bar to color_accent. + * + * @param progressBar the progress bar to be colored + * @param color the color to be used + */ + public static void colorHorizontalProgressBar(ProgressBar progressBar, @ColorInt int color) { + if (progressBar != null) { progressBar.getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN); progressBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN); } @@ -315,7 +342,7 @@ public class DisplayUtils { * Sets the color of the status bar to {@code color} on devices with OS version lollipop or higher. * * @param fragmentActivity fragment activity - * @param color the color + * @param color the color */ public static void colorStatusBar(FragmentActivity fragmentActivity, @ColorInt int color) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -326,11 +353,11 @@ public class DisplayUtils { /** * Sets the color of the progressbar to {@code color} within the given toolbar. * - * @param activity the toolbar activity instance + * @param activity the toolbar activity instance * @param progressBarColor the color to be used for the toolbar's progress bar */ public static void colorToolbarProgressBar(FragmentActivity activity, int progressBarColor) { - if(activity instanceof ToolbarActivity) { + if (activity instanceof ToolbarActivity) { ((ToolbarActivity) activity).setProgressBarBackgroundColor(progressBarColor); } } From 0f80bdc894346ac9362f1e6e19a30acc2da3f33f Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Sun, 14 Aug 2016 20:13:47 +0200 Subject: [PATCH 28/33] CR changes --- res/layout/drawer.xml | 1 - .../android/ui/activity/DrawerActivity.java | 4 +- .../owncloud/android/utils/DisplayUtils.java | 41 ++++++++++++++++--- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/res/layout/drawer.xml b/res/layout/drawer.xml index ff17ea3e5d..3892505f3c 100644 --- a/res/layout/drawer.xml +++ b/res/layout/drawer.xml @@ -35,7 +35,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" - android:background="#F5F5F5" android:clickable="false" android:orientation="vertical" android:paddingBottom="@dimen/standard_half_padding" diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 77b9ba37be..78270003f5 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -553,8 +553,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU mQuotaTextView.setText(String.format( getString(R.string.drawer_quota), - DisplayUtils.bytesToHumanReadable(usedSpace), - DisplayUtils.bytesToHumanReadable(totalSpace))); + DisplayUtils.quotaBytesToHumanReadable(usedSpace), + DisplayUtils.quotaBytesToHumanReadable(totalSpace))); showQuota(true); } diff --git a/src/com/owncloud/android/utils/DisplayUtils.java b/src/com/owncloud/android/utils/DisplayUtils.java index 949ea69ba2..0a89597ce1 100644 --- a/src/com/owncloud/android/utils/DisplayUtils.java +++ b/src/com/owncloud/android/utils/DisplayUtils.java @@ -67,6 +67,7 @@ public class DisplayUtils { private static final String[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; private static final int[] sizeScales = { 0, 0, 1, 1, 1, 2, 2, 2, 2 }; + private static final int[] quotaSizeScales = { 0, 0, 0, 1, 1, 2, 2, 2, 2 }; public static final int RELATIVE_THRESHOLD_WARNING = 90; public static final int RELATIVE_THRESHOLD_CRITICAL = 95; @@ -95,18 +96,48 @@ public class DisplayUtils { * * * @param bytes Input file size - * @return Like something readable like "12 MB" + * @return something readable like "12 MB" */ public static String bytesToHumanReadable(long bytes) { + return bytesToHumanReadable(bytes, sizeScales, sizeSuffixes); + } + + /** + * Converts the file size in bytes to human readable output. + *
    + *
  • appends a size suffix, e.g. B, KB, MB etc.
  • + *
  • rounds the size based on the suffix to 0,1 or 2 decimals
  • + *
+ * + * @param bytes Input file size + * @return something readable like "12 MB" + */ + public static String quotaBytesToHumanReadable(long bytes) { + return bytesToHumanReadable(bytes, quotaSizeScales, sizeSuffixes); + } + + /** + * Converts the file size in bytes to human readable output. + *
    + *
  • appends a size suffix, e.g. B, KB, MB etc.
  • + *
  • rounds the size based on the suffix to 0,1 or 2 decimals
  • + *
+ * + * @param bytes Input file size + * @param sizeScales scales for the different size units + * @param sizeSuffixes suffixes for the different size units + * @return something readable like "12 MB" + */ + private static String bytesToHumanReadable(long bytes, int[] sizeScales, String[] sizeSuffixes) { double result = bytes; - int attachedSuff = 0; - while (result > 1024 && attachedSuff < sizeSuffixes.length) { + int suffixIndex = 0; + while (result > 1024 && suffixIndex < sizeSuffixes.length) { result /= 1024.; - attachedSuff++; + suffixIndex++; } return new BigDecimal(result).setScale( - sizeScales[attachedSuff], BigDecimal.ROUND_HALF_UP) + " " + sizeSuffixes[attachedSuff]; + sizeScales[suffixIndex], BigDecimal.ROUND_HALF_UP) + " " + sizeSuffixes[suffixIndex]; } /** From 457027a1968250d46d02c93998e8e0aedccb789d Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Sun, 14 Aug 2016 20:26:08 +0200 Subject: [PATCH 29/33] fixed the background color --- res/layout/drawer.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/layout/drawer.xml b/res/layout/drawer.xml index 3892505f3c..cca0b25ba3 100644 --- a/res/layout/drawer.xml +++ b/res/layout/drawer.xml @@ -35,6 +35,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" + android:background="@color/white" android:clickable="false" android:orientation="vertical" android:paddingBottom="@dimen/standard_half_padding" From b29744c00487dcf1831295a660389a3af088debb Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 31 Aug 2016 19:05:50 +0200 Subject: [PATCH 30/33] show quota for server without quota-unlimited info capability --- build.gradle | 2 +- .../android/ui/activity/DrawerActivity.java | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index b62cc2eab7..098dc8ed75 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { /// dependencies for app building compile name: 'touch-image-view' - compile 'com.github.nextcloud:android-library:1.0.4' + compile 'com.github.nextcloud:android-library:1.0.6' compile "com.android.support:support-v4:${supportLibraryVersion}" compile "com.android.support:design:${supportLibraryVersion}" compile 'com.jakewharton:disklrucache:2.0.2' diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 78270003f5..555aa9044f 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -587,19 +587,33 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU AccountUtils.getCurrentOwnCloudAccount(DrawerActivity.this), DrawerActivity.this); if (result.isSuccess() && result.getData() != null) { - RemoteGetUserQuotaOperation.Quota quota = (RemoteGetUserQuotaOperation.Quota) result.getData().get - (0); + final RemoteGetUserQuotaOperation.Quota quota = + (RemoteGetUserQuotaOperation.Quota) result.getData().get(0); final long used = quota.getUsed(); final long total = quota.getTotal(); final int relative = (int) Math.ceil(quota.getRelative()); + final long quotaValue = quota.getQuota(); runOnUiThread(new Runnable() { @Override public void run() { - if (mQuotaView != null) { - setQuotaInformation(used,total,relative); + if (quotaValue > 0 + || quotaValue == RemoteGetUserQuotaOperation.QUOTA_LIMIT_INFO_NOT_AVAILABLE) { + /** + * show quota in case + * it is available and calculated (> 0) or + * in case of legacy servers (==QUOTA_LIMIT_INFO_NOT_AVAILABLE) + */ + setQuotaInformation(used, total, relative); } else { + /** + * quotaValue < 0 means special cases like + * {@link RemoteGetUserQuotaOperation.SPACE_NOT_COMPUTED}, + * {@link RemoteGetUserQuotaOperation.SPACE_UNKNOWN} or + * {@link RemoteGetUserQuotaOperation.SPACE_UNLIMITED} + * thus don't display any quota information. + */ showQuota(false); } } From 2326d4b32ad3ad73bbbc3359b4d2ba95905618ae Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 1 Sep 2016 00:34:00 +0000 Subject: [PATCH 31/33] [tx-robot] updated from transifex --- res/values-cs-rCZ/strings.xml | 1 + res/values-de-rDE/strings.xml | 3 ++- res/values-de/strings.xml | 13 +++++++------ res/values-es/strings.xml | 6 +++++- res/values-fr/strings.xml | 1 + res/values-is/strings.xml | 35 +++++++++++++++++++++++++++++++++-- res/values-it/strings.xml | 1 + res/values-nl/strings.xml | 1 + 8 files changed, 51 insertions(+), 10 deletions(-) diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 2e355c7a7f..af22994464 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -57,6 +57,7 @@ Soubory Připojit Nahrát + Vytvořit textový soubor Vybrat adresář k nahrávání Nenalezen žádný účet Na tomto přístroji nejsou žádné %1$s účty. Nejdříve prosím zadejte účet. diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index b6531d82e9..d84f1a2b35 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -57,6 +57,7 @@ Dateien Verbinden Hochladen + Erstelle Textdatei Hochladeordner auswählen Kein Konto gefunden Es sind keine %1$s-Konten auf Ihrem Gerät eingerichtet. Bitte richten Sie zuerst ein Konto ein. @@ -106,7 +107,7 @@ Passwort ändern Benutzerkonto löschen Das Konto %s löschen?\n\nDas Löschen kann nicht rückgängig gemacht werden. - Account erstellen + Konto erstellen Dateien hochladen von... Ordnername Hochladen... diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index e5cc14a5d4..c99e9c38f3 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -36,7 +36,7 @@ Lade Videos von der Kamera sofort hoch Protokollierung aktivieren Dies wird zur Protokollierung von Problemen genutzt - Log Historie + Protokollierungs-Historie Dies zeigt die gespeicherten Protokollierungen Verlauf löschen Hilfe @@ -57,6 +57,7 @@ Dateien Verbinden Hochladen + Erstelle Textdatei Hochladeordner auswählen Kein Konto gefunden Es sind keine %1$s Konten auf deinem Gerät eingerichtet. Bitte erstelle zuerst ein Konto. @@ -174,8 +175,8 @@ PIN gespeichert %1$s Musik Player - %1$s (playing) - %1$s (loading) + %1$s (wird abgespielt) + %1$s (wird geladen) %1$s Beendet Keine Mediendatei gefunden Kein Konto angegeben @@ -189,9 +190,9 @@ Sicherheitsfehler beim Versuch %1$s zu spielen Eingabefehler beim Versuch %1$s wiederzugeben Ein unerwarteter Fehler ist aufgetreten beim Versuch %1$s abzuspielen - Zurückspielen Knopf - Play-/Pause Knopf - Vorspulen Knopf + Rückspulknopf + Wiedergabe-/Pause Knopf + Vorspul Knopf Genehmigung bekommen ... Der Versuch, sich anzumelden ... diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 9bd9cb0bb7..6c701c9cde 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -57,6 +57,7 @@ Archivos Conectar Subir + Crear archivo de texto Elige carpeta de subida No se encontró la cuenta No hay %1$s cuentas en tu dispositivo. Por favor añade una cuenta primero. @@ -303,6 +304,7 @@ No se puede mostrar la imagen %1$s se pudo copiar a la carpeta local %2$s + Carpeta para subida instantánea Usar subcarpeta Archivar en subcarpetas basadas en año y mes. @@ -376,7 +378,8 @@ Subidas instantáneas Detalles - La sincronización de la carpeta %1$s no se pudo completar + Carpeta para subida instantáneo de vídeos + La sincronización de la carpeta %1$s no se pudo completar compartido con usted @@ -454,6 +457,7 @@ El archivo no se encuentra en el servidor local de archivos. ¿Está seguro de que quiere eliminar los elementos seleccionados? ¿Está sguro de que quiere eliminar los elementos seleccionados y sus contenidos? + Buscar %d seleccionado %d seleccionados diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index ce71aa23ca..3fe31b3870 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -58,6 +58,7 @@ Téléchargez-le ici : %2$s
Fichiers Connecter Téléverser + Créer un fichier texte Choisir le dossier de téléversement Aucun compte n\'a été trouvé Aucun compte %1$s sur l\'appareil. Veuillez configurer un compte au préalable. diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 34c09cae7d..5725d69b59 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -57,11 +57,14 @@ Skrár Tengjast Senda inn + Búa til textaskrá + Veldu innsendingarmöppu Enginn notandaaðgangur fannst Það eru engir %1$s aðgangar á tækinu þínu. Settu fyrst upp notandaaðgang. Uppsetning Hætta Engin skrá til að senda inn + Ekki tókst að senda inn skrá sek. Ekkert hér. Settu eitthvað inn! Hleð inn… @@ -84,6 +87,8 @@ Nei Í lagi + Fjarlægja innsendingu + Reyna aftur að senda inn Hætta við samstillingu Hætta við Til baka @@ -105,14 +110,17 @@ Innsending mistókst Ekki var hægt að ljúka innsendingu á %1$s Innsending mistókst, þú verður að skrá þig inn aftur + Innsendingar Núverandi Hlaðið inn Lokið Hætt við Í bið Villa við tengingu + Villa í auðkennum Villa í möppu Villa í skrá + Villa í heimildum Árekstur Óþekkt villa Bíð eftir þráðlausri tengingu @@ -278,7 +286,10 @@ Ekki er hægt að birta myndina %1$s var ekki hægt að afrita í staðværu %2$s möppuna - Því miður, deiling gagna er ekki virk á þjóninum. Hafðu samband við + Nota undirmöppur + Geyma í undirmöppum byggðum á ári og mánuðum + + Því miður, deiling gagna er ekki virk á þjóninum. Hafðu samband við kerfisstjóra. Get ekki deilt. Athugaðu hvort skráin sé til Villa kom upp við að reyna að deila þessari skrá eða möppu @@ -293,6 +304,9 @@ Afrita tengil Afritað á klippispjaldið + Óvænt villa kom upp við afritun á klippispjald + Texti afritaður úr %1$s + Alvarleg villa: get ekki framkvæmt aðgerðir Villa kom upp við að tengjast við þjóninn. @@ -311,6 +325,7 @@ Notandaaðgangar Bæta við notandaaðgangi + Sýsla með notandaaðganga Öruggri tengingu er endurbeint í gegnum óörugga leið. Annálar @@ -365,6 +380,8 @@ Upprunaleg skrá verður... Afrita skrá Færa skrá + Velja allt + áfram í upprunalegri möppu færð í forritsmöppu @@ -399,6 +416,11 @@ Hætta deilingu lokið + Mistókst að reyna aftur + Hreinsun mistókst + Hreinsun tókst + Hreinsa allt klárað + Reitir Listi @@ -407,4 +429,13 @@ Ekki tókst að eyða öllum skrám. Aukinna heimilda er krafist til að geta sent inn og sótt skrár. - + Skráin fannst ekki á staðværu skráakerfi + Ertu viss um að þú viljir fjarlægja valin atriði? + Ertu viss um að þú viljir fjarlægja valin atriði og innihald þeirra? + Leita + + %d valið + %d valið + + + diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 9a79d1e3b2..7260f8cc3e 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -57,6 +57,7 @@ File Connetti Carica + Crea file di testo Scegli la cartella di caricamento Nessun account trovato Non ci sono account %1$s sul tuo dispositivo. Configura prima un account. diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index c2e41370c7..866cb1d2cb 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -58,6 +58,7 @@ Download hier: %2$s Bestanden Verbinden Uploaden + Creëren tekstbestand Kies een uploadmap Geen account gevonden Er zijn geen %1$s accounts op dit apparaat. Stel eerst een account in. From 4f32abfafe1ba0f57679576d00cd1bc68948e05e Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 1 Sep 2016 10:12:02 +0200 Subject: [PATCH 32/33] sizeScale 1 for MB, code removed for unsupported legacy Android versions --- .../android/ui/activity/DrawerActivity.java | 4 +- .../owncloud/android/utils/DisplayUtils.java | 74 ++++++------------- 2 files changed, 23 insertions(+), 55 deletions(-) diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 555aa9044f..7b81013aad 100644 --- a/src/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/src/com/owncloud/android/ui/activity/DrawerActivity.java @@ -553,8 +553,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU mQuotaTextView.setText(String.format( getString(R.string.drawer_quota), - DisplayUtils.quotaBytesToHumanReadable(usedSpace), - DisplayUtils.quotaBytesToHumanReadable(totalSpace))); + DisplayUtils.bytesToHumanReadable(usedSpace), + DisplayUtils.bytesToHumanReadable(totalSpace))); showQuota(true); } diff --git a/src/com/owncloud/android/utils/DisplayUtils.java b/src/com/owncloud/android/utils/DisplayUtils.java index 0a89597ce1..6ad06093fd 100644 --- a/src/com/owncloud/android/utils/DisplayUtils.java +++ b/src/com/owncloud/android/utils/DisplayUtils.java @@ -1,23 +1,25 @@ /** - * ownCloud Android client application + * Nextcloud Android client application * + * @author Andy Scherzinger * @author Bartek Przybylski * @author David A. Velasco * Copyright (C) 2011 Bartek Przybylski * Copyright (C) 2015 ownCloud Inc. + * Copyright (C) 2016 Andy Scherzinger * - * 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 free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 . + * 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 . */ package com.owncloud.android.utils; @@ -37,7 +39,6 @@ import android.support.design.widget.Snackbar; import android.support.v4.app.FragmentActivity; import android.support.v4.content.ContextCompat; import android.text.format.DateUtils; -import android.view.Display; import android.view.View; import android.widget.ProgressBar; import android.widget.SeekBar; @@ -60,16 +61,16 @@ import java.util.HashMap; import java.util.Map; /** - * A helper class for some string operations. + * A helper class for UI/display related operations. */ public class DisplayUtils { private static final String TAG = DisplayUtils.class.getSimpleName(); private static final String[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; private static final int[] sizeScales = { 0, 0, 1, 1, 1, 2, 2, 2, 2 }; - private static final int[] quotaSizeScales = { 0, 0, 0, 1, 1, 2, 2, 2, 2 }; public static final int RELATIVE_THRESHOLD_WARNING = 90; public static final int RELATIVE_THRESHOLD_CRITICAL = 95; + public static final String MIME_TYPE_UNKNOWN = "Unknown type"; private static Map mimeType2HumanReadable; @@ -95,40 +96,10 @@ public class DisplayUtils { *
  • rounds the size based on the suffix to 0,1 or 2 decimals
  • * * - * @param bytes Input file size + * @param bytes Input file size * @return something readable like "12 MB" */ public static String bytesToHumanReadable(long bytes) { - return bytesToHumanReadable(bytes, sizeScales, sizeSuffixes); - } - - /** - * Converts the file size in bytes to human readable output. - *
      - *
    • appends a size suffix, e.g. B, KB, MB etc.
    • - *
    • rounds the size based on the suffix to 0,1 or 2 decimals
    • - *
    - * - * @param bytes Input file size - * @return something readable like "12 MB" - */ - public static String quotaBytesToHumanReadable(long bytes) { - return bytesToHumanReadable(bytes, quotaSizeScales, sizeSuffixes); - } - - /** - * Converts the file size in bytes to human readable output. - *
      - *
    • appends a size suffix, e.g. B, KB, MB etc.
    • - *
    • rounds the size based on the suffix to 0,1 or 2 decimals
    • - *
    - * - * @param bytes Input file size - * @param sizeScales scales for the different size units - * @param sizeSuffixes suffixes for the different size units - * @return something readable like "12 MB" - */ - private static String bytesToHumanReadable(long bytes, int[] sizeScales, String[] sizeSuffixes) { double result = bytes; int suffixIndex = 0; while (result > 1024 && suffixIndex < sizeSuffixes.length) { @@ -145,7 +116,7 @@ public class DisplayUtils { * like "JPG image". * * @param mimetype MIME type to convert - * @return A human friendly version of the MIME type + * @return A human friendly version of the MIME type, {@link #MIME_TYPE_UNKNOWN} if it can't be converted */ public static String convertMIMEtoPrettyPrint(String mimetype) { if (mimeType2HumanReadable.containsKey(mimetype)) { @@ -153,11 +124,12 @@ public class DisplayUtils { } if (mimetype.split("/").length >= 2) return mimetype.split("/")[1].toUpperCase() + " file"; - return "Unknown type"; + return MIME_TYPE_UNKNOWN; } /** * Converts Unix time to human readable format + * * @param milliseconds that have passed since 01/01/1970 * @return The human readable time for the users locale */ @@ -169,6 +141,7 @@ public class DisplayUtils { /** * Converts an internationalized domain name (IDN) in an URL to and from ASCII/Unicode. + * * @param url the URL where the domain name should be converted * @param toASCII if true converts from Unicode to ASCII, if false converts from ASCII to Unicode * @return the URL containing the converted domain name @@ -299,7 +272,7 @@ public class DisplayUtils { } /** - * Gets the screen size in pixels in a backwards compatible way. + * Gets the screen size in pixels. * * @param caller Activity calling; needed to get access to the {@link android.view.WindowManager} * @return Size in pixels of the screen, or default {@link Point} if caller is null @@ -307,12 +280,7 @@ public class DisplayUtils { public static Point getScreenSize(Activity caller) { Point size = new Point(); if (caller != null) { - Display display = caller.getWindowManager().getDefaultDisplay(); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) { - display.getSize(size); - } else { - size.set(display.getWidth(), display.getHeight()); - } + caller.getWindowManager().getDefaultDisplay().getSize(size); } return size; } @@ -359,9 +327,9 @@ public class DisplayUtils { } /** - * set the owncloud standard colors for the snackbar. + * set the Nextcloud standard colors for the snackbar. * - * @param context the context relevant for setting the color according to the context's theme + * @param context the context relevant for setting the color according to the context's theme * @param snackbar the snackbar to be colored */ public static void colorSnackbar(Context context, Snackbar snackbar) { From 74452c0dd7c6a42973155976bc31064d4a74f417 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Mon, 8 Aug 2016 10:06:09 +0200 Subject: [PATCH 33/33] search for the right ocShare with public link --- .../owncloud/android/ui/activity/ShareActivity.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/ui/activity/ShareActivity.java b/src/com/owncloud/android/ui/activity/ShareActivity.java index b08c6f1815..d1fe8d0bd6 100644 --- a/src/com/owncloud/android/ui/activity/ShareActivity.java +++ b/src/com/owncloud/android/ui/activity/ShareActivity.java @@ -289,7 +289,18 @@ public class ShareActivity extends FileActivity // Create dialog to allow the user choose an app to send the link Intent intentToShareLink = new Intent(Intent.ACTION_SEND); - String link = ((OCShare) (result.getData().get(0))).getShareLink(); + + // if share to user and share via link multiple ocshares are returned, + // therefore filtering for public_link + String link = ""; + for (Object object : result.getData()) { + OCShare shareLink = (OCShare) object; + if (shareLink.getShareType().name().equalsIgnoreCase("PUBLIC_LINK")) { + link = shareLink.getShareLink(); + break; + } + } + intentToShareLink.putExtra(Intent.EXTRA_TEXT, link); intentToShareLink.setType("text/plain"); String username = AccountUtils.getUsernameForAccount(getAccount());