Replace progress dialogs with bars

For GoogleTaskListSettingsActivity
pull/795/head
Alex Baker 5 years ago
parent 4b73aa5077
commit 7aa50bf5f9

@ -0,0 +1,13 @@
package org.tasks.activities;
import android.content.Context;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import org.tasks.ui.CompletableViewModel;
@SuppressWarnings("WeakerAccess")
public class CreateListViewModel extends CompletableViewModel<TaskList> {
void createList(Context context, String account, String name) {
run(() -> new GtasksInvoker(context, account).createGtaskList(name));
}
}

@ -0,0 +1,13 @@
package org.tasks.activities;
import android.content.Context;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import org.tasks.data.GoogleTaskList;
import org.tasks.ui.ActionViewModel;
@SuppressWarnings("WeakerAccess")
public class DeleteListViewModel extends ActionViewModel {
void deleteList(Context context, GoogleTaskList list) {
run(() -> new GtasksInvoker(context, list.getAccount()).deleteGtaskList(list.getRemoteId()));
}
}

@ -1,25 +1,25 @@
package org.tasks.activities;
import static android.text.TextUtils.isEmpty;
import static org.tasks.gtasks.CreateListDialog.newCreateListDialog;
import static org.tasks.gtasks.DeleteListDialog.newDeleteListDialog;
import static org.tasks.gtasks.RenameListDialog.newRenameListDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProviders;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnFocusChange;
import com.google.android.material.textfield.TextInputEditText;
import com.google.api.services.tasks.model.TaskList;
import com.rey.material.widget.ProgressView;
import com.todoroo.astrid.activity.MainActivity;
import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.gtasks.GtasksListService;
@ -32,31 +32,25 @@ import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.gtasks.CreateListDialog;
import org.tasks.gtasks.DeleteListDialog;
import org.tasks.gtasks.RenameListDialog;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.MenuColorizer;
import timber.log.Timber;
public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActivity
implements Toolbar.OnMenuItemClickListener,
CreateListDialog.CreateListDialogCallback,
DeleteListDialog.DeleteListDialogCallback,
RenameListDialog.RenameListDialogCallback {
implements Toolbar.OnMenuItemClickListener {
public static final String EXTRA_ACCOUNT = "extra_account";
public static final String EXTRA_STORE_DATA = "extra_store_data";
public static final String ACTION_DELETED = "action_deleted";
public static final String ACTION_RELOAD = "action_reload";
private static final String EXTRA_SELECTED_THEME = "extra_selected_theme";
private static final String FRAG_TAG_CREATE_LIST_DIALOG = "frag_tag_create_list_dialog";
private static final String FRAG_TAG_DELETE_LIST_DIALOG = "frag_tag_delete_list_dialog";
private static final String FRAG_TAG_RENAME_LIST_DIALOG = "frag_tag_rename_list_dialog";
private static final int REQUEST_COLOR_PICKER = 10109;
@Inject @ForApplication Context context;
@Inject GoogleTaskListDao googleTaskListDao;
@Inject DialogBuilder dialogBuilder;
@Inject Preferences preferences;
@ -75,9 +69,15 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.progress_bar)
ProgressView progressView;
private boolean isNewList;
private GoogleTaskList gtasksList;
private int selectedTheme;
private CreateListViewModel createListViewModel;
private RenameListViewModel renameListViewModel;
private DeleteListViewModel deleteListViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -86,6 +86,10 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
setContentView(R.layout.activity_google_task_list_settings);
ButterKnife.bind(this);
createListViewModel = ViewModelProviders.of(this).get(CreateListViewModel.class);
renameListViewModel = ViewModelProviders.of(this).get(RenameListViewModel.class);
deleteListViewModel = ViewModelProviders.of(this).get(DeleteListViewModel.class);
Intent intent = getIntent();
gtasksList = intent.getParcelableExtra(EXTRA_STORE_DATA);
if (gtasksList == null) {
@ -135,6 +139,34 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
}
updateTheme();
if (createListViewModel.inProgress()
|| renameListViewModel.inProgress()
|| deleteListViewModel.inProgress()) {
showProgressIndicator();
}
createListViewModel.getData().observe(this, this::onListCreated);
renameListViewModel.getData().observe(this, this::onListRenamed);
deleteListViewModel
.getData()
.observe(
this,
deleted -> {
if (deleted) {
onListDeleted();
}
});
createListViewModel.getError().observe(this, this::requestFailed);
renameListViewModel.getError().observe(this, this::requestFailed);
deleteListViewModel.getError().observe(this, this::requestFailed);
}
private void showProgressIndicator() {
progressView.setVisibility(View.VISIBLE);
}
private void hideProgressIndicator() {
progressView.setVisibility(View.GONE);
}
@Override
@ -175,11 +207,11 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
}
if (isNewList) {
newCreateListDialog(gtasksList.getAccount(), newName)
.show(getSupportFragmentManager(), FRAG_TAG_CREATE_LIST_DIALOG);
showProgressIndicator();
createListViewModel.createList(context, gtasksList.getAccount(), newName);
} else if (nameChanged()) {
newRenameListDialog(gtasksList, newName)
.show(getSupportFragmentManager(), FRAG_TAG_RENAME_LIST_DIALOG);
showProgressIndicator();
renameListViewModel.renameList(context, gtasksList, newName);
} else {
if (colorChanged()) {
gtasksList.setColor(selectedTheme);
@ -213,10 +245,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
dialogBuilder
.newMessageDialog(R.string.delete_tag_confirmation, gtasksList.getTitle())
.setPositiveButton(
R.string.delete,
(dialog, which) ->
newDeleteListDialog(gtasksList)
.show(getSupportFragmentManager(), FRAG_TAG_DELETE_LIST_DIALOG))
R.string.delete, (dialog, which) -> deleteListViewModel.deleteList(context, gtasksList))
.setNegativeButton(android.R.string.cancel, null)
.show();
}
@ -262,28 +291,26 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
return !getNewName().equals(gtasksList.getTitle());
}
@Override
public void onListCreated(TaskList taskList) {
private void onListCreated(TaskList taskList) {
tracker.reportEvent(Tracking.Events.GTASK_NEW_LIST);
gtasksList.setRemoteId(taskList.getId());
gtasksList.setTitle(taskList.getTitle());
gtasksList.setColor(selectedTheme);
gtasksList.setId(googleTaskListDao.insertOrReplace(gtasksList));
setResult(
RESULT_OK, new Intent().putExtra(MainActivity.OPEN_FILTER, new GtasksFilter(gtasksList)));
RESULT_OK,
new Intent().putExtra(MainActivity.OPEN_FILTER, new GtasksFilter(gtasksList)));
finish();
}
@Override
public void onListDeleted() {
private void onListDeleted() {
tracker.reportEvent(Tracking.Events.GTASK_DELETE_LIST);
taskDeleter.delete(gtasksList);
setResult(RESULT_OK, new Intent(ACTION_DELETED));
finish();
}
@Override
public void onListRenamed(TaskList taskList) {
private void onListRenamed(TaskList taskList) {
tracker.reportEvent(Tracking.Events.GTASK_RENAME_LIST);
gtasksList.setTitle(taskList.getTitle());
gtasksList.setColor(selectedTheme);
@ -308,8 +335,9 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
}
}
@Override
public void requestFailed() {
private void requestFailed(Throwable error) {
Timber.e(error);
hideProgressIndicator();
Toast.makeText(this, R.string.gtasks_GLA_errorIOAuth, Toast.LENGTH_LONG).show();
}

@ -0,0 +1,17 @@
package org.tasks.activities;
import android.content.Context;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import org.tasks.data.GoogleTaskList;
import org.tasks.ui.CompletableViewModel;
@SuppressWarnings("WeakerAccess")
public class RenameListViewModel extends CompletableViewModel<TaskList> {
void renameList(Context context, GoogleTaskList list, String name) {
run(
() ->
new GtasksInvoker(context, list.getAccount())
.renameGtaskList(list.getRemoteId(), name));
}
}

@ -1,104 +0,0 @@
package org.tasks.gtasks;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import timber.log.Timber;
public class CreateListDialog extends InjectingDialogFragment {
private static final String EXTRA_ACCOUNT = "extra_account";
private static final String EXTRA_NAME = "extra_name";
@Inject DialogBuilder dialogBuilder;
@Inject @ForApplication Context context;
private CreateListDialogCallback callback;
private ProgressDialog dialog;
private String account;
private String name;
public static CreateListDialog newCreateListDialog(String account, String name) {
CreateListDialog dialog = new CreateListDialog();
Bundle args = new Bundle();
args.putString(EXTRA_ACCOUNT, account);
args.putString(EXTRA_NAME, name);
dialog.setArguments(args);
return dialog;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Bundle arguments = getArguments();
account = arguments.getString(EXTRA_ACCOUNT);
name = arguments.getString(EXTRA_NAME);
dialog = dialogBuilder.newProgressDialog(R.string.creating_new_list);
execute();
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return dialog;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (CreateListDialogCallback) activity;
}
@Override
protected void inject(DialogFragmentComponent component) {
component.inject(this);
}
private void execute() {
new AsyncTask<Void, Void, TaskList>() {
@Override
protected TaskList doInBackground(Void... voids) {
try {
return new GtasksInvoker(context, account).createGtaskList(name);
} catch (IOException e) {
Timber.e(e);
return null;
}
}
@Override
protected void onPostExecute(TaskList taskList) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (taskList == null) {
callback.requestFailed();
} else {
callback.onListCreated(taskList);
}
}
}.execute();
}
public interface CreateListDialogCallback {
void onListCreated(TaskList taskList);
void requestFailed();
}
}

@ -1,102 +0,0 @@
package org.tasks.gtasks;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.GoogleTaskList;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import timber.log.Timber;
public class DeleteListDialog extends InjectingDialogFragment {
private static final String EXTRA_LIST = "extra_list";
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
private DeleteListDialogCallback callback;
private GoogleTaskList googleTaskList;
private ProgressDialog dialog;
public static DeleteListDialog newDeleteListDialog(GoogleTaskList googleTaskList) {
DeleteListDialog dialog = new DeleteListDialog();
Bundle args = new Bundle();
args.putParcelable(EXTRA_LIST, googleTaskList);
dialog.setArguments(args);
return dialog;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Bundle arguments = getArguments();
googleTaskList = arguments.getParcelable(EXTRA_LIST);
dialog = dialogBuilder.newProgressDialog(R.string.deleting_list);
execute();
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return dialog;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (DeleteListDialogCallback) activity;
}
@Override
protected void inject(DialogFragmentComponent component) {
component.inject(this);
}
private void execute() {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... voids) {
try {
new GtasksInvoker(context, googleTaskList.getAccount())
.deleteGtaskList(googleTaskList.getRemoteId());
return true;
} catch (IOException e) {
Timber.e(e);
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (result) {
callback.onListDeleted();
} else {
callback.requestFailed();
}
}
}.execute();
}
public interface DeleteListDialogCallback {
void onListDeleted();
void requestFailed();
}
}

