mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
revert from settings activity - split widgets into separate classes / providers
This commit is contained in:
parent
d69895279f
commit
5a59f4451d
15 changed files with 312 additions and 430 deletions
|
|
@ -166,12 +166,6 @@
|
|||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ui.activities.TaskListWidgetActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".helpers.notifications.HabiticaFirebaseMessagingService">
|
||||
<intent-filter>
|
||||
|
|
@ -204,7 +198,15 @@
|
|||
android:resource="@xml/avatar_widget_info" />
|
||||
</receiver>
|
||||
<receiver android:name=".widget.DailiesWidgetProvider"
|
||||
android:label="@string/widget_task_list">
|
||||
android:label="@string/widget_dailies">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/task_list_widget_info" />
|
||||
</receiver>
|
||||
<receiver android:name=".widget.TodoListWidgetProvider"
|
||||
android:label="@string/widget_todo_list">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
|
@ -223,6 +225,9 @@
|
|||
<service
|
||||
android:name=".widget.DailiesWidgetService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
<service
|
||||
android:name=".widget.TodosWidgetService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
<service android:name=".widget.HabitButtonWidgetService"/>
|
||||
</application>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/recyclerView"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/CardView.Default"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/CardContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
|
@ -416,7 +416,8 @@ To start, which parts of your life do you want to improve?</string>
|
|||
<string name="add_reward">Add Reward</string>
|
||||
<string name="all_dailies_completed">You completed all your dailies. Well done!</string>
|
||||
<string name="widget_habit_button">Habitica Do Habit</string>
|
||||
<string name="widget_task_list">Habitica Task List</string>
|
||||
<string name="widget_dailies">Habitica Dailies</string>
|
||||
<string name="widget_todo_list">Habitica Todo List</string>
|
||||
<string name="widget_add_task">Habitica Add Task</string>
|
||||
<string name="google_services_missing">Google play services could not be found.</string>
|
||||
<string name="gem.purchase.toolbartitle">Purchase</string>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
||||
</appwidget-provider>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<String, String> 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<TaskTypeSelectionViewAdapter.ViewHolder>
|
||||
{
|
||||
private HashMap<String, String> taskTypes;
|
||||
private TaskTypeSelected taskTypeSelected;
|
||||
|
||||
public TaskTypeSelectionViewAdapter(HashMap<String, String> 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<String> 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);
|
||||
}
|
||||
|
||||
|
|
@ -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<Task> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,3 +10,4 @@ public class DailiesWidgetService extends RemoteViewsService {
|
|||
return new DailiesListProvider(this.getApplicationContext(), intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Task> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.habitrpg.android.habitica.widget;
|
||||
|
||||
public class TodoListWidgetProvider extends TaskListWidgetProvider{
|
||||
|
||||
@Override
|
||||
protected Class getServiceClass() {
|
||||
return TodosWidgetService.class;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue