diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d81273a8..14b6839ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ Change Log --- +### 6.6.3 (2019-05-08) + +* Fix backup import crash +* Fix crash when refreshing purchases +* Google Tasks synchronization bug fix +* Update translations + * Polish - mujehu + * Russian - Balbatoon + * Slovak - Cuco + ### 6.6.2 (2019-04-22) * Backup and restore preferences diff --git a/app/build.gradle b/app/build.gradle index 876457b31..0cc62af39 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,8 +21,8 @@ android { defaultConfig { testApplicationId "org.tasks.test" applicationId "org.tasks" - versionCode 578 - versionName "6.6.2" + versionCode 579 + versionName "6.6.3" targetSdkVersion 28 minSdkVersion 16 multiDexEnabled true diff --git a/app/src/googleplay/java/org/tasks/billing/BillingClientImpl.java b/app/src/googleplay/java/org/tasks/billing/BillingClientImpl.java index dd3087952..f13e760fd 100644 --- a/app/src/googleplay/java/org/tasks/billing/BillingClientImpl.java +++ b/app/src/googleplay/java/org/tasks/billing/BillingClientImpl.java @@ -105,9 +105,13 @@ public class BillingClientImpl implements BillingClient, PurchasesUpdatedListene purchases, Single.fromCallable(() -> billingClient.queryPurchases(SkuType.SUBS)), (iaps, subs) -> { - if (subs.getResponseCode() == BillingResponse.OK) { - iaps.getPurchasesList().addAll(subs.getPurchasesList()); + if (iaps.getResponseCode() != BillingResponse.OK) { + return iaps; } + if (subs.getResponseCode() != BillingResponse.OK) { + return subs; + } + iaps.getPurchasesList().addAll(subs.getPurchasesList()); return iaps; }); } diff --git a/app/src/main/java/org/tasks/dialogs/ImportTasksDialog.java b/app/src/main/java/org/tasks/dialogs/ImportTasksDialog.java index eb2032d94..b7e3769b7 100644 --- a/app/src/main/java/org/tasks/dialogs/ImportTasksDialog.java +++ b/app/src/main/java/org/tasks/dialogs/ImportTasksDialog.java @@ -2,13 +2,10 @@ package org.tasks.dialogs; import android.app.Dialog; import android.app.ProgressDialog; -import android.content.ContentResolver; import android.content.Context; import android.net.Uri; import android.os.Bundle; -import android.webkit.MimeTypeMap; import com.todoroo.astrid.backup.TasksXmlImporter; -import java.io.IOException; import javax.inject.Inject; import org.tasks.analytics.Tracker; import org.tasks.analytics.Tracking; @@ -16,21 +13,25 @@ import org.tasks.backup.TasksJsonImporter; import org.tasks.injection.ForApplication; import org.tasks.injection.InjectingNativeDialogFragment; import org.tasks.injection.NativeDialogFragmentComponent; -import timber.log.Timber; +import org.tasks.ui.Toaster; public class ImportTasksDialog extends InjectingNativeDialogFragment { private static final String EXTRA_URI = "extra_uri"; + private static final String EXTRA_EXTENSION = "extra_extension"; + @Inject TasksXmlImporter xmlImporter; @Inject TasksJsonImporter jsonImporter; @Inject DialogBuilder dialogBuilder; @Inject Tracker tracker; @Inject @ForApplication Context context; + @Inject Toaster toaster; - public static ImportTasksDialog newImportTasksDialog(Uri data) { + public static ImportTasksDialog newImportTasksDialog(Uri data, String extension) { ImportTasksDialog importTasksDialog = new ImportTasksDialog(); Bundle args = new Bundle(); args.putParcelable(EXTRA_URI, data); + args.putString(EXTRA_EXTENSION, extension); importTasksDialog.setArguments(args); return importTasksDialog; } @@ -39,35 +40,26 @@ public class ImportTasksDialog extends InjectingNativeDialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle arguments = getArguments(); Uri data = arguments.getParcelable(EXTRA_URI); + String extension = arguments.getString(EXTRA_EXTENSION); ProgressDialog progressDialog = dialogBuilder.newProgressDialog(); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setCancelable(false); progressDialog.setIndeterminate(true); progressDialog.show(); setCancelable(false); - try { - String extension = - data.getScheme().equals(ContentResolver.SCHEME_CONTENT) - ? MimeTypeMap.getSingleton() - .getExtensionFromMimeType(context.getContentResolver().getType(data)) - : MimeTypeMap.getFileExtensionFromUrl(data.getPath()); - switch (extension) { - case "json": - jsonImporter.importTasks(getActivity(), data, progressDialog); - tracker.reportEvent(Tracking.Events.IMPORT_JSON); - break; - case "xml": - xmlImporter.importTasks(getActivity(), data, progressDialog); - tracker.reportEvent(Tracking.Events.IMPORT_XML); - break; - default: - throw new IOException("Invalid file type: " + extension); - } - return progressDialog; - } catch (IOException e) { - Timber.e(e); + switch (extension) { + case "json": + jsonImporter.importTasks(getActivity(), data, progressDialog); + tracker.reportEvent(Tracking.Events.IMPORT_JSON); + break; + case "xml": + xmlImporter.importTasks(getActivity(), data, progressDialog); + tracker.reportEvent(Tracking.Events.IMPORT_XML); + break; + default: + throw new RuntimeException("Invalid extension: " + extension); } - return null; + return progressDialog; } @Override diff --git a/app/src/main/java/org/tasks/files/FileHelper.java b/app/src/main/java/org/tasks/files/FileHelper.java index c08d3a895..a40c4a3dc 100644 --- a/app/src/main/java/org/tasks/files/FileHelper.java +++ b/app/src/main/java/org/tasks/files/FileHelper.java @@ -24,6 +24,7 @@ import android.webkit.MimeTypeMap; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.documentfile.provider.DocumentFile; +import com.google.common.base.Strings; import com.google.common.io.ByteStreams; import com.google.common.io.Files; import java.io.File; @@ -144,6 +145,24 @@ public class FileHelper { return null; } + public static String getExtension(Context context, Uri uri) { + if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { + String extension = + MimeTypeMap.getSingleton() + .getExtensionFromMimeType(context.getContentResolver().getType(uri)); + if (!Strings.isNullOrEmpty(extension)) { + return extension; + } + } + + String extension = MimeTypeMap.getFileExtensionFromUrl(uri.getPath()); + if (!Strings.isNullOrEmpty(extension)) { + return extension; + } + + return Files.getFileExtension(getFilename(context, uri)); + } + public static String getMimeType(Context context, Uri uri) { String filename = getFilename(context, uri); String extension = Files.getFileExtension(filename); diff --git a/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java index ba5a2711c..4b56a4db3 100644 --- a/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java +++ b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java @@ -193,9 +193,6 @@ public class GoogleTaskSynchronizer { break; } eTag = remoteLists.getEtag(); - if (!Strings.isNullOrEmpty(eTag) && eTag.equals(account.getEtag())) { - return; - } List items = remoteLists.getItems(); if (items != null) { gtaskLists.addAll(items); diff --git a/app/src/main/java/org/tasks/preferences/BasicPreferences.java b/app/src/main/java/org/tasks/preferences/BasicPreferences.java index e4ac0d087..c68818d33 100644 --- a/app/src/main/java/org/tasks/preferences/BasicPreferences.java +++ b/app/src/main/java/org/tasks/preferences/BasicPreferences.java @@ -443,8 +443,14 @@ public class BasicPreferences extends InjectingPreferenceActivity } } else if (requestCode == REQUEST_PICKER) { if (resultCode == RESULT_OK) { - newImportTasksDialog(data.getData()).show(getFragmentManager(), FRAG_TAG_IMPORT_TASKS); - result.putBoolean(AppearancePreferences.EXTRA_RESTART, true); + Uri uri = data.getData(); + String extension = FileHelper.getExtension(this, uri); + if (!("json".equalsIgnoreCase(extension) || "xml".equalsIgnoreCase(extension))) { + toaster.longToast(R.string.invalid_backup_file); + } else { + newImportTasksDialog(uri, extension).show(getFragmentManager(), FRAG_TAG_IMPORT_TASKS); + result.putBoolean(AppearancePreferences.EXTRA_RESTART, true); + } } } else if (requestCode == RC_DRIVE_BACKUP) { boolean success = resultCode == RESULT_OK; diff --git a/app/src/main/java/org/tasks/ui/Toaster.java b/app/src/main/java/org/tasks/ui/Toaster.java index 88c98d7e1..2c0c8a950 100644 --- a/app/src/main/java/org/tasks/ui/Toaster.java +++ b/app/src/main/java/org/tasks/ui/Toaster.java @@ -21,6 +21,10 @@ public class Toaster { this.locale = locale; } + public void longToast(@StringRes int resId, String arg) { + longToast(context.getString(resId, arg)); + } + public void longToast(@StringRes int resId, int number) { longToast(context.getString(resId, locale.formatNumber(number))); } diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 6d8c0af8f..412471581 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -57,12 +57,14 @@ Dzień przed terminem Tydzień przed terminem w terminie + o czasie Dzień przed terminem tydzień przed terminem Kiedy Powtórz Kalendarz Priorytet + Lokalizacja Opis Pliki Przypomnienia @@ -110,6 +112,8 @@ Domyślny priorytet Ukrywanie zadania (domyślnie) Przypomnienia (domyślnie) + Domyślne powiadomienia o lokalizacji + Domyślny promień Domyślny dzwonek/wibracja Ważne Średnio ważne @@ -121,6 +125,9 @@ W dniu terminu nieprzekraczalnego W nieprzekraczalnym terminie lub gdy zaległe Brak przypomnień + Po przybyciu + Przy wyruszaniu + Po przybyciu i przy wyruszeniu Moje zadania Niedawno zmodyfikowane Aktywne zadania @@ -203,8 +210,8 @@ %d zadań - czas - times + raz + razy minuta @@ -240,7 +247,7 @@ miesiąc - miesiący + miesięcy %d miesiąc @@ -255,11 +262,13 @@ %d lat w terminie - data zakoµczenia + data zakończenia Powtarzaj bez końca Powtarzaj do %s Powtarzaj ilość razy. + Występuje %1$s przełożone na %2$s + %1$s o %2$s Stwórz nowy tag Utwórz nową listę Na żadnej liście @@ -298,6 +307,7 @@ Ciche gdzoiny Katalog załączników Katalog kopii zapasowych + Kopiuj do Dysku Google Różne Synchronizacja Włączone @@ -320,6 +330,7 @@ Wybierz datę i czas Gdy zaległe Gdy w terminie + Promień Tagi Filtry Na godzinę @@ -352,6 +363,7 @@ Ulepsz Tasks Wyślij anonimowe statyki użycia i raporty o awariach celem ulepszenia Tasks. Żadne prywatne dane nie będą gromadzone. Tag już istnieje + Duplikuj nazwę Nazwa nie może być pusta Wymagana nazwa użytkownika Wymagane hasło @@ -418,6 +430,7 @@ Data i czas Początek tygodnia Użyj domyślnych + Użyj natywnych narzędzi wyboru daty i czasu Dodaj konto Użytkownik Hasło @@ -433,7 +446,9 @@ Powtarza się %s Powtarza się %1$s w: %2$s Powtarza się %1$s do %2$s + Powtarzane %1$s, występuje %2$d %3$s Powtarza się %1$s w %2$s do %3$s + Powtarzane %1$s w %2$s, występuje %3$d %4$s co minutę co godzinę raz dziennie @@ -441,12 +456,19 @@ raz w miesiącu raz w roku Powtarzaj co %s + Powtarzane co każde %1$s w %2$s + Powtarzane co każde %1$s aż do %2$s + Powtarzane co każde %1$s, występuje %2$d %3$s + Powtarzane co każde %1$s w %2$s aż do %3$s + Powtarzane co każde %1$s w %2$s, występuje %3$d %4$s Nie dodawaj do kalendarza Domyślny kalendarz Wyświetl liczbę zadań na ikonie Tasks. Nie wszystkie programy wspierają plakietki. + Wyświetlaj wiele powiadomień jako jedno powiadomienie tego samego dnia każdego miesiąca Nie synchronizowane każdy %1$s %2$s + co każde %1$s %2$s pierwszy drugi trzeci @@ -458,22 +480,47 @@ Błąd połączenia Tylko niezliczane połączenia Upgrade do pro + Zarządzaj subskrypcją Odśwież zakupy Subskrybowane Zasubskrybuj Więcej informacji Posiadane + Płatność niedostępna. Upewnij się, że aplikacja Google Play jest poprawnie skonfigurowana. + Płatność niedostępna. Sprawdź swoje urządzenie. O + Tasks jest aplikacją darmową z otwartym kodem źródłowym, rozprowadzaną na licencją GNU General Public License v3.0 Dodatkowe motywy Synchronizacja CalDAV Wiele kont Google Task + Wyszukiwanie w Google Places Wymaga subskrypcji pro Wyloguj Wyloguj z %s? Wszystkie dane z tego konta zostaną usunięte z urządzenia Brak dostępu do konta + Powiąż ponownie Stwórz nowe zadanie Pokaż opis Pokaż pełen opis Pokaż linki Dodaj linki do stron WWW, adresów i numerów telefonów + Przypomnij po przybyciu + Przypomnij przy wyruszaniu + Wejdź na stronę + Przybyto do %s + Wyruszono z %s + Generowanie powiadomień + Wybierz lokalizację + Ustaw wybraną lokalizację + Lub wybierz lokalizację + Dostawca map + Silnik wyszukiwania + Brakujące uprawnienia + Uprawnienia lokalizacji są wymagane do powiadomień o lokalizacji + Uprawnienia lokalizacji są wymagane do ustalenia twojej aktualnej lokalizacji + Otwórz mapę + Wybierz nową lokalizację + Licencje innych podmiotów + Lista zmian + Wersja %s \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1c073ff2f..929e6f1fc 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -511,6 +511,15 @@ Добавить ссылки на сайты, адреса и номера телефонов Напомнить по прибытии Напомнить покинув место + Посетить вебсайт Прибытие в %s Покинули %s + Выбрать местоположение + Выбрать это местоположение + Или выбрать местоположение + Поставщик системы карт + Поставщик системы поиска + Отсутствующие разрешения + Список изменений + Версия %s \ No newline at end of file diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 9299e8236..1b25af18d 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -30,6 +30,8 @@ Hľadať Nastavenia Upraviť + Volať + Otvoriť Ručne triediť s podúlohami Chytré triedenie Podľa názvu @@ -54,10 +56,15 @@ Čas dokončenia Deň pre ukončením Týždeň pred ukončením + termín deň + termín čas + o deň skôr + o týždeň skôr Kedy Opakovať Kalendár Priorita + Poloha Popis Prílohy Pripomienky @@ -106,6 +113,7 @@ Predvolené Skryť do Predvolené pripomienky Východzie upozornenia podľa polohy + Predvolený polomer Východzie vyzváňanie/vybrovanie Vysoká Stredná @@ -149,6 +157,7 @@ %s (dokončené) V zozname: ? V zozname GTasks... + V zozname CalDAV … Vymazať dokončené Overovanie... Prepáč, nastal problém v komunikácii s Google serverom. Prosím, skús to znovu neskôr. @@ -260,6 +269,7 @@ Opakovať určitý počet krát Vyskytuje sa %1$s preložené na %2$s + %1$s, %2$s Vytvoriť nový štítok Vytvoriť nový zoznam Nezaradené @@ -298,6 +308,7 @@ Čas ticha Priečinok pre prílohy Zalóhovať adresár + Kopírovať na Disk Google Rôzne Synchronizácia Povolené @@ -311,6 +322,7 @@ Žiadne upozornenia počas obdobia ticha Darovať Pridať pripomienku + Pridaj polohu Odstrániť Raz náhodne Náhodne @@ -319,6 +331,7 @@ Vybrať dátum a čas Keď po termíne Keď v termíne + Polomer Štítky Filtre Za hodinu @@ -366,6 +379,7 @@ Téma Farba Zvýraznenie + Ikona Červená Ružová Fialová @@ -387,6 +401,7 @@ Modro šedá Čierna Tmavo šedá + Biela Svetlá Tmavá Tapeta @@ -467,6 +482,7 @@ Iba na bezplatných pripojeniach Nová verzia Rozšíriť na verziu pro + Platená verzia Obnoviť nákupy Prihlásený Prihlásiť sa @@ -480,9 +496,37 @@ Google Play je správne nastavená Ďaľšie témy CaIDAV synchronizácia Viac účtov Google Task + Miesta Google vyhľadanie Zásuvný modul Tasker Rozšírenie Dashclock Vyžaduje platenú verziu pro + Odhlásiť sa + Odhlásiť sa o %s? Všetky údaje tohto účtu budú odstránené z Vášho zariadenia + Chyba v prístupe k účtu + Znovu aktivovať + Vytvoriť novú úlohu + Ukázať popis + Ukázať plný popis + Ukázať prepojenia + Pridať prepojenia do stránok, adries a telefónnych čísel + Ukázať zoznamy Pripomenúť pri príchode Pripomenúť pri odchode + Navštíviť stránky + Príchod o %s + Odchod o %s + Všeobecné upozornenia + Vybrať polohu + Vybrať túto polohu + Alebo vybrať polohu ručne + Mapy poskytuje + Vyhľadávanie poskytuje + Chýbajúce oprávnenia + Pre upozornenia podľa polohy sú potrebné povolenia + Pre učenie súčasnej polohy sú potrebné povolenia + Otvoriť mapu + Zvoliť novú polohu + Licencie tretích strán + Zoznam zmien + Verzia %s \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8441c7fa4..39defc9e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -886,4 +886,5 @@ File %1$s contained %2$s.\n\n Third-party licenses Changelog Version %s + Invalid backup file