@ -1,106 +0,0 @@
package org.tasks.gtasks;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.api.services.tasks.model.TaskList;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.GoogleTaskList;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import timber.log.Timber;
public class RenameListDialog extends InjectingDialogFragment {
private static final String EXTRA_NAME = "extra_name";
private static final String EXTRA_LIST = "extra_list";
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
private RenameListDialogCallback callback;
private ProgressDialog dialog;
private GoogleTaskList googleTaskList;
private String name;
public static RenameListDialog newRenameListDialog(GoogleTaskList googleTaskList, String name) {
RenameListDialog dialog = new RenameListDialog();
Bundle args = new Bundle();
args.putParcelable(EXTRA_LIST, googleTaskList);
args.putString(EXTRA_NAME, name);
dialog.setArguments(args);
return dialog;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Bundle arguments = getArguments();
googleTaskList = arguments.getParcelable(EXTRA_LIST);
name = arguments.getString(EXTRA_NAME);
dialog = dialogBuilder.newProgressDialog(R.string.renaming_list);
execute();
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return dialog;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (RenameListDialogCallback) activity;
}
@Override
protected void inject(DialogFragmentComponent component) {
component.inject(this);
}
private void execute() {
new AsyncTask<Void, Void, TaskList>() {
@Override
protected TaskList doInBackground(Void... voids) {
try {
return new GtasksInvoker(context, googleTaskList.getAccount())
.renameGtaskList(googleTaskList.getRemoteId(), name);
} catch (IOException e) {
Timber.e(e);
return null;
}
}
@Override
protected void onPostExecute(TaskList taskList) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (taskList == null) {
callback.requestFailed();
} else {
callback.onListRenamed(taskList);
}
}
}.execute();
}
public interface RenameListDialogCallback {
void onListRenamed(TaskList taskList);
void requestFailed();
}
}

