Switch between paged/non-paged lists on the fly

pull/996/head
Alex Baker 6 years ago
parent c515bc6c2c
commit d3ecb6628d

@ -41,6 +41,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.util.Pair; import androidx.core.util.Pair;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.paging.PagedList;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -138,7 +139,6 @@ public final class TaskListFragment extends InjectingFragment
private static final int REQUEST_LIST_SETTINGS = 10101; private static final int REQUEST_LIST_SETTINGS = 10101;
private static final int REQUEST_MOVE_TASKS = 10103; private static final int REQUEST_MOVE_TASKS = 10103;
private static final int REQUEST_TAG_TASKS = 10106; private static final int REQUEST_TAG_TASKS = 10106;
private static final int REQUEST_DUE_DATE = 10107;
private static final int SEARCH_DEBOUNCE_TIMEOUT = 300; private static final int SEARCH_DEBOUNCE_TIMEOUT = 300;
private final RefreshReceiver refreshReceiver = new RefreshReceiver(); private final RefreshReceiver refreshReceiver = new RefreshReceiver();
@ -286,34 +286,15 @@ public final class TaskListFragment extends InjectingFragment
searchQuery = savedInstanceState.getString(EXTRA_SEARCH); searchQuery = savedInstanceState.getString(EXTRA_SEARCH);
} }
boolean dragAndDrop = taskAdapter.supportsManualSorting() || preferences.showSubtasks(); taskListViewModel.setFilter(searchQuery == null ? filter : createSearchFilter(searchQuery));
taskListViewModel.setFilter(
searchQuery == null ? filter : createSearchFilter(searchQuery), dragAndDrop);
recyclerAdapter =
dragAndDrop
? new DragAndDropRecyclerAdapter(
taskAdapter,
recyclerView,
viewHolderFactory,
this,
taskListViewModel.getValue(),
taskDao)
: new PagedListRecyclerAdapter(
taskAdapter,
recyclerView,
viewHolderFactory,
this,
taskListViewModel.getValue(),
taskDao);
taskAdapter.setHelper(recyclerAdapter);
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); ((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setLayoutManager(new LinearLayoutManager(context));
taskListViewModel.observe( taskListViewModel.observe(
this, this,
list -> { list -> {
recyclerAdapter.submitList(list); submitList(list);
if (list.isEmpty()) { if (list.isEmpty()) {
swipeRefreshLayout.setVisibility(View.GONE); swipeRefreshLayout.setVisibility(View.GONE);
@ -324,8 +305,6 @@ public final class TaskListFragment extends InjectingFragment
} }
}); });
recyclerView.setAdapter(recyclerAdapter);
setupRefresh(swipeRefreshLayout); setupRefresh(swipeRefreshLayout);
setupRefresh(emptyRefreshLayout); setupRefresh(emptyRefreshLayout);
@ -338,6 +317,30 @@ public final class TaskListFragment extends InjectingFragment
return parent; return parent;
} }
private void submitList(List<TaskContainer> tasks) {
if (tasks instanceof PagedList) {
if (!(recyclerAdapter instanceof PagedListRecyclerAdapter)) {
setAdapter(
new PagedListRecyclerAdapter(
taskAdapter, recyclerView, viewHolderFactory, this, tasks, taskDao));
return;
}
} else if (!(recyclerAdapter instanceof DragAndDropRecyclerAdapter)) {
setAdapter(
new DragAndDropRecyclerAdapter(
taskAdapter, recyclerView, viewHolderFactory, this, tasks, taskDao));
return;
}
recyclerAdapter.submitList(tasks);
}
private void setAdapter(TaskListRecyclerAdapter adapter) {
recyclerAdapter = adapter;
recyclerView.setAdapter(adapter);
taskAdapter.setHelper(adapter);
}
private void setupMenu() { private void setupMenu() {
Menu menu = toolbar.getMenu(); Menu menu = toolbar.getMenu();
menu.clear(); menu.clear();
@ -364,7 +367,7 @@ public final class TaskListFragment extends InjectingFragment
sortMenu.setEnabled(false); sortMenu.setEnabled(false);
sortMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); sortMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
} }
if (!preferences.showSubtasks() if (preferences.disableSubtasks()
|| !filter.supportSubtasks() || !filter.supportSubtasks()
|| taskAdapter.supportsManualSorting()) { || taskAdapter.supportsManualSorting()) {
menu.findItem(R.id.menu_collapse_subtasks).setVisible(false); menu.findItem(R.id.menu_collapse_subtasks).setVisible(false);

@ -36,6 +36,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.tasks.BuildConfig; import org.tasks.BuildConfig;
import org.tasks.data.Place; import org.tasks.data.Place;
import org.tasks.data.SubtaskInfo;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.data.TaskListQuery; import org.tasks.data.TaskListQuery;
import org.tasks.jobs.WorkManager; import org.tasks.jobs.WorkManager;
@ -142,10 +143,13 @@ public abstract class TaskDao {
@Transaction @Transaction
public List<TaskContainer> fetchTasks(QueryCallback callback) { public List<TaskContainer> fetchTasks(QueryCallback callback) {
return fetchTasks(callback, getSubtaskInfo());
}
@Transaction
public List<TaskContainer> fetchTasks(QueryCallback callback, SubtaskInfo subtasks) {
long start = BuildConfig.DEBUG ? now() : 0; long start = BuildConfig.DEBUG ? now() : 0;
boolean includeGoogleSubtasks = hasGoogleTaskSubtasks(); List<String> queries = callback.getQueries(subtasks);
boolean includeCaldavSubtasks = hasSubtasks();
List<String> queries = callback.getQueries(includeGoogleSubtasks, includeCaldavSubtasks);
SupportSQLiteDatabase db = database.getOpenHelper().getWritableDatabase(); SupportSQLiteDatabase db = database.getOpenHelper().getWritableDatabase();
int last = queries.size() - 1; int last = queries.size() - 1;
for (int i = 0 ; i < last ; i++) { for (int i = 0 ; i < last ; i++) {
@ -157,10 +161,7 @@ public abstract class TaskDao {
} }
public List<TaskContainer> fetchTasks(Preferences preferences, Filter filter) { public List<TaskContainer> fetchTasks(Preferences preferences, Filter filter) {
return fetchTasks( return fetchTasks(subtasks -> TaskListQuery.getQuery(preferences, filter, subtasks));
(includeGoogleTaskSubtasks, includeCaldavSubtasks) ->
TaskListQuery.getQuery(
preferences, filter, includeGoogleTaskSubtasks, includeCaldavSubtasks));
} }
@RawQuery @RawQuery
@ -169,14 +170,12 @@ public abstract class TaskDao {
@RawQuery @RawQuery
abstract int count(SimpleSQLiteQuery query); abstract int count(SimpleSQLiteQuery query);
@Query("SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0)")
abstract boolean hasSubtasks();
@Query( @Query(
"SELECT EXISTS(SELECT 1 FROM google_tasks " "SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0) AS hasSubtasks,"
+ "INNER JOIN tasks ON gt_task = _id " + "EXISTS(SELECT 1 FROM google_tasks "
+ "WHERE deleted = 0 AND gt_parent > 0 AND gt_deleted = 0)") + " INNER JOIN tasks ON gt_task = _id "
abstract boolean hasGoogleTaskSubtasks(); + " WHERE deleted = 0 AND gt_parent > 0 AND gt_deleted = 0) AS hasGoogleSubtasks")
public abstract SubtaskInfo getSubtaskInfo();
@RawQuery(observedEntities = {Place.class}) @RawQuery(observedEntities = {Place.class})
public abstract DataSource.Factory<Integer, TaskContainer> getTaskFactory( public abstract DataSource.Factory<Integer, TaskContainer> getTaskFactory(
@ -339,6 +338,6 @@ public abstract class TaskDao {
} }
public interface QueryCallback { public interface QueryCallback {
List<String> getQueries(boolean includeGoogleTaskSubtasks, boolean includeCaldavSubtasks); List<String> getQueries(SubtaskInfo subtasks);
} }
} }

@ -0,0 +1,10 @@
package org.tasks.data;
public class SubtaskInfo {
public boolean hasSubtasks;
public boolean hasGoogleSubtasks;
public boolean usesSubtasks() {
return hasSubtasks || hasGoogleSubtasks;
}
}

@ -72,14 +72,12 @@ public class TaskListQuery {
public static List<String> getQuery( public static List<String> getQuery(
Preferences preferences, Preferences preferences,
com.todoroo.astrid.api.Filter filter, com.todoroo.astrid.api.Filter filter,
boolean includeGoogleTaskSubtasks, SubtaskInfo subtasks) {
boolean includeCaldavSubtasks) {
if (filter.supportSubtasks() if (filter.supportSubtasks()
&& (includeGoogleTaskSubtasks || includeCaldavSubtasks) && subtasks.usesSubtasks()
&& preferences.showSubtasks() && preferences.showSubtasks()
&& !(preferences.isManualSort() && filter.supportsManualSort())) { && !(preferences.isManualSort() && filter.supportsManualSort())) {
return getRecursiveQuery( return getRecursiveQuery(filter, preferences, subtasks);
filter, preferences, includeGoogleTaskSubtasks, includeCaldavSubtasks);
} else { } else {
return getNonRecursiveQuery(filter, preferences); return getNonRecursiveQuery(filter, preferences);
} }
@ -88,8 +86,7 @@ public class TaskListQuery {
private static List<String> getRecursiveQuery( private static List<String> getRecursiveQuery(
com.todoroo.astrid.api.Filter filter, com.todoroo.astrid.api.Filter filter,
Preferences preferences, Preferences preferences,
boolean includeGoogleTaskSubtasks, SubtaskInfo subtasks) {
boolean includeCaldavSubtasks) {
List<Field> fields = newArrayList(FIELDS); List<Field> fields = newArrayList(FIELDS);
fields.add(TAG_QUERY); fields.add(TAG_QUERY);
fields.add(INDENT); fields.add(INDENT);
@ -141,9 +138,9 @@ public class TaskListQuery {
.where(TaskCriteria.activeAndVisible()); .where(TaskCriteria.activeAndVisible());
} else { } else {
parentQuery = PermaSql.replacePlaceholdersForQuery(filter.getSqlQuery()); parentQuery = PermaSql.replacePlaceholdersForQuery(filter.getSqlQuery());
if (includeGoogleTaskSubtasks && includeCaldavSubtasks) { if (subtasks.hasGoogleSubtasks && subtasks.hasSubtasks) {
addGoogleAndCaldavSubtasks(subtaskQuery); addGoogleAndCaldavSubtasks(subtaskQuery);
} else if (includeGoogleTaskSubtasks) { } else if (subtasks.hasGoogleSubtasks) {
addGoogleSubtasks(subtaskQuery); addGoogleSubtasks(subtaskQuery);
} else { } else {
addCaldavSubtasks(subtaskQuery); addCaldavSubtasks(subtaskQuery);

@ -523,7 +523,11 @@ public class Preferences {
} }
public boolean showSubtasks() { public boolean showSubtasks() {
return getBoolean(R.string.p_show_subtasks, false); return !disableSubtasks();
}
public boolean disableSubtasks() {
return getBoolean(R.string.p_disable_subtasks, false);
} }
public int getThemeBase() { public int getThemeBase() {

@ -70,7 +70,7 @@ class LookAndFeel : InjectingPreferenceFragment() {
override fun getPreferenceXml() = R.xml.preferences_look_and_feel override fun getPreferenceXml() = R.xml.preferences_look_and_feel
override fun setupPreferences(savedInstanceState: Bundle?) { override fun setupPreferences(savedInstanceState: Bundle?) {
findPreference(R.string.p_show_subtasks) findPreference(R.string.p_disable_subtasks)
.setOnPreferenceChangeListener { _: Preference?, _: Any? -> .setOnPreferenceChangeListener { _: Preference?, _: Any? ->
localBroadcastManager.broadcastRefresh() localBroadcastManager.broadcastRefresh()
true true

@ -110,7 +110,7 @@ public class SubtaskControlSet extends TaskEditControlFragment implements Callba
recyclerAdapter = new SubtasksRecyclerAdapter(activity, chipProvider, checkBoxProvider, this); recyclerAdapter = new SubtasksRecyclerAdapter(activity, chipProvider, checkBoxProvider, this);
if (task.getId() > 0) { if (task.getId() > 0) {
recyclerAdapter.submitList(viewModel.getValue()); recyclerAdapter.submitList(viewModel.getValue());
viewModel.setFilter(new Filter("subtasks", getQueryTemplate(task)), true); viewModel.setFilter(new Filter("subtasks", getQueryTemplate(task)));
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); ((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.setLayoutManager(new LinearLayoutManager(activity)); recyclerView.setLayoutManager(new LinearLayoutManager(activity));
recyclerView.setNestedScrollingEnabled(false); recyclerView.setNestedScrollingEnabled(false);

@ -3,6 +3,7 @@ package org.tasks.ui;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread; import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread; import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
import static com.todoroo.andlib.utility.DateUtilities.now; import static com.todoroo.andlib.utility.DateUtilities.now;
import static io.reactivex.Single.fromCallable;
import static org.tasks.data.TaskListQuery.getQuery; import static org.tasks.data.TaskListQuery.getQuery;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -26,6 +27,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.BuildConfig; import org.tasks.BuildConfig;
import org.tasks.data.SubtaskInfo;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import timber.log.Timber; import timber.log.Timber;
@ -40,25 +42,18 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
@Inject TaskDao taskDao; @Inject TaskDao taskDao;
private MutableLiveData<List<TaskContainer>> tasks = new MutableLiveData<>(); private MutableLiveData<List<TaskContainer>> tasks = new MutableLiveData<>();
private Filter filter; private Filter filter;
private boolean manualSort; private boolean manualSortFilter;
private final CompositeDisposable disposable = new CompositeDisposable(); private final CompositeDisposable disposable = new CompositeDisposable();
private LiveData<PagedList<TaskContainer>> internal; private LiveData<PagedList<TaskContainer>> internal;
public void setFilter(@NonNull Filter filter) { public void setFilter(@NonNull Filter filter) {
boolean manualSort =
preferences.showSubtasks() || (filter.supportsManualSort() && preferences.isManualSort());
setFilter(filter, manualSort);
}
public void setFilter(@NonNull Filter filter, boolean manualSort) {
if (!filter.equals(this.filter) if (!filter.equals(this.filter)
|| !filter.getSqlQuery().equals(this.filter.getSqlQuery()) || !filter.getSqlQuery().equals(this.filter.getSqlQuery())) {
|| this.manualSort != manualSort) {
this.filter = filter; this.filter = filter;
this.manualSort = manualSort;
tasks = new MutableLiveData<>(); tasks = new MutableLiveData<>();
invalidate(); invalidate();
} }
manualSortFilter = filter.supportsManualSort() && preferences.isManualSort();
} }
public void observe(LifecycleOwner owner, Observer<List<TaskContainer>> observer) { public void observe(LifecycleOwner owner, Observer<List<TaskContainer>> observer) {
@ -85,53 +80,61 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
return; return;
} }
if (manualSort) { disposable.add(
disposable.add( Single.fromCallable(taskDao::getSubtaskInfo)
Single.fromCallable( .subscribeOn(Schedulers.io())
() -> .observeOn(AndroidSchedulers.mainThread())
taskDao.fetchTasks( .subscribe(
((includeGoogleSubtasks, includeCaldavSubtasks) -> subtasks -> {
getQuery( if (manualSortFilter || (subtasks.usesSubtasks() && preferences.showSubtasks())) {
preferences, performNonPagedQuery(subtasks);
filter, } else {
includeGoogleSubtasks, performPagedListQuery();
includeCaldavSubtasks)))) }
.subscribeOn(Schedulers.io()) },
.observeOn(AndroidSchedulers.mainThread()) Timber::e));
.subscribe(tasks::postValue, Timber::e)); }
} else {
List<String> queries = getQuery(preferences, filter, false, false); private void performNonPagedQuery(SubtaskInfo subtasks) {
if (BuildConfig.DEBUG && queries.size() != 1) { disposable.add(
throw new RuntimeException("Invalid queries"); fromCallable(() -> taskDao.fetchTasks(s -> getQuery(preferences, filter, s), subtasks))
} .subscribeOn(Schedulers.io())
SimpleSQLiteQuery query = new SimpleSQLiteQuery(queries.get(0)); .observeOn(AndroidSchedulers.mainThread())
Timber.d("paged query: %s", query.getSql()); .subscribe(tasks::postValue, Timber::e));
Factory<Integer, TaskContainer> factory = taskDao.getTaskFactory(query); }
LivePagedListBuilder<Integer, TaskContainer> builder =
new LivePagedListBuilder<>(factory, PAGED_LIST_CONFIG); private void performPagedListQuery() {
List<TaskContainer> current = tasks.getValue(); List<String> queries = getQuery(preferences, filter, new SubtaskInfo());
if (current instanceof PagedList) { if (BuildConfig.DEBUG && queries.size() != 1) {
Object lastKey = ((PagedList<TaskContainer>) current).getLastKey(); throw new RuntimeException("Invalid queries");
if (lastKey instanceof Integer) { }
builder.setInitialLoadKey((Integer) lastKey); SimpleSQLiteQuery query = new SimpleSQLiteQuery(queries.get(0));
} Timber.d("paged query: %s", query.getSql());
} Factory<Integer, TaskContainer> factory = taskDao.getTaskFactory(query);
if (BuildConfig.DEBUG) { LivePagedListBuilder<Integer, TaskContainer> builder =
builder.setFetchExecutor( new LivePagedListBuilder<>(factory, PAGED_LIST_CONFIG);
command -> List<TaskContainer> current = tasks.getValue();
Completable.fromAction( if (current instanceof PagedList) {
() -> { Object lastKey = ((PagedList<TaskContainer>) current).getLastKey();
assertNotMainThread(); if (lastKey instanceof Integer) {
long start = now(); builder.setInitialLoadKey((Integer) lastKey);
command.run();
Timber.d("*** paged list execution took %sms", now() - start);
})
.subscribeOn(Schedulers.io())
.subscribe());
} }
internal = builder.build();
internal.observeForever(this);
} }
if (BuildConfig.DEBUG) {
builder.setFetchExecutor(
command ->
Completable.fromAction(
() -> {
assertNotMainThread();
long start = now();
command.run();
Timber.d("*** paged list execution took %sms", now() - start);
})
.subscribeOn(Schedulers.io())
.subscribe());
}
internal = builder.build();
internal.observeForever(this);
} }
@Override @Override

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.tasks.BuildConfig; import org.tasks.BuildConfig;
import org.tasks.R; import org.tasks.R;
import org.tasks.data.SubtaskInfo;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.data.TaskListQuery; import org.tasks.data.TaskListQuery;
import org.tasks.locale.Locale; import org.tasks.locale.Locale;
@ -86,10 +87,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
@Override @Override
public void onDataSetChanged() { public void onDataSetChanged() {
updateSettings(); updateSettings();
tasks = tasks = taskDao.fetchTasks(subtasks -> getQuery(filter, subtasks));
taskDao.fetchTasks(
(includeGoogleSubtasks, includeCaldavSubtasks) ->
getQuery(filter, includeGoogleSubtasks, includeCaldavSubtasks));
} }
@Override @Override
@ -251,11 +249,8 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
return position < tasks.size() ? tasks.get(position) : null; return position < tasks.size() ? tasks.get(position) : null;
} }
private List<String> getQuery( private List<String> getQuery(Filter filter, SubtaskInfo subtasks) {
Filter filter, boolean includeGoogleSubtasks, boolean includeCaldavSubtasks) { List<String> queries = TaskListQuery.getQuery(preferences, filter, subtasks);
List<String> queries =
TaskListQuery.getQuery(
preferences, filter, includeGoogleSubtasks, includeCaldavSubtasks);
int last = queries.size() - 1; int last = queries.size() - 1;
queries.set(last, subtasksHelper.applySubtasksToWidgetFilter(filter, queries.get(last))); queries.set(last, subtasksHelper.applySubtasksToWidgetFilter(filter, queries.get(last)));
return queries; return queries;

@ -513,8 +513,6 @@
<string name="collapse_subtasks">Sbalit podúkoly</string> <string name="collapse_subtasks">Sbalit podúkoly</string>
<string name="subtasks_multilevel_google_task">Úkoly Google nepodporují víceúrovňové podúkoly</string> <string name="subtasks_multilevel_google_task">Úkoly Google nepodporují víceúrovňové podúkoly</string>
<string name="enter_title_hint">Zadejte název</string> <string name="enter_title_hint">Zadejte název</string>
<string name="show_subtasks">Zobrazovat podúkoly</string>
<string name="show_subtasks_summary">Zobrazování podúkolů zpomalí aplikaci</string>
<string name="enter_tag_name">Zadejte název štítku</string> <string name="enter_tag_name">Zadejte název štítku</string>
<string name="create_new_tag">Vytvořit \"%s\"</string> <string name="create_new_tag">Vytvořit \"%s\"</string>
<string name="choose_synchronization_service">Zvolte službu</string> <string name="choose_synchronization_service">Zvolte službu</string>

@ -503,7 +503,6 @@
<string name="subtasks">Unteraufgaben</string> <string name="subtasks">Unteraufgaben</string>
<string name="subtasks_multilevel_google_task">Mehrere Unteraufgaben-Ebenen werden von Google Tasks nicht unterstützt</string> <string name="subtasks_multilevel_google_task">Mehrere Unteraufgaben-Ebenen werden von Google Tasks nicht unterstützt</string>
<string name="enter_title_hint">Titel eingeben</string> <string name="enter_title_hint">Titel eingeben</string>
<string name="show_subtasks">Teilaufgaben anzeigen</string>
<string name="no_application_found_link">Keine Anwendung konnte den Link verarbeiten</string> <string name="no_application_found_link">Keine Anwendung konnte den Link verarbeiten</string>
<string name="encryption_password_required">Verschlüsselungs-Passwort erforderlich</string> <string name="encryption_password_required">Verschlüsselungs-Passwort erforderlich</string>
<string name="encryption_password">Verschlüsselungs-Passwort</string> <string name="encryption_password">Verschlüsselungs-Passwort</string>
@ -514,7 +513,6 @@
<string name="encryption_password_wrong">Falsches Verschlüsselungs-Passwort</string> <string name="encryption_password_wrong">Falsches Verschlüsselungs-Passwort</string>
<string name="help_and_feedback">Hilfe &amp; Feedback</string> <string name="help_and_feedback">Hilfe &amp; Feedback</string>
<string name="theme_system_default">Systemstandard</string> <string name="theme_system_default">Systemstandard</string>
<string name="show_subtasks_summary">Das Anzeigen von Teilaufgaben wird die Anwendung verlangsamen</string>
<string name="enter_tag_name">Schlagwort eingeben</string> <string name="enter_tag_name">Schlagwort eingeben</string>
<string name="create_new_tag">Erstelle \"%s\"</string> <string name="create_new_tag">Erstelle \"%s\"</string>
<string name="choose_synchronization_service">Wähle einen Dienst</string> <string name="choose_synchronization_service">Wähle einen Dienst</string>

@ -508,8 +508,6 @@
<string name="subtasks">Subtareas</string> <string name="subtasks">Subtareas</string>
<string name="subtasks_multilevel_google_task">Subtareas multinivel no compatibles con Google Tasks</string> <string name="subtasks_multilevel_google_task">Subtareas multinivel no compatibles con Google Tasks</string>
<string name="enter_title_hint">Introducir título</string> <string name="enter_title_hint">Introducir título</string>
<string name="show_subtasks">Mostrar subtareas</string>
<string name="show_subtasks_summary">La visualización de subtareas degradará el rendimiento de la aplicación</string>
<string name="no_application_found_link">Ninguna aplicación podría manejar el enlace</string> <string name="no_application_found_link">Ninguna aplicación podría manejar el enlace</string>
<string name="enter_tag_name">Introduzca el nombre de la etiqueta</string> <string name="enter_tag_name">Introduzca el nombre de la etiqueta</string>
<string name="create_new_tag">Crear \"%s\"</string> <string name="create_new_tag">Crear \"%s\"</string>

@ -510,8 +510,6 @@
<string name="subtasks">Azpi-zereginak</string> <string name="subtasks">Azpi-zereginak</string>
<string name="subtasks_multilevel_google_task">Google Tasks-ek ez ditu hainbat mailako azpi-zereginak onartzen</string> <string name="subtasks_multilevel_google_task">Google Tasks-ek ez ditu hainbat mailako azpi-zereginak onartzen</string>
<string name="enter_title_hint">Sartu izenburua</string> <string name="enter_title_hint">Sartu izenburua</string>
<string name="show_subtasks">Erakutsi azpi-zereginak</string>
<string name="show_subtasks_summary">Azpi-zereginak erakusteak errendimendua kaltetu dezake</string>
<string name="no_application_found_link">Ez dago aplikaziorik esteka kudeatzeko</string> <string name="no_application_found_link">Ez dago aplikaziorik esteka kudeatzeko</string>
<string name="enter_tag_name">Sartu etiketaren izena</string> <string name="enter_tag_name">Sartu etiketaren izena</string>
<string name="create_new_tag">Sortu \"%s\"</string> <string name="create_new_tag">Sortu \"%s\"</string>

@ -443,8 +443,6 @@
<string name="choose_synchronization_service">Valitse alusta</string> <string name="choose_synchronization_service">Valitse alusta</string>
<string name="create_new_tag">Luo \"%s\"</string> <string name="create_new_tag">Luo \"%s\"</string>
<string name="enter_tag_name">Anna tunnisteen nimi</string> <string name="enter_tag_name">Anna tunnisteen nimi</string>
<string name="show_subtasks_summary">Alitehtävien esittäminen alentaa sovelluksen toimintatehokkuutta</string>
<string name="show_subtasks">Näytä alitehtävät</string>
<string name="enter_title_hint">Syötä otsikko</string> <string name="enter_title_hint">Syötä otsikko</string>
<string name="subtasks_multilevel_google_task">Google Tasks ei tue monitasoisia alitehtäviä</string> <string name="subtasks_multilevel_google_task">Google Tasks ei tue monitasoisia alitehtäviä</string>
<string name="collapse_subtasks">Pienennä alitehtävät</string> <string name="collapse_subtasks">Pienennä alitehtävät</string>

@ -503,8 +503,6 @@
<string name="subtasks">Sous-tâches</string> <string name="subtasks">Sous-tâches</string>
<string name="subtasks_multilevel_google_task">Les sous-tâches multi-niveaux ne sont pas prises en charge par Google Tasks</string> <string name="subtasks_multilevel_google_task">Les sous-tâches multi-niveaux ne sont pas prises en charge par Google Tasks</string>
<string name="enter_title_hint">Entrer le titre</string> <string name="enter_title_hint">Entrer le titre</string>
<string name="show_subtasks">Afficher les sous-tâches</string>
<string name="show_subtasks_summary">L\'affichage des sous-tâches dégradera les performances de l\'application</string>
<string name="no_application_found_link">Aucune application ne pouvait gérer le lien</string> <string name="no_application_found_link">Aucune application ne pouvait gérer le lien</string>
<string name="enter_tag_name">Entrez le nom du tag</string> <string name="enter_tag_name">Entrez le nom du tag</string>
<string name="create_new_tag">Créer %s</string> <string name="create_new_tag">Créer %s</string>

@ -506,8 +506,6 @@
<string name="subtasks">Részfeladatok</string> <string name="subtasks">Részfeladatok</string>
<string name="subtasks_multilevel_google_task">A Google Tasks nem támogatja a többszintű részfeladatokat</string> <string name="subtasks_multilevel_google_task">A Google Tasks nem támogatja a többszintű részfeladatokat</string>
<string name="enter_title_hint">Cím megadása</string> <string name="enter_title_hint">Cím megadása</string>
<string name="show_subtasks">Részfeladatok megjelenítése</string>
<string name="show_subtasks_summary">A részfeladatok megjelenítése csökkenti a program sebességét</string>
<string name="no_application_found_link">A link feldolgozására képes app nem található</string> <string name="no_application_found_link">A link feldolgozására képes app nem található</string>
<string name="enter_tag_name">Címke neve</string> <string name="enter_tag_name">Címke neve</string>
<string name="create_new_tag">\"%s\" létrehozása</string> <string name="create_new_tag">\"%s\" létrehozása</string>

@ -413,8 +413,6 @@
<string name="expand_subtasks" /> <string name="expand_subtasks" />
<string name="subtasks_multilevel_google_task">Subtugas multi-level tidak didukung oleh Google Tasks</string> <string name="subtasks_multilevel_google_task">Subtugas multi-level tidak didukung oleh Google Tasks</string>
<string name="enter_title_hint">Masukkan judul</string> <string name="enter_title_hint">Masukkan judul</string>
<string name="show_subtasks">Tampilkan subtugas</string>
<string name="show_subtasks_summary">Menampilkan subtugas akan mengurangi performa aplikasi</string>
<string name="enter_tag_name">Masukkan nama tag</string> <string name="enter_tag_name">Masukkan nama tag</string>
<string name="create_new_tag">Buat \"%s\"</string> <string name="create_new_tag">Buat \"%s\"</string>
<string name="this_feature_requires_a_subscription">Fitur ini membutuhkan anda berlangganan versi pro</string> <string name="this_feature_requires_a_subscription">Fitur ini membutuhkan anda berlangganan versi pro</string>

@ -554,8 +554,6 @@
</plurals> </plurals>
<string name="EPr_temp_show_completed_tasks">Mostra temporaneamente le attività al completamento</string> <string name="EPr_temp_show_completed_tasks">Mostra temporaneamente le attività al completamento</string>
<string name="create_new_tag">Crea \"%s\"</string> <string name="create_new_tag">Crea \"%s\"</string>
<string name="show_subtasks_summary">Visualizzare le sotto-attività riduce le prestazioni dell\'app</string>
<string name="show_subtasks">Mostra sotto-attività</string>
<string name="subtasks_multilevel_google_task">Google Tasks non supporta sotto-attività su più livelli</string> <string name="subtasks_multilevel_google_task">Google Tasks non supporta sotto-attività su più livelli</string>
<string name="expand_subtasks">Espandi sotto-attività</string> <string name="expand_subtasks">Espandi sotto-attività</string>
<string name="caldav_account_repeating_tasks">Lascia che il server programmi le attività ricorrenti</string> <string name="caldav_account_repeating_tasks">Lascia che il server programmi le attività ricorrenti</string>

@ -505,8 +505,6 @@
<string name="subtasks">하위하일</string> <string name="subtasks">하위하일</string>
<string name="subtasks_multilevel_google_task">Google Tasks는 다단계 하위할일을 지원하지 않습니다</string> <string name="subtasks_multilevel_google_task">Google Tasks는 다단계 하위할일을 지원하지 않습니다</string>
<string name="enter_title_hint">제목 입력</string> <string name="enter_title_hint">제목 입력</string>
<string name="show_subtasks">하위할일 보이기</string>
<string name="show_subtasks_summary">하위할일을 표시하면 앱 성능이 떨어집니다</string>
<string name="no_application_found_link">링크를 처리할 앱이 없습니다</string> <string name="no_application_found_link">링크를 처리할 앱이 없습니다</string>
<string name="enter_tag_name">태그 이름 입력</string> <string name="enter_tag_name">태그 이름 입력</string>
<string name="create_new_tag">\"%s\" 생성</string> <string name="create_new_tag">\"%s\" 생성</string>

@ -510,8 +510,6 @@
<string name="TEA_add_subtask">Legg til gjøremålssteg</string> <string name="TEA_add_subtask">Legg til gjøremålssteg</string>
<string name="subtasks">Gjøremålssteg</string> <string name="subtasks">Gjøremålssteg</string>
<string name="subtasks_multilevel_google_task">Gjøremålssteg med flere nivåer støttes ikke av Google Tasks</string> <string name="subtasks_multilevel_google_task">Gjøremålssteg med flere nivåer støttes ikke av Google Tasks</string>
<string name="show_subtasks">Vis gjøremålssteg</string>
<string name="show_subtasks_summary">Visning av gjøremålssteg påvirker ytelsen</string>
<string name="no_application_found_link">Mangler program for håndtering av lenke</string> <string name="no_application_found_link">Mangler program for håndtering av lenke</string>
<string name="enter_tag_name">Skriv inn etikettnavn</string> <string name="enter_tag_name">Skriv inn etikettnavn</string>
<string name="create_new_tag">Opprett «%s»</string> <string name="create_new_tag">Opprett «%s»</string>

@ -503,8 +503,6 @@
<string name="subtasks">Deeltaken</string> <string name="subtasks">Deeltaken</string>
<string name="subtasks_multilevel_google_task">Deeltaken met meerdere niveau\'s worden niet ondersteund door Google Taken</string> <string name="subtasks_multilevel_google_task">Deeltaken met meerdere niveau\'s worden niet ondersteund door Google Taken</string>
<string name="enter_title_hint">Voer titel in</string> <string name="enter_title_hint">Voer titel in</string>
<string name="show_subtasks">Deeltaken tonen</string>
<string name="show_subtasks_summary">Deeltaken tonen vermindert prestaties van de app</string>
<string name="no_application_found_link">Geen applicatie kan de link te openen</string> <string name="no_application_found_link">Geen applicatie kan de link te openen</string>
<string name="enter_tag_name">Voer label naam in</string> <string name="enter_tag_name">Voer label naam in</string>
<string name="create_new_tag">Maak \"%s\" aan</string> <string name="create_new_tag">Maak \"%s\" aan</string>

@ -519,8 +519,6 @@
<string name="subtasks">Podzadania</string> <string name="subtasks">Podzadania</string>
<string name="subtasks_multilevel_google_task">Wielopoziomowe podzadania nie są obsługiwane przez Google Tasks</string> <string name="subtasks_multilevel_google_task">Wielopoziomowe podzadania nie są obsługiwane przez Google Tasks</string>
<string name="enter_title_hint">Wprowadź tytuł</string> <string name="enter_title_hint">Wprowadź tytuł</string>
<string name="show_subtasks">Pokaż podzadania</string>
<string name="show_subtasks_summary">Wyświetlanie podzadań spowoduje obniżenie wydajności aplikacji</string>
<string name="no_application_found_link">Nie znaleziono aplikacji do otwarcia linku</string> <string name="no_application_found_link">Nie znaleziono aplikacji do otwarcia linku</string>
<string name="enter_tag_name">Wprowadź nazwę tagu</string> <string name="enter_tag_name">Wprowadź nazwę tagu</string>
<string name="create_new_tag">Stwórz \"%s\"</string> <string name="create_new_tag">Stwórz \"%s\"</string>

@ -525,8 +525,6 @@
<string name="collapse_subtasks">Свернуть подзадачи</string> <string name="collapse_subtasks">Свернуть подзадачи</string>
<string name="subtasks_multilevel_google_task">Многоуровневые подзадачи не поддерживаются Google Tasks</string> <string name="subtasks_multilevel_google_task">Многоуровневые подзадачи не поддерживаются Google Tasks</string>
<string name="enter_title_hint">Введите название</string> <string name="enter_title_hint">Введите название</string>
<string name="show_subtasks">Показать подзадачи</string>
<string name="show_subtasks_summary">Отображение подзадач снизит производительность приложения</string>
<string name="no_application_found_link">Не найдено приложение для открытия ссылки</string> <string name="no_application_found_link">Не найдено приложение для открытия ссылки</string>
<string name="enter_tag_name">Введите имя тега</string> <string name="enter_tag_name">Введите имя тега</string>
<string name="create_new_tag">Создать \"%s\"</string> <string name="create_new_tag">Создать \"%s\"</string>

@ -508,8 +508,6 @@
<string name="subtasks">Alt görevler</string> <string name="subtasks">Alt görevler</string>
<string name="subtasks_multilevel_google_task">Google Tasks, çoklu düzey alt görevleri desteklemez</string> <string name="subtasks_multilevel_google_task">Google Tasks, çoklu düzey alt görevleri desteklemez</string>
<string name="enter_title_hint">Başlık girin</string> <string name="enter_title_hint">Başlık girin</string>
<string name="show_subtasks">Alt görevleri göster</string>
<string name="show_subtasks_summary">Alt görevleri göstermek uygulama performansını düşürür</string>
<string name="no_application_found_link">Bağlantıyı işleyecek uygulama yok</string> <string name="no_application_found_link">Bağlantıyı işleyecek uygulama yok</string>
<string name="enter_tag_name">Etiket adı girin</string> <string name="enter_tag_name">Etiket adı girin</string>
<string name="create_new_tag">\"%s\" oluştur</string> <string name="create_new_tag">\"%s\" oluştur</string>

@ -541,8 +541,6 @@
<string name="choose_synchronization_service">Обрати платформу</string> <string name="choose_synchronization_service">Обрати платформу</string>
<string name="create_new_tag">Створити \"%s\"</string> <string name="create_new_tag">Створити \"%s\"</string>
<string name="enter_tag_name">Введіть назву тега</string> <string name="enter_tag_name">Введіть назву тега</string>
<string name="show_subtasks_summary">Відображення підзавдань погіршить швидкість роботи додатку</string>
<string name="show_subtasks">Показати підзавдання</string>
<string name="enter_title_hint">Введіть назву</string> <string name="enter_title_hint">Введіть назву</string>
<string name="subtasks_multilevel_google_task">Багаторівневі підзадачі не підтримуються Google Tasks</string> <string name="subtasks_multilevel_google_task">Багаторівневі підзадачі не підтримуються Google Tasks</string>
<string name="collapse_subtasks">Згорнути підзавдання</string> <string name="collapse_subtasks">Згорнути підзавдання</string>

@ -499,8 +499,6 @@
<string name="subtasks">子任务</string> <string name="subtasks">子任务</string>
<string name="subtasks_multilevel_google_task">Google Tasks不支持多层子任务</string> <string name="subtasks_multilevel_google_task">Google Tasks不支持多层子任务</string>
<string name="enter_title_hint">输入标题</string> <string name="enter_title_hint">输入标题</string>
<string name="show_subtasks">显示子任务</string>
<string name="show_subtasks_summary">显示子任务将降级应用性能</string>
<string name="no_application_found_link">没有找到能处理链接的应用</string> <string name="no_application_found_link">没有找到能处理链接的应用</string>
<string name="enter_tag_name">输入标签名称</string> <string name="enter_tag_name">输入标签名称</string>
<string name="create_new_tag">创建\"%s\"</string> <string name="create_new_tag">创建\"%s\"</string>

@ -345,7 +345,7 @@
<string name="google_tasks_position_hack">Custom order synchronization fix</string> <string name="google_tasks_position_hack">Custom order synchronization fix</string>
<string name="google_tasks_position_hack_summary">Always perform a full synchronization to workaround https://issuetracker.google.com/issues/132432317</string> <string name="google_tasks_position_hack_summary">Always perform a full synchronization to workaround https://issuetracker.google.com/issues/132432317</string>
<string name="subscription_help_url">https://tasks.org/subscribe</string> <string name="subscription_help_url">https://tasks.org/subscribe</string>
<string name="p_show_subtasks">show_subtasks</string> <string name="p_disable_subtasks">disable_subtasks</string>
<string name="p_wearable_notifications">wearable_notifications</string> <string name="p_wearable_notifications">wearable_notifications</string>
<string name="p_notified_oauth_error">notified_oauth_error_%s_%s</string> <string name="p_notified_oauth_error">notified_oauth_error_%s_%s</string>
<string name="p_chip_style">chip_style</string> <string name="p_chip_style">chip_style</string>

@ -536,8 +536,8 @@ File %1$s contained %2$s.\n\n
<string name="collapse_subtasks">Collapse subtasks</string> <string name="collapse_subtasks">Collapse subtasks</string>
<string name="subtasks_multilevel_google_task">Multi-level subtasks not supported by Google Tasks</string> <string name="subtasks_multilevel_google_task">Multi-level subtasks not supported by Google Tasks</string>
<string name="enter_title_hint">Enter title</string> <string name="enter_title_hint">Enter title</string>
<string name="show_subtasks">Show subtasks</string> <string name="disable_subtasks">Disable subtasks</string>
<string name="show_subtasks_summary">Displaying subtasks will degrade app performance</string> <string name="disable_subtasks_summary">Disabling subtasks may improve app performance</string>
<string name="enter_tag_name">Enter tag name</string> <string name="enter_tag_name">Enter tag name</string>
<string name="create_new_tag">Create \"%s\"</string> <string name="create_new_tag">Create \"%s\"</string>
<string name="choose_synchronization_service">Select a platform</string> <string name="choose_synchronization_service">Select a platform</string>

@ -52,9 +52,9 @@
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:key="@string/p_show_subtasks" android:key="@string/p_disable_subtasks"
android:summary="@string/show_subtasks_summary" android:summary="@string/disable_subtasks_summary"
android:title="@string/show_subtasks" /> android:title="@string/disable_subtasks" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"

Loading…
Cancel
Save