From 5a59f4451d9021d0f694785c77974cf45f6beacf Mon Sep 17 00:00:00 2001 From: Negue Date: Fri, 18 Nov 2016 22:16:45 +0100 Subject: [PATCH] revert from settings activity - split widgets into separate classes / providers --- Habitica/AndroidManifest.xml | 19 +- .../res/layout/widget_configure_task_list.xml | 7 - .../widget_configure_task_list_item.xml | 21 --- Habitica/res/values/strings.xml | 3 +- Habitica/res/xml/task_list_widget_info.xml | 3 +- .../habitica/components/AppComponent.java | 4 +- .../ui/activities/TaskListWidgetActivity.java | 164 ------------------ .../habitica/widget/DailiesListProvider.java | 122 +------------ .../widget/DailiesWidgetProvider.java | 111 +----------- .../habitica/widget/DailiesWidgetService.java | 1 + .../habitica/widget/TaskListProvider.java | 129 ++++++++++++++ .../widget/TaskListWidgetProvider.java | 125 +++++++++++++ .../habitica/widget/TodoListProvider.java | 12 ++ .../widget/TodoListWidgetProvider.java | 9 + .../habitica/widget/TodosWidgetService.java | 12 ++ 15 files changed, 312 insertions(+), 430 deletions(-) delete mode 100644 Habitica/res/layout/widget_configure_task_list.xml delete mode 100644 Habitica/res/layout/widget_configure_task_list_item.xml delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskListWidgetActivity.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListProvider.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListProvider.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index 465a4ae4a..00a950c73 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -166,12 +166,6 @@ - - - - - - @@ -204,7 +198,15 @@ android:resource="@xml/avatar_widget_info" /> + android:label="@string/widget_dailies"> + + + + + + @@ -223,6 +225,9 @@ + diff --git a/Habitica/res/layout/widget_configure_task_list.xml b/Habitica/res/layout/widget_configure_task_list.xml deleted file mode 100644 index 52a5f6d8e..000000000 --- a/Habitica/res/layout/widget_configure_task_list.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/Habitica/res/layout/widget_configure_task_list_item.xml b/Habitica/res/layout/widget_configure_task_list_item.xml deleted file mode 100644 index 2de284224..000000000 --- a/Habitica/res/layout/widget_configure_task_list_item.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 32c9b402c..8bbe7d42e 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -416,7 +416,8 @@ To start, which parts of your life do you want to improve? Add Reward You completed all your dailies. Well done! Habitica Do Habit - Habitica Task List + Habitica Dailies + Habitica Todo List Habitica Add Task Google play services could not be found. Purchase diff --git a/Habitica/res/xml/task_list_widget_info.xml b/Habitica/res/xml/task_list_widget_info.xml index ba50c211a..db0b85187 100644 --- a/Habitica/res/xml/task_list_widget_info.xml +++ b/Habitica/res/xml/task_list_widget_info.xml @@ -4,7 +4,6 @@ android:minHeight="120dp" android:minWidth="120dp" android:updatePeriodMillis="1800000" - android:resizeMode="horizontal|vertical" - android:configure="com.habitrpg.android.habitica.ui.activities.TaskListWidgetActivity"> + android:resizeMode="horizontal|vertical"> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java index f40aa70f7..e819a04da 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java @@ -21,7 +21,6 @@ import com.habitrpg.android.habitica.ui.activities.SetupActivity; import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity; import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity; import com.habitrpg.android.habitica.ui.activities.TaskFormActivity; -import com.habitrpg.android.habitica.ui.activities.TaskListWidgetActivity; import com.habitrpg.android.habitica.ui.fragments.GemsPurchaseFragment; import com.habitrpg.android.habitica.ui.fragments.NewsFragment; import com.habitrpg.android.habitica.ui.fragments.faq.FAQDetailFragment; @@ -61,6 +60,7 @@ import com.habitrpg.android.habitica.widget.AvatarStatsWidgetProvider; import com.habitrpg.android.habitica.widget.DailiesWidgetProvider; import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider; import com.habitrpg.android.habitica.widget.HabitButtonWidgetService; +import com.habitrpg.android.habitica.widget.TaskListWidgetProvider; import javax.inject.Singleton; @@ -186,5 +186,5 @@ public interface AppComponent { void inject(SoundManager soundManager); - void inject(TaskListWidgetActivity taskListWidgetActivity); + void inject(TaskListWidgetProvider taskListWidgetProvider); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskListWidgetActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskListWidgetActivity.java deleted file mode 100644 index 38bc88165..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskListWidgetActivity.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.habitrpg.android.habitica.ui.activities; - -import android.appwidget.AppWidgetManager; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.support.v7.preference.PreferenceManager; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider; - -import java.util.ArrayList; -import java.util.HashMap; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class TaskListWidgetActivity extends BaseActivity implements TaskTypeSelected { - - @BindView(R.id.recyclerView) - RecyclerView recyclerView; - private int widgetId; - - @Override - protected int getLayoutResId() { - return R.layout.widget_configure_task_list; - } - - @Override - protected void injectActivity(AppComponent component) { - component.inject(this); - } - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - Bundle extras = intent.getExtras(); - if (extras != null) { - widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); - } - - // If this activity was started with an intent without an app widget ID, - // finish with an error. - if (widgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { - finish(); - } - - LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); - - if (layoutManager == null) { - layoutManager = new LinearLayoutManager(this); - - recyclerView.setLayoutManager(layoutManager); - } - - HashMap taskTypesMap = new HashMap<>(); - taskTypesMap.put(getString(R.string.dailies),"dailies"); - taskTypesMap.put(getString(R.string.todos),"todos"); - - recyclerView.setAdapter(new TaskTypeSelectionViewAdapter(taskTypesMap, this)); - } - - @Override - public void taskTypeSelected(String selectedType) { - finishWithSelection(selectedType); - } - - - - public class TaskTypeSelectionViewAdapter extends RecyclerView.Adapter - { - private HashMap taskTypes; - private TaskTypeSelected taskTypeSelected; - - public TaskTypeSelectionViewAdapter(HashMap taskTypes, TaskTypeSelected taskTypeSelected) { - - this.taskTypes = taskTypes; - this.taskTypeSelected = taskTypeSelected; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.widget_configure_task_list_item, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - ArrayList keys = new ArrayList<>(taskTypes.keySet()); - - String label = keys.get(position); - String value = taskTypes.get(label); - - holder.bind(label, value); - } - - @Override - public int getItemCount() { - return taskTypes.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - @BindView(R.id.text) - TextView textView; - - public ViewHolder(View itemView) { - super(itemView); - - itemView.setOnClickListener(this); - itemView.setClickable(true); - - ButterKnife.bind(this, itemView); - } - - private String key; - - public void bind(String label, String key){ - textView.setText(label); - this.key = key; - } - - @Override - public void onClick(View view) { - taskTypeSelected.taskTypeSelected(key); - } - } - } - - private void finishWithSelection(String selectedTaskType) { - storeSelectedTaskType(selectedTaskType); - - Intent resultValue = new Intent(); - resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); - setResult(RESULT_OK, resultValue); - finish(); - - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, HabitButtonWidgetProvider.class); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {widgetId}); - sendBroadcast(intent); - } - - private void storeSelectedTaskType(String selectedTaskType) { - SharedPreferences.Editor preferences = PreferenceManager.getDefaultSharedPreferences(this).edit(); - preferences.putString("habit_list_widget_" + widgetId, selectedTaskType); - preferences.apply(); - } -} - -interface TaskTypeSelected -{ - void taskTypeSelected(String selectedType); -} - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListProvider.java index 3123002e5..44bbde43d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListProvider.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListProvider.java @@ -1,129 +1,13 @@ package com.habitrpg.android.habitica.widget; -import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; -import android.content.res.TypedArray; -import android.text.SpannableStringBuilder; -import android.text.style.DynamicDrawableSpan; -import android.widget.RemoteViews; -import android.widget.RemoteViewsService; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; -import com.raizlabs.android.dbflow.sql.builder.Condition; -import com.raizlabs.android.dbflow.sql.language.OrderBy; -import com.raizlabs.android.dbflow.sql.language.Select; - -import net.pherth.android.emoji_library.EmojiHandler; - -import java.util.ArrayList; -import java.util.List; - -import rx.Observable; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; - -public class DailiesListProvider implements RemoteViewsService.RemoteViewsFactory { - private final int widgetId; - private List taskList = new ArrayList<>(); - private Context context = null; - private boolean reloadData; +public class DailiesListProvider extends TaskListProvider { public DailiesListProvider(Context context, Intent intent) { - this.context = context; - this.widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); - this.reloadData = false; - this.loadData(); + super(context, intent, Task.TYPE_DAILY); } +} - private void loadData() { - Observable.defer(() -> Observable.from(new Select() - .from(Task.class) - .where(Condition.column("type").eq(Task.TYPE_DAILY)) - .and(Condition.column("completed").eq(false)) - .orderBy(OrderBy.columns("position", "dateCreated").descending()) - .queryList())) - .filter(task -> task.isDisplayedActive(0)) - .toList() - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(tasks -> { - taskList = tasks; - this.reloadData = false; - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(widgetId, R.id.list_view); - }, throwable -> { - this.reloadData = false; - }); - } - - - @Override - public void onCreate() { - } - - @Override - public void onDataSetChanged() { - if (this.reloadData) { - this.loadData(); - } - this.reloadData = true; - } - - @Override - public void onDestroy() { - } - - @Override - public int getCount() { - return taskList.size(); - } - - @Override - public RemoteViews getViewAt(int position) { - final RemoteViews remoteView = new RemoteViews( - context.getPackageName(), R.layout.widget_dailies_list_row); - if (taskList.size() > position) { - Task task = taskList.get(position); - - CharSequence parsedText = MarkdownParser.parseMarkdown(task.text); - - SpannableStringBuilder builder = new SpannableStringBuilder(parsedText); - EmojiHandler.addEmojis(this.context, builder, 16, DynamicDrawableSpan.ALIGN_BASELINE, 16, 0, -1, false); - - remoteView.setTextViewText(R.id.dailies_text, builder); - remoteView.setInt(R.id.checkbox_background, "setBackgroundResource", task.getLightTaskColor()); - Intent fillInIntent = new Intent(); - fillInIntent.putExtra(DailiesWidgetProvider.TASK_ID_ITEM, task.getId()); - remoteView.setOnClickFillInIntent(R.id.dailies_list_row, fillInIntent); - } - return remoteView; - } - - @Override - public RemoteViews getLoadingView() { - return new RemoteViews( - context.getPackageName(), R.layout.widget_dailies_list_row); - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public long getItemId(int position) { - if (taskList.size() > position) { - Task task = taskList.get(position); - return task.getId().hashCode(); - } - return position; - } - - @Override - public boolean hasStableIds() { - return true; - } - -} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java index c486a3bf7..3f416ea9c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java @@ -1,113 +1,10 @@ package com.habitrpg.android.habitica.widget; -import android.app.PendingIntent; -import android.appwidget.AppWidgetManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.widget.RemoteViews; - -import com.habitrpg.android.habitica.APIHelper; -import com.habitrpg.android.habitica.HabiticaApplication; -import com.habitrpg.android.habitica.HostConfig; -import com.habitrpg.android.habitica.R; -import com.magicmicky.habitrpgwrapper.lib.models.TaskDirection; -import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; -import com.raizlabs.android.dbflow.sql.builder.Condition; -import com.raizlabs.android.dbflow.sql.language.Select; - -import javax.inject.Inject; - -public class DailiesWidgetProvider extends BaseWidgetProvider { - public static final String DAILY_ACTION = "com.habitrpg.android.habitica.DAILY_ACTION"; - public static final String TASK_ID_ITEM = "com.habitrpg.android.habitica.TASK_ID_ITEM"; - - @Inject - APIHelper apiHelper; - @Inject - HostConfig hostConfig; - - private void setUp(Context context) { - if (apiHelper == null) { - HabiticaApplication application = HabiticaApplication.getInstance(context); - application.getComponent().inject(this); - } - } +public class DailiesWidgetProvider extends TaskListWidgetProvider{ @Override - public void onReceive(Context context, Intent intent) { - setUp(context); - if (intent.getAction().equals(DAILY_ACTION)) { - AppWidgetManager mgr = AppWidgetManager.getInstance(context); - int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); - String taskId = intent.getStringExtra(TASK_ID_ITEM); - - if (taskId != null) { - apiHelper.apiService.postTaskDirection(taskId, TaskDirection.up.toString()) - .compose(apiHelper.configureApiCallObserver()) - .subscribe(taskDirectionData -> { - Task task = new Select().from(Task.class).where(Condition.column("id").eq(taskId)).querySingle(); - task.completed = true; - task.save(); - showToastForTaskDirection(context, taskDirectionData, hostConfig.getUser()); - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); - }, throwable -> { - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); - }); - } - } - super.onReceive(context, intent); + protected Class getServiceClass() { + return DailiesWidgetService.class; } +} - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - setUp(context); - ComponentName thisWidget = new ComponentName(context, - DailiesWidgetProvider.class); - int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); - - if (Build.VERSION.SDK_INT >= 16) { - for (int widgetId : allWidgetIds) { - Bundle options = appWidgetManager.getAppWidgetOptions(widgetId); - appWidgetManager.partiallyUpdateAppWidget(widgetId, - sizeRemoteViews(context, options, widgetId)); - } - } - - for (int i = 0; i < appWidgetIds.length; ++i) { - Intent intent = new Intent(context, DailiesWidgetService.class); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); - intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); - RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_dailies); - rv.setRemoteAdapter(appWidgetIds[i], R.id.list_view, intent); - rv.setEmptyView(R.id.list, R.id.empty_view); - - Intent taskIntent = new Intent(context, DailiesWidgetProvider.class); - taskIntent.setAction(DAILY_ACTION); - taskIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); - intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); - PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, taskIntent, - PendingIntent.FLAG_UPDATE_CURRENT); - rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent); - - appWidgetManager.updateAppWidget(appWidgetIds[i], rv); - - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetIds[i], R.id.list_view); - } - super.onUpdate(context, appWidgetManager, appWidgetIds); - } - - @Override - public int layoutResourceId() { - return R.layout.widget_dailies; - } - - @Override - public RemoteViews configureRemoteViews(RemoteViews remoteViews, int widgetId, int columns, int rows) { - return remoteViews; - } -} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java index 03f081f5f..094448126 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java @@ -10,3 +10,4 @@ public class DailiesWidgetService extends RemoteViewsService { return new DailiesListProvider(this.getApplicationContext(), intent); } } + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListProvider.java new file mode 100644 index 000000000..8bc17e635 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListProvider.java @@ -0,0 +1,129 @@ +package com.habitrpg.android.habitica.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.text.SpannableStringBuilder; +import android.text.style.DynamicDrawableSpan; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import com.habitrpg.android.habitica.R; +import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; +import com.raizlabs.android.dbflow.sql.builder.Condition; +import com.raizlabs.android.dbflow.sql.language.OrderBy; +import com.raizlabs.android.dbflow.sql.language.Select; + +import net.pherth.android.emoji_library.EmojiHandler; + +import java.util.ArrayList; +import java.util.List; + +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public abstract class TaskListProvider implements RemoteViewsService.RemoteViewsFactory { + private final int widgetId; + private String taskType; + private List taskList = new ArrayList<>(); + private Context context = null; + private boolean reloadData; + + public TaskListProvider(Context context, Intent intent, String taskType) { + this.context = context; + this.widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); + this.reloadData = false; + this.taskType = taskType; + + this.loadData(); + } + + private void loadData() { + Observable.defer(() -> Observable.from(new Select() + .from(Task.class) + .where(Condition.column("type").eq(taskType)) + .and(Condition.column("completed").eq(false)) + .orderBy(OrderBy.columns("position", "dateCreated").descending()) + .queryList())) + .filter(task -> task.type.equals(Task.TYPE_TODO) || task.isDisplayedActive(0)) + .toList() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(tasks -> { + taskList = tasks; + this.reloadData = false; + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(widgetId, R.id.list_view); + }, throwable -> { + this.reloadData = false; + }); + } + + + @Override + public void onCreate() { + } + + @Override + public void onDataSetChanged() { + if (this.reloadData) { + this.loadData(); + } + this.reloadData = true; + } + + @Override + public void onDestroy() { + } + + @Override + public int getCount() { + return taskList.size(); + } + + @Override + public RemoteViews getViewAt(int position) { + final RemoteViews remoteView = new RemoteViews( + context.getPackageName(), R.layout.widget_dailies_list_row); + if (taskList.size() > position) { + Task task = taskList.get(position); + + CharSequence parsedText = MarkdownParser.parseMarkdown(task.text); + + SpannableStringBuilder builder = new SpannableStringBuilder(parsedText); + EmojiHandler.addEmojis(this.context, builder, 16, DynamicDrawableSpan.ALIGN_BASELINE, 16, 0, -1, false); + + remoteView.setTextViewText(R.id.dailies_text, builder); + remoteView.setInt(R.id.checkbox_background, "setBackgroundResource", task.getLightTaskColor()); + Intent fillInIntent = new Intent(); + fillInIntent.putExtra(TaskListWidgetProvider.TASK_ID_ITEM, task.getId()); + remoteView.setOnClickFillInIntent(R.id.dailies_list_row, fillInIntent); + } + return remoteView; + } + + @Override + public RemoteViews getLoadingView() { + return new RemoteViews(context.getPackageName(), R.layout.widget_dailies_list_row); + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public long getItemId(int position) { + if (taskList.size() > position) { + Task task = taskList.get(position); + return task.getId().hashCode(); + } + return position; + } + + @Override + public boolean hasStableIds() { + return true; + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java new file mode 100644 index 000000000..98a84ee5c --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java @@ -0,0 +1,125 @@ +package com.habitrpg.android.habitica.widget; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.widget.RemoteViews; + +import com.habitrpg.android.habitica.APIHelper; +import com.habitrpg.android.habitica.HabiticaApplication; +import com.habitrpg.android.habitica.HostConfig; +import com.habitrpg.android.habitica.R; +import com.magicmicky.habitrpgwrapper.lib.models.TaskDirection; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; +import com.raizlabs.android.dbflow.sql.builder.Condition; +import com.raizlabs.android.dbflow.sql.language.Select; + +import javax.inject.Inject; + +public abstract class TaskListWidgetProvider extends BaseWidgetProvider { + public static final String DAILY_ACTION = "com.habitrpg.android.habitica.DAILY_ACTION"; + public static final String TASK_ID_ITEM = "com.habitrpg.android.habitica.TASK_ID_ITEM"; + + @Inject + APIHelper apiHelper; + @Inject + HostConfig hostConfig; + @Inject + public SharedPreferences sharedPreferences; + + private void setUp(Context context) { + if (apiHelper == null) { + HabiticaApplication application = HabiticaApplication.getInstance(context); + application.getComponent().inject(this); + } + } + + protected abstract Class getServiceClass(); + + + @Override + public void onReceive(Context context, Intent intent) { + setUp(context); + if (intent.getAction().equals(DAILY_ACTION)) { + AppWidgetManager mgr = AppWidgetManager.getInstance(context); + int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + String taskId = intent.getStringExtra(TASK_ID_ITEM); + + if (taskId != null) { + apiHelper.apiService.postTaskDirection(taskId, TaskDirection.up.toString()) + .compose(apiHelper.configureApiCallObserver()) + .subscribe(taskDirectionData -> { + Task task = new Select().from(Task.class).where(Condition.column("id").eq(taskId)).querySingle(); + task.completed = true; + task.save(); + showToastForTaskDirection(context, taskDirectionData, hostConfig.getUser()); + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); + }, throwable -> { + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); + }); + } + } + super.onReceive(context, intent); + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + setUp(context); + ComponentName thisWidget = new ComponentName(context, + DailiesWidgetProvider.class); + int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); + + if (Build.VERSION.SDK_INT >= 16) { + for (int widgetId : allWidgetIds) { + Bundle options = appWidgetManager.getAppWidgetOptions(widgetId); + appWidgetManager.partiallyUpdateAppWidget(widgetId, + sizeRemoteViews(context, options, widgetId)); + } + } + + for (int i = 0; i < appWidgetIds.length; ++i) { + Intent intent = new Intent(context, getServiceClass()); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_dailies); + rv.setRemoteAdapter(appWidgetIds[i], R.id.list_view, intent); + rv.setEmptyView(R.id.list, R.id.empty_view); + + Intent taskIntent = new Intent(context, DailiesWidgetProvider.class); + taskIntent.setAction(DAILY_ACTION); + taskIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, taskIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent); + + appWidgetManager.updateAppWidget(appWidgetIds[i], rv); + + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetIds[i], R.id.list_view); + } + + super.onUpdate(context, appWidgetManager, appWidgetIds); + } + + @Override + public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { + super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); + } + + @Override + public int layoutResourceId() { + return R.layout.widget_dailies; + } + + @Override + public RemoteViews configureRemoteViews(RemoteViews remoteViews, int widgetId, int columns, int rows) { + return remoteViews; + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListProvider.java new file mode 100644 index 000000000..0f24c7edc --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListProvider.java @@ -0,0 +1,12 @@ +package com.habitrpg.android.habitica.widget; + +import android.content.Context; +import android.content.Intent; + +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; + +public class TodoListProvider extends TaskListProvider { + public TodoListProvider(Context context, Intent intent) { + super(context, intent, Task.TYPE_TODO); + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java new file mode 100644 index 000000000..185a14da0 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java @@ -0,0 +1,9 @@ +package com.habitrpg.android.habitica.widget; + +public class TodoListWidgetProvider extends TaskListWidgetProvider{ + + @Override + protected Class getServiceClass() { + return TodosWidgetService.class; + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java new file mode 100644 index 000000000..e84a6a5db --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java @@ -0,0 +1,12 @@ +package com.habitrpg.android.habitica.widget; + +import android.content.Intent; +import android.widget.RemoteViewsService; + +public class TodosWidgetService extends RemoteViewsService { + + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return new TodoListProvider(this.getApplicationContext(), intent); + } +}