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) diff --git a/build.gradle b/build.gradle index f88f80a678..098dc8ed75 100644 --- a/build.gradle +++ b/build.gradle @@ -7,10 +7,10 @@ buildscript { repositories { - mavenCentral() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.2' + classpath 'com.android.tools.build:gradle:2.1.3' } } @@ -21,7 +21,7 @@ ext { } repositories { - mavenCentral() + jcenter() maven { url "https://jitpack.io" } flatDir { @@ -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.6' compile "com.android.support:support-v4:${supportLibraryVersion}" compile "com.android.support:design:${supportLibraryVersion}" compile 'com.jakewharton:disklrucache:2.0.2' 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..d83bc52279 100644 --- a/oc_jb_workaround/build.gradle +++ b/oc_jb_workaround/build.gradle @@ -1,9 +1,9 @@ buildscript { repositories { - mavenCentral() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.2' + classpath 'com.android.tools.build:gradle:2.1.3' } } apply plugin: 'com.android.application' diff --git a/res/drawable-xxxhdpi/background.jpg b/res/drawable-xxxhdpi/background.jpg new file mode 100644 index 0000000000..6a44a8163b Binary files /dev/null and b/res/drawable-xxxhdpi/background.jpg differ diff --git a/res/layout/drawer.xml b/res/layout/drawer.xml index 843a1ebdf3..cca0b25ba3 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/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"> + + + + + \ No newline at end of file diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 828e3af1ad..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. @@ -457,4 +458,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 + + + diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index 4293c65ea6..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... @@ -177,9 +178,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-de/strings.xml b/res/values-de/strings.xml index 3d39d1a85f..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. @@ -74,7 +75,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 +94,7 @@ Nein OK Upload entfernen - hochladen erneut versuchen + Hochladen erneut versuchen Synchronisation abbrechen Abbrechen Zurück @@ -143,7 +144,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 +167,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 @@ -174,24 +175,24 @@ PIN gespeichert %1$s Musik Player - %1$s (playing) - %1$s (loading) + %1$s (wird abgespielt) + %1$s (wird geladen) %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 - 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 89ce1f7a2a..3fe31b3870 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 @@ -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. 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/res/values/strings.xml b/res/values/strings.xml index 7620dff3c7..259a93884d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -23,6 +23,7 @@ On device Settings Uploads + %1$s of %2$s used Close Open General @@ -57,6 +58,7 @@ Files Connect Upload + Create text file 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/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/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); } diff --git a/src/com/owncloud/android/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index 36c8728898..5518c8e491 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -362,7 +362,7 @@ public class UploadFileOperation extends SyncOperation { if ( mChunked && (new File(mFile.getStoragePath())).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) { - mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), + mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, mFile.getStoragePath(), mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict()); } else { mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), diff --git a/src/com/owncloud/android/ui/activity/DrawerActivity.java b/src/com/owncloud/android/ui/activity/DrawerActivity.java index 965799b554..7b81013aad 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; @@ -35,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; @@ -42,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; @@ -118,6 +126,21 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU */ 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; + /** * Initializes the drawer, its content and highlights the menu item with the given id. * This method needs to be called after the content view has been set. @@ -138,30 +161,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; + setupDrawerHeader(); - mAccountMiddleAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle); - mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end); + setupDrawerMenu(mNavigationView); - // 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); - } - - setupDrawerContent(mNavigationView); - - findNavigationViewChildById(R.id.drawer_active_user) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - toggleAccountList(); - } - }); + 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. */ @@ -185,7 +200,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); } /** @@ -193,7 +236,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 @@ -243,9 +293,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); } } @@ -446,6 +496,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 + getAndDisplayUserQuota(); } } @@ -474,6 +527,38 @@ 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 relative the percentage of space already used + */ + 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))); + + showQuota(true); + } + /** * checks/highlights the provided menu item if the drawer has been initialized and the menu item exists. * @@ -489,6 +574,57 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU } } + /** + * Retrieves and shows the user quota if available + */ + private void getAndDisplayUserQuota() { + // 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) { + 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 (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); + } + } + }); + } + } + }); + + t.start(); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index cdedbce4b2..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 + DELAY_TO_REQUEST_REFRESH_OPERATION_LATER ); } diff --git a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 5193c28b43..a5ca029a63 100644 --- a/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -42,6 +42,7 @@ 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.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; @@ -65,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; @@ -76,6 +79,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; @@ -94,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; @@ -175,13 +182,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 +342,67 @@ 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(getBaseContext()); + View view = layout.inflate(R.layout.edit_box_dialog, null); + + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( + this); + + alertDialogBuilder.setView(view); + + final EditText userInput = (EditText) view.findViewById(R.id.user_input); + 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("nextcloud", TEXT_FILE_SUFFIX); + out = new PrintWriter(f); + out.println(getIntent().getStringExtra(Intent.EXTRA_TEXT)); + out.close(); + + FileUploader.UploadRequester requester = + new FileUploader.UploadRequester(); + + // verify if file name has suffix + String filename = userInput.getText().toString(); + + if (!filename.endsWith(TEXT_FILE_SUFFIX)){ + filename += TEXT_FILE_SUFFIX; + } + + requester.uploadNewFile( + getBaseContext(), + getAccount(), + f.getAbsolutePath(), + mFile.getRemotePath() + filename, + FileUploader.LOCAL_BEHAVIOUR_COPY, + null, + true, + UploadFileOperation.CREATED_BY_USER + ); + } catch (IOException e) { + Log_OC.w(TAG, e.getMessage()); + } + + 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 +482,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 +541,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") 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; 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); 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); diff --git a/src/com/owncloud/android/utils/DisplayUtils.java b/src/com/owncloud/android/utils/DisplayUtils.java index c9a81a9a61..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,20 +61,21 @@ 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 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; + public static final String MIME_TYPE_UNKNOWN = "Unknown type"; private static Map mimeType2HumanReadable; static { - mimeType2HumanReadable = new HashMap(); + mimeType2HumanReadable = new HashMap<>(); // images mimeType2HumanReadable.put("image/jpeg", "JPEG image"); mimeType2HumanReadable.put("image/jpg", "JPEG image"); @@ -94,19 +96,19 @@ public class DisplayUtils { *
  • rounds the size based on the suffix to 0,1 or 2 decimals
  • * * - * @param bytes Input file size - * @return Like something readable like "12 MB" + * @param bytes Input file size + * @return something readable like "12 MB" */ public static String bytesToHumanReadable(long bytes) { 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]; } /** @@ -114,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)) { @@ -122,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 */ @@ -138,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 @@ -155,9 +159,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 +211,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 +258,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,22 +271,16 @@ public class DisplayUtils { return path; } - /** - * 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 + * @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(); 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; } @@ -277,7 +292,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); } @@ -301,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) { @@ -315,7 +341,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 +352,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); } }