@ -9,9 +9,6 @@ import org.tasks.dialogs.LocationDialog;
import org.tasks.dialogs.RecordAudioDialog;
import org.tasks.dialogs.SeekBarDialog;
import org.tasks.dialogs.SortDialog;
import org.tasks.gtasks.CreateListDialog;
import org.tasks.gtasks.DeleteListDialog;
import org.tasks.gtasks.RenameListDialog;
import org.tasks.reminders.NotificationDialog;
import org.tasks.reminders.SnoozeDialog;
import org.tasks.repeats.BasicRecurrenceDialog;
@ -36,12 +33,6 @@ public interface DialogFragmentComponent {
void inject(RecordAudioDialog recordAudioDialog);
void inject(CreateListDialog createListDialog);
void inject(DeleteListDialog deleteListDialog);
void inject(RenameListDialog renameListDialog);
void inject(CustomRecurrenceDialog customRecurrenceDialog);
void inject(BasicRecurrenceDialog basicRecurrenceDialog);

@ -0,0 +1,47 @@
package org.tasks.ui;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Action;
import io.reactivex.schedulers.Schedulers;
public class ActionViewModel extends ViewModel {
private MutableLiveData<Boolean> completed = new MutableLiveData<>();
private MutableLiveData<Throwable> error = new MutableLiveData<>();
private boolean inProgress;
public LiveData<Boolean> getData() {
return completed;
}
public LiveData<Throwable> getError() {
return error;
}
public boolean inProgress() {
return inProgress;
}
protected void run(Action action) {
assertMainThread();
if (!inProgress) {
inProgress = true;
Completable.fromAction(action)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> completed.setValue(true))
.doOnError(error::setValue)
.doFinally(() -> {
assertMainThread();
inProgress = false;
})
.subscribe();
}
}
}

@ -0,0 +1,47 @@
package org.tasks.ui;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import java.util.concurrent.Callable;
public abstract class CompletableViewModel<T> extends ViewModel {
private MutableLiveData<T> data = new MutableLiveData<>();
private MutableLiveData<Throwable> error = new MutableLiveData<>();
private boolean inProgress;
public LiveData<T> getData() {
return data;
}
public LiveData<Throwable> getError() {
return error;
}
public boolean inProgress() {
return inProgress;
}
protected void run(Callable<T> callable) {
assertMainThread();
if (!inProgress) {
inProgress = true;
Single.fromCallable(callable)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess(data::setValue)
.doOnError(error::setValue)
.doFinally(() -> {
assertMainThread();
inProgress = false;
})
.subscribe();
}
}
}

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/asContentBackground"
@ -7,6 +8,16 @@
<include layout="@layout/toolbar"/>
<com.rey.material.widget.ProgressView
android:id="@+id/progress_bar"
android:layout_width="fill_parent"
android:layout_height="4dp"
android:visibility="gone"
app:pv_autostart="true"
app:pv_circular="false"
app:pv_progressMode="indeterminate"
app:pv_progressStyle="@style/ProgressViewStyle"/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">

@ -231,4 +231,11 @@
<item>2</item>
<item>3</item>
</string-array>
<array name="progress_view_colors">
<item>@color/priority_1</item>
<item>@color/priority_2</item>
<item>@color/priority_3</item>
<item>@color/priority_4</item>
</array>
</resources>

@ -151,4 +151,9 @@
<item name="android:layout_gravity">bottom|end</item>
</style>
<style name="ProgressViewStyle" parent="Material.Drawable.LinearProgress">
<item name="lpd_strokeColors">@array/progress_view_colors</item>
<item name="lpd_strokeSecondaryColor">@android:color/transparent</item>
</style>
</resources>

Loading…
Cancel
Save