mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Code review changes; Made 'stack view' design available for all widgets
This commit is contained in:
@@ -24,6 +24,7 @@ android {
|
|||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
buildToolsVersion '26.0.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buildToolsVersion '26.0.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0-beta6'
|
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||||
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
|
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
|
||||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ android {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
main.assets.srcDirs += '../uhabits-core/src/main/resources/'
|
main.assets.srcDirs += '../uhabits-core/src/main/resources/'
|
||||||
}
|
}
|
||||||
|
buildToolsVersion '26.0.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -84,13 +84,6 @@
|
|||||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".widgets.HabitGroupPickerDialog"
|
|
||||||
android:theme="@style/Theme.AppCompat.Light.Dialog">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.about.AboutActivity"
|
android:name=".activities.about.AboutActivity"
|
||||||
android:label="@string/about">
|
android:label="@string/about">
|
||||||
@@ -110,7 +103,7 @@
|
|||||||
android:name="android.appwidget.provider"
|
android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/widget_checkmark_info"/>
|
android:resource="@xml/widget_checkmark_info"/>
|
||||||
</receiver>
|
</receiver>
|
||||||
<service android:name=".widgets.CheckmarkStackWidgetService"
|
<service android:name=".widgets.StackWidgetService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS"
|
android:permission="android.permission.BIND_REMOTEVIEWS"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<receiver
|
<receiver
|
||||||
|
|||||||
@@ -141,10 +141,12 @@ public abstract class BaseWidgetProvider extends AppWidgetProvider
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
protected Habit getHabitFromWidgetId(int widgetId)
|
protected Habit getHabitFromWidgetId(int widgetId)
|
||||||
{
|
{
|
||||||
long habitId = widgetPrefs.getHabitIdFromWidgetId(widgetId);
|
long habitId = widgetPrefs.getHabitIdFromWidgetId(widgetId);
|
||||||
|
if (habitId == WidgetPreferences.STACK_WIDGET_HABITS) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Habit habit = habits.getById(habitId);
|
Habit habit = habits.getById(habitId);
|
||||||
if (habit == null) throw new HabitNotFoundException();
|
if (habit == null) throw new HabitNotFoundException();
|
||||||
return habit;
|
return habit;
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package org.isoron.uhabits.widgets
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import org.isoron.uhabits.HabitsApplication
|
|
||||||
|
|
||||||
class CheckmarkStackWidgetProvider : BaseWidgetProvider() {
|
|
||||||
|
|
||||||
override fun getWidgetFromId(context: Context, id: Int): CheckmarkStackWidget {
|
|
||||||
val habitIds = getHabitGroupFromWidget(context, id)
|
|
||||||
return CheckmarkStackWidget(context, id, habitIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getHabitGroupFromWidget(context: Context, widgetId: Int) : List<Long> {
|
|
||||||
val app = context.getApplicationContext() as HabitsApplication
|
|
||||||
val widgetPrefs = app.component.widgetPreferences
|
|
||||||
val habitIds = widgetPrefs.getHabitIdsGroupFromWidgetId(widgetId)
|
|
||||||
return habitIds
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,24 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.widgets
|
package org.isoron.uhabits.widgets
|
||||||
|
|
||||||
import android.content.*
|
import android.content.Context
|
||||||
import org.isoron.uhabits.HabitsApplication
|
|
||||||
|
|
||||||
class CheckmarkWidgetProvider : BaseWidgetProvider() {
|
class CheckmarkWidgetProvider : BaseWidgetProvider() {
|
||||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||||
try {
|
// if the habit was null, but did not have a habit id associated with a stack widget,
|
||||||
val habit = getHabitFromWidgetId(id)
|
// `getHabitFromWidgetId` will throw a HabitNotFoundException
|
||||||
|
val habit = getHabitFromWidgetId(id)
|
||||||
|
if (habit != null) {
|
||||||
return CheckmarkWidget(context, id, habit)
|
return CheckmarkWidget(context, id, habit)
|
||||||
} catch (e: Exception) {
|
} else {
|
||||||
val habitIds = getHabitIdsGroupFromWidget(context, id)
|
return StackWidget(context, id, StackWidgetType.CHECKMARK)
|
||||||
return CheckmarkStackWidget(context, id, habitIds)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHabitIdsGroupFromWidget(context: Context, widgetId: Int) : List<Long> {
|
|
||||||
val app = context.getApplicationContext() as HabitsApplication
|
|
||||||
val widgetPrefs = app.component.widgetPreferences
|
|
||||||
val habitIds = widgetPrefs.getHabitIdsGroupFromWidgetId(widgetId)
|
|
||||||
return habitIds
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,17 @@
|
|||||||
|
|
||||||
package org.isoron.uhabits.widgets
|
package org.isoron.uhabits.widgets
|
||||||
|
|
||||||
import android.content.*
|
import android.content.Context
|
||||||
|
|
||||||
class FrequencyWidgetProvider : BaseWidgetProvider() {
|
class FrequencyWidgetProvider : BaseWidgetProvider() {
|
||||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||||
|
// if the habit was null, but did not have a habit id associated with a stack widget,
|
||||||
|
// `getHabitFromWidgetId` will throw a HabitNotFoundException
|
||||||
val habit = getHabitFromWidgetId(id)
|
val habit = getHabitFromWidgetId(id)
|
||||||
return FrequencyWidget(context, id, habit)
|
if (habit != null) {
|
||||||
|
return FrequencyWidget(context, id, habit)
|
||||||
|
} else {
|
||||||
|
return StackWidget(context, id, StackWidgetType.FREQUENCY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Loop Habit Tracker.
|
|
||||||
*
|
|
||||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.isoron.uhabits.widgets
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
|
|
||||||
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.*
|
|
||||||
import android.widget.CompoundButton
|
|
||||||
import org.isoron.uhabits.HabitsApplication
|
|
||||||
import org.isoron.uhabits.R
|
|
||||||
import org.isoron.uhabits.core.models.HabitList
|
|
||||||
import org.isoron.uhabits.core.preferences.WidgetPreferences
|
|
||||||
|
|
||||||
class HabitGroupPickerDialog : Activity(), AdapterView.OnItemClickListener {
|
|
||||||
|
|
||||||
private var widgetId = 0
|
|
||||||
private lateinit var habitList: HabitList
|
|
||||||
private lateinit var preferences: WidgetPreferences
|
|
||||||
private lateinit var habitIds: ArrayList<Long>
|
|
||||||
private lateinit var widgetUpdater: WidgetUpdater
|
|
||||||
private lateinit var habitIdsSelected: ArrayList<Long>
|
|
||||||
private lateinit var habitListView: ListView
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
val component = (applicationContext as HabitsApplication).component
|
|
||||||
habitList = component.habitList
|
|
||||||
preferences = component.widgetPreferences
|
|
||||||
widgetUpdater = component.widgetUpdater
|
|
||||||
widgetId = intent.extras?.getInt(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID) ?: 0
|
|
||||||
habitIdsSelected = ArrayList<Long>()
|
|
||||||
|
|
||||||
habitIds = ArrayList<Long>()
|
|
||||||
val habitNames = ArrayList<String>()
|
|
||||||
for (h in habitList) {
|
|
||||||
if (h.isArchived) continue
|
|
||||||
habitIds.add(h.getId()!!)
|
|
||||||
habitNames.add(h.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
setContentView(R.layout.stack_widget_configure_activity)
|
|
||||||
habitListView = findViewById(R.id.stackWidgetListView) as ListView
|
|
||||||
with(habitListView) {
|
|
||||||
adapter = ListAdapter(context, R.layout.habit_checkbox_list_item,
|
|
||||||
R.id.listItemHabitName, R.id.listItemHabitCheckbox, habitNames)
|
|
||||||
onItemClickListener = this@HabitGroupPickerDialog
|
|
||||||
}
|
|
||||||
with(findViewById(R.id.doneConfigureButton) as Button) {
|
|
||||||
setOnClickListener {
|
|
||||||
if (habitIdsSelected.size == 1) {
|
|
||||||
preferences.addWidget(widgetId, habitIdsSelected.first())
|
|
||||||
widgetUpdater.updateWidgets()
|
|
||||||
setResult(Activity.RESULT_OK, Intent().apply {
|
|
||||||
putExtra(EXTRA_APPWIDGET_ID, widgetId)
|
|
||||||
})
|
|
||||||
finish()
|
|
||||||
} else if (!habitIdsSelected.isEmpty()) {
|
|
||||||
preferences.addWidget(widgetId, habitIdsSelected.toString())
|
|
||||||
widgetUpdater.updateWidgets()
|
|
||||||
setResult(Activity.RESULT_OK, Intent().apply {
|
|
||||||
putExtra(EXTRA_APPWIDGET_ID, widgetId)
|
|
||||||
})
|
|
||||||
finish()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, getString(R.string.select_habit_requirement_prompt),
|
|
||||||
Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClick(parent: AdapterView<*>,
|
|
||||||
view: View,
|
|
||||||
position: Int,
|
|
||||||
id: Long) {
|
|
||||||
val checkbox = view.findViewById(R.id.listItemHabitCheckbox) as CheckBox
|
|
||||||
checkbox.isChecked = !checkbox.isChecked
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class ListAdapter(context: Context,
|
|
||||||
private var layoutResource: Int,
|
|
||||||
private var textViewResourceId: Int,
|
|
||||||
private var checkBoxResourceId: Int,
|
|
||||||
private var habitNames: List<String>) :
|
|
||||||
ArrayAdapter<String>(context, layoutResource, textViewResourceId, habitNames) {
|
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
|
||||||
val layoutInflater: LayoutInflater = LayoutInflater.from(context)
|
|
||||||
val view = layoutInflater.inflate(layoutResource, null)
|
|
||||||
|
|
||||||
val item = getItem(position)
|
|
||||||
if (item != null) {
|
|
||||||
val tv = view.findViewById(textViewResourceId) as TextView
|
|
||||||
tv.text = habitNames.get(position)
|
|
||||||
val cb = view.findViewById(checkBoxResourceId) as CheckBox
|
|
||||||
cb.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
|
|
||||||
if (isChecked) {
|
|
||||||
habitIdsSelected.add(habitIds.get(position))
|
|
||||||
} else {
|
|
||||||
habitIdsSelected.remove(habitIds.get(position))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,6 +23,7 @@ import android.app.*
|
|||||||
import android.appwidget.AppWidgetManager.*
|
import android.appwidget.AppWidgetManager.*
|
||||||
import android.content.*
|
import android.content.*
|
||||||
import android.os.*
|
import android.os.*
|
||||||
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import org.isoron.uhabits.*
|
import org.isoron.uhabits.*
|
||||||
@@ -61,6 +62,16 @@ class HabitPickerDialog : Activity(), AdapterView.OnItemClickListener {
|
|||||||
habitNames)
|
habitNames)
|
||||||
onItemClickListener = this@HabitPickerDialog
|
onItemClickListener = this@HabitPickerDialog
|
||||||
}
|
}
|
||||||
|
with(findViewById(R.id.createStackWidgetButton) as Button) {
|
||||||
|
setOnClickListener(View.OnClickListener {
|
||||||
|
preferences.addWidget(widgetId, WidgetPreferences.STACK_WIDGET_HABITS)
|
||||||
|
widgetUpdater.updateWidgets()
|
||||||
|
setResult(Activity.RESULT_OK, Intent().apply {
|
||||||
|
putExtra(EXTRA_APPWIDGET_ID, widgetId)
|
||||||
|
})
|
||||||
|
finish()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(parent: AdapterView<*>,
|
override fun onItemClick(parent: AdapterView<*>,
|
||||||
|
|||||||
@@ -18,11 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.widgets
|
package org.isoron.uhabits.widgets
|
||||||
|
|
||||||
import android.content.*
|
import android.content.Context
|
||||||
|
|
||||||
class HistoryWidgetProvider : BaseWidgetProvider() {
|
class HistoryWidgetProvider : BaseWidgetProvider() {
|
||||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||||
|
// if the habit was null, but did not have a habit id associated with a stack widget,
|
||||||
|
// `getHabitFromWidgetId` will throw a HabitNotFoundException
|
||||||
val habit = getHabitFromWidgetId(id)
|
val habit = getHabitFromWidgetId(id)
|
||||||
return HistoryWidget(context, id, habit)
|
if (habit != null) {
|
||||||
|
return HistoryWidget(context, id, habit)
|
||||||
|
} else {
|
||||||
|
return StackWidget(context, id, StackWidgetType.HISTORY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.widgets
|
package org.isoron.uhabits.widgets
|
||||||
|
|
||||||
import android.content.*
|
import android.content.Context
|
||||||
import org.isoron.uhabits.*
|
import org.isoron.uhabits.HabitsApplication
|
||||||
|
|
||||||
class ScoreWidgetProvider : BaseWidgetProvider() {
|
class ScoreWidgetProvider : BaseWidgetProvider() {
|
||||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||||
val component = (context.applicationContext as HabitsApplication).component
|
// if the habit was null, but did not have a habit id associated with a stack widget,
|
||||||
|
// `getHabitFromWidgetId` will throw a HabitNotFoundException
|
||||||
val habit = getHabitFromWidgetId(id)
|
val habit = getHabitFromWidgetId(id)
|
||||||
return ScoreWidget(context, id, habit, component.preferences)
|
val component = (context.applicationContext as HabitsApplication).component
|
||||||
|
if (habit != null) {
|
||||||
|
return ScoreWidget(context, id, habit, component.preferences)
|
||||||
|
} else {
|
||||||
|
return StackWidget(context, id, StackWidgetType.SCORE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ package org.isoron.uhabits.widgets
|
|||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import org.isoron.uhabits.R
|
|
||||||
|
|
||||||
class CheckmarkStackWidget(
|
class StackWidget(
|
||||||
context: Context,
|
context: Context,
|
||||||
widgetId: Int,
|
widgetId: Int,
|
||||||
private val habitIds: List<Long>
|
private val widgetType: StackWidgetType
|
||||||
) : BaseWidget(context, widgetId) {
|
) : BaseWidget(context, widgetId) {
|
||||||
|
|
||||||
override fun getOnClickPendingIntent(context: Context) = null
|
override fun getOnClickPendingIntent(context: Context) = null
|
||||||
@@ -39,14 +39,16 @@ class CheckmarkStackWidget(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getRemoteViews(width: Int, height: Int): RemoteViews {
|
override fun getRemoteViews(width: Int, height: Int): RemoteViews {
|
||||||
val remoteViews = RemoteViews(context.packageName, R.layout.stackview_widget)
|
val remoteViews = RemoteViews(context.packageName, StackWidgetType.getStackWidgetLayoutId(widgetType))
|
||||||
val serviceIntent = Intent(context, CheckmarkStackWidgetService::class.java)
|
val serviceIntent = Intent(context, StackWidgetService::class.java)
|
||||||
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
|
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
|
||||||
serviceIntent.putExtra(CheckmarkStackWidgetService.HABIT_IDS_SELECTED, habitIds.toLongArray())
|
serviceIntent.putExtra(StackWidgetService.WIDGET_TYPE, widgetType.value)
|
||||||
remoteViews.setRemoteAdapter(R.id.stackWidgetView, serviceIntent)
|
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)))
|
||||||
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(id, R.id.stackWidgetView)
|
remoteViews.setRemoteAdapter(StackWidgetType.getStackWidgetAdapterViewId(widgetType), serviceIntent)
|
||||||
|
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(id, StackWidgetType.getStackWidgetAdapterViewId(widgetType))
|
||||||
// TODO what should the empty view look like?
|
// TODO what should the empty view look like?
|
||||||
remoteViews.setEmptyView(R.id.stackWidgetView, R.id.stackWidgetEmptyView)
|
remoteViews.setEmptyView(StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
||||||
|
StackWidgetType.getStackWidgetEmptyViewId(widgetType))
|
||||||
return remoteViews
|
return remoteViews
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,6 +4,8 @@ import android.appwidget.AppWidgetManager;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import android.widget.RemoteViewsService;
|
import android.widget.RemoteViewsService;
|
||||||
@@ -12,37 +14,36 @@ import org.isoron.uhabits.HabitsApplication;
|
|||||||
import org.isoron.uhabits.core.models.Habit;
|
import org.isoron.uhabits.core.models.Habit;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT;
|
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT;
|
||||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
|
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
|
||||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
|
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
|
||||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
|
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
|
||||||
import static org.isoron.androidbase.utils.InterfaceUtils.dpToPixels;
|
import static org.isoron.androidbase.utils.InterfaceUtils.dpToPixels;
|
||||||
import static org.isoron.uhabits.widgets.CheckmarkStackWidgetService.HABIT_IDS_SELECTED;
|
import static org.isoron.uhabits.widgets.StackWidgetService.WIDGET_TYPE;
|
||||||
|
|
||||||
public class CheckmarkStackWidgetService extends RemoteViewsService {
|
public class StackWidgetService extends RemoteViewsService {
|
||||||
|
|
||||||
public static final String HABIT_IDS_SELECTED = "HABIT_IDS_SELECTED";
|
public static final String WIDGET_TYPE = "WIDGET_TYPE";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||||
return new CheckmarkStackRemoteViewsFactory(this.getApplicationContext(), intent);
|
return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
|
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private int mAppWidgetId;
|
private int mAppWidgetId;
|
||||||
private ArrayList<Habit> mHabitList;
|
private ArrayList<Habit> mHabitList;
|
||||||
private List<Long> mHabitsSelected;
|
private StackWidgetType mWidgetType;
|
||||||
|
|
||||||
public CheckmarkStackRemoteViewsFactory(Context context, Intent intent) {
|
public StackRemoteViewsFactory(Context context, Intent intent) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||||
mHabitsSelected = new ArrayList<>();
|
int widgetTypeValue = intent.getIntExtra(WIDGET_TYPE, -1);
|
||||||
for (long id : intent.getLongArrayExtra(HABIT_IDS_SELECTED)) {
|
if (widgetTypeValue != -1) {
|
||||||
mHabitsSelected.add(id);
|
mWidgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViews
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
mHabitList.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
@@ -75,20 +76,62 @@ class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViews
|
|||||||
|
|
||||||
public RemoteViews getViewAt(int position) {
|
public RemoteViews getViewAt(int position) {
|
||||||
RemoteViews rv = null;
|
RemoteViews rv = null;
|
||||||
|
|
||||||
if (position < getCount()) {
|
if (position < getCount()) {
|
||||||
Habit habit = mHabitList.get(position);
|
Habit habit = mHabitList.get(position);
|
||||||
CheckmarkWidget checkmarkWidget = new CheckmarkWidget(mContext, mAppWidgetId, habit);
|
BaseWidget widget = initializeWidget(habit);
|
||||||
Bundle options = AppWidgetManager.getInstance(mContext).getAppWidgetOptions(mAppWidgetId);
|
Bundle options = AppWidgetManager.getInstance(mContext).getAppWidgetOptions(mAppWidgetId);
|
||||||
checkmarkWidget.setDimensions(getDimensionsFromOptions(mContext, options));
|
widget.setDimensions(getDimensionsFromOptions(mContext, options));
|
||||||
RemoteViews landscape = checkmarkWidget.getLandscapeRemoteViews();
|
final RemoteViews[] landscape = new RemoteViews[1];
|
||||||
RemoteViews portrait = checkmarkWidget.getPortraitRemoteViews();
|
final RemoteViews[] portrait = new RemoteViews[1];
|
||||||
rv = new RemoteViews(landscape, portrait);
|
|
||||||
|
Object lock = new Object();
|
||||||
|
final boolean[] flag = {false};
|
||||||
|
|
||||||
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
synchronized (lock) {
|
||||||
|
landscape[0] = widget.getLandscapeRemoteViews();
|
||||||
|
portrait[0] = widget.getPortraitRemoteViews();
|
||||||
|
flag[0] = true;
|
||||||
|
lock.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
synchronized (lock) {
|
||||||
|
while (!flag[0]) {
|
||||||
|
try {
|
||||||
|
lock.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = new RemoteViews(landscape[0], portrait[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BaseWidget initializeWidget(Habit habit) {
|
||||||
|
switch (mWidgetType) {
|
||||||
|
case CHECKMARK:
|
||||||
|
return new CheckmarkWidget(mContext, mAppWidgetId, habit);
|
||||||
|
case FREQUENCY:
|
||||||
|
return new FrequencyWidget(mContext, mAppWidgetId, habit);
|
||||||
|
case SCORE:
|
||||||
|
HabitsApplication app = (HabitsApplication) mContext.getApplicationContext();
|
||||||
|
return new ScoreWidget(mContext, mAppWidgetId, habit, app.getComponent().getPreferences());
|
||||||
|
case HISTORY:
|
||||||
|
return new HistoryWidget(mContext, mAppWidgetId, habit);
|
||||||
|
case STREAKS:
|
||||||
|
return new StreakWidget(mContext, mAppWidgetId, habit);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public RemoteViews getLoadingView() {
|
public RemoteViews getLoadingView() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -109,9 +152,7 @@ class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViews
|
|||||||
mHabitList = new ArrayList<>();
|
mHabitList = new ArrayList<>();
|
||||||
HabitsApplication app = (HabitsApplication) mContext.getApplicationContext();
|
HabitsApplication app = (HabitsApplication) mContext.getApplicationContext();
|
||||||
for (Habit h : app.getComponent().getHabitList()) {
|
for (Habit h : app.getComponent().getHabitList()) {
|
||||||
if (mHabitsSelected.contains(h.getId())) {
|
mHabitList.add(h);
|
||||||
mHabitList.add(h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package org.isoron.uhabits.widgets;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by victoryu on 11/3/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum StackWidgetType {
|
||||||
|
|
||||||
|
CHECKMARK(0),
|
||||||
|
FREQUENCY(1),
|
||||||
|
SCORE(2), // habit strength widget
|
||||||
|
HISTORY(3),
|
||||||
|
STREAKS(4);
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
StackWidgetType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StackWidgetType getWidgetTypeFromValue(int value) {
|
||||||
|
if (CHECKMARK.getValue() == value) {
|
||||||
|
return CHECKMARK;
|
||||||
|
} else if (FREQUENCY.getValue() == value) {
|
||||||
|
return FREQUENCY;
|
||||||
|
} else if (SCORE.getValue() == value) {
|
||||||
|
return SCORE;
|
||||||
|
} else if (HISTORY.getValue() == value) {
|
||||||
|
return HISTORY;
|
||||||
|
} else if (STREAKS.getValue() == value) {
|
||||||
|
return STREAKS;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getStackWidgetLayoutId(StackWidgetType type) {
|
||||||
|
switch (type) {
|
||||||
|
case CHECKMARK:
|
||||||
|
return R.layout.checkmark_stackview_widget;
|
||||||
|
case FREQUENCY:
|
||||||
|
return R.layout.frequency_stackview_widget;
|
||||||
|
case SCORE:
|
||||||
|
return R.layout.score_stackview_widget;
|
||||||
|
case HISTORY:
|
||||||
|
return R.layout.history_stackview_widget;
|
||||||
|
case STREAKS:
|
||||||
|
return R.layout.streak_stackview_widget;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getStackWidgetAdapterViewId(StackWidgetType type) {
|
||||||
|
switch (type) {
|
||||||
|
case CHECKMARK:
|
||||||
|
return R.id.checkmarkStackWidgetView;
|
||||||
|
case FREQUENCY:
|
||||||
|
return R.id.frequencyStackWidgetView;
|
||||||
|
case SCORE:
|
||||||
|
return R.id.scoreStackWidgetView;
|
||||||
|
case HISTORY:
|
||||||
|
return R.id.historyStackWidgetView;
|
||||||
|
case STREAKS:
|
||||||
|
return R.id.streakStackWidgetView;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getStackWidgetEmptyViewId(StackWidgetType type) {
|
||||||
|
switch (type) {
|
||||||
|
case CHECKMARK:
|
||||||
|
return R.id.checkmarkStackWidgetEmptyView;
|
||||||
|
case FREQUENCY:
|
||||||
|
return R.id.frequencyStackWidgetEmptyView;
|
||||||
|
case SCORE:
|
||||||
|
return R.id.scoreStackWidgetEmptyView;
|
||||||
|
case HISTORY:
|
||||||
|
return R.id.historyStackWidgetEmptyView;
|
||||||
|
case STREAKS:
|
||||||
|
return R.id.streakStackWidgetEmptyView;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,11 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.widgets
|
package org.isoron.uhabits.widgets
|
||||||
|
|
||||||
import android.content.*
|
import android.content.Context
|
||||||
|
|
||||||
class StreakWidgetProvider : BaseWidgetProvider() {
|
class StreakWidgetProvider : BaseWidgetProvider() {
|
||||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||||
|
// if the habit was null, but did not have a habit id associated with a stack widget,
|
||||||
|
// `getHabitFromWidgetId` will throw a HabitNotFoundException
|
||||||
val habit = getHabitFromWidgetId(id)
|
val habit = getHabitFromWidgetId(id)
|
||||||
return StreakWidget(context, id, habit)
|
if (habit != null) {
|
||||||
|
return StreakWidget(context, id, habit)
|
||||||
|
} else {
|
||||||
|
return StackWidget(context, id, StackWidgetType.STREAKS)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/stackWidgetView"
|
android:id="@+id/checkmarkStackWidgetView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:loopViews="true" />
|
android:loopViews="true" />
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/stackWidgetEmptyView"
|
android:id="@+id/checkmarkStackWidgetEmptyView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/checkmark_stack_widget"
|
android:text="@string/checkmark_stack_widget"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/frequencyStackWidgetView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:loopViews="true" />
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/frequencyStackWidgetEmptyView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/frequency_stack_widget"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</FrameLayout>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/historyStackWidgetView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:loopViews="true" />
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/historyStackWidgetEmptyView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/history_stack_widget"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</FrameLayout>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/scoreStackWidgetView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:loopViews="true" />
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/scoreStackWidgetEmptyView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/score_stack_widget"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</FrameLayout>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/streakStackWidgetView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:loopViews="true" />
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/streakStackWidgetEmptyView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/streaks_stack_widget"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</FrameLayout>
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
<!--
|
|
||||||
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
~
|
~
|
||||||
~ This file is part of Loop Habit Tracker.
|
~ This file is part of Loop Habit Tracker.
|
||||||
@@ -18,10 +17,23 @@
|
|||||||
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<ListView android:id="@+id/listView"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:orientation="vertical">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
</ListView>
|
<Button
|
||||||
|
android:id="@+id/createStackWidgetButton"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:text="@string/create_stackview_widget_button"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/listView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_weight="1">
|
||||||
|
</ListView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -125,7 +125,13 @@
|
|||||||
<string name="version_n">Version %s</string>
|
<string name="version_n">Version %s</string>
|
||||||
<string name="frequency">Frequency</string>
|
<string name="frequency">Frequency</string>
|
||||||
<string name="checkmark">Checkmark</string>
|
<string name="checkmark">Checkmark</string>
|
||||||
|
<string name="create_stackview_widget_button">StackView Widget For All Habits</string>
|
||||||
<string name="checkmark_stack_widget">Checkmark Stack Widget</string>
|
<string name="checkmark_stack_widget">Checkmark Stack Widget</string>
|
||||||
|
<string name="frequency_stack_widget">Frequency Stack Widget</string>
|
||||||
|
<string name="score_stack_widget">Score Stack Widget</string>
|
||||||
|
<string name="history_stack_widget">History Stack Widget</string>
|
||||||
|
<string name="streaks_stack_widget">Streaks Stack Widget</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="strength">Strength</string>
|
<string name="strength">Strength</string>
|
||||||
<string name="best_streaks">Best streaks</string>
|
<string name="best_streaks">Best streaks</string>
|
||||||
|
|||||||
@@ -25,6 +25,6 @@
|
|||||||
android:previewImage="@drawable/widget_preview_checkmark"
|
android:previewImage="@drawable/widget_preview_checkmark"
|
||||||
android:resizeMode="none"
|
android:resizeMode="none"
|
||||||
android:updatePeriodMillis="3600000"
|
android:updatePeriodMillis="3600000"
|
||||||
android:configure="org.isoron.uhabits.widgets.HabitGroupPickerDialog"
|
android:configure="org.isoron.uhabits.widgets.HabitPickerDialog"
|
||||||
android:widgetCategory="home_screen">
|
android:widgetCategory="home_screen">
|
||||||
</appwidget-provider>
|
</appwidget-provider>
|
||||||
@@ -21,11 +21,6 @@ package org.isoron.uhabits.core.preferences;
|
|||||||
|
|
||||||
import org.isoron.uhabits.core.AppScope;
|
import org.isoron.uhabits.core.AppScope;
|
||||||
import org.isoron.uhabits.core.models.HabitNotFoundException;
|
import org.isoron.uhabits.core.models.HabitNotFoundException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -33,6 +28,9 @@ import javax.inject.Inject;
|
|||||||
public class WidgetPreferences {
|
public class WidgetPreferences {
|
||||||
private Preferences.Storage storage;
|
private Preferences.Storage storage;
|
||||||
|
|
||||||
|
public static final long STACK_WIDGET_HABITS = -1;
|
||||||
|
public static final long HABIT_NOT_FOUND = -2;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public WidgetPreferences(Preferences.Storage storage) {
|
public WidgetPreferences(Preferences.Storage storage) {
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
@@ -42,32 +40,13 @@ public class WidgetPreferences {
|
|||||||
storage.putLong(getHabitIdKey(widgetId), habitId);
|
storage.putLong(getHabitIdKey(widgetId), habitId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param habitIds the string should be in the format: [habitId1, habitId2, habitId3...]
|
|
||||||
*/
|
|
||||||
public void addWidget(int widgetId, String habitIds) {
|
|
||||||
storage.putString(getHabitIdKey(widgetId), habitIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getHabitIdFromWidgetId(int widgetId) {
|
public long getHabitIdFromWidgetId(int widgetId) {
|
||||||
Long habitId = storage.getLong(getHabitIdKey(widgetId), -1);
|
Long habitId = storage.getLong(getHabitIdKey(widgetId), HABIT_NOT_FOUND);
|
||||||
if (habitId < 0) throw new HabitNotFoundException();
|
if (habitId == HABIT_NOT_FOUND) throw new HabitNotFoundException();
|
||||||
|
|
||||||
return habitId;
|
return habitId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> getHabitIdsGroupFromWidgetId(int widgetId) {
|
|
||||||
String habitIdsGroup = storage.getString(getHabitIdKey(widgetId), "");
|
|
||||||
if (habitIdsGroup.isEmpty()) throw new HabitNotFoundException();
|
|
||||||
|
|
||||||
ArrayList<Long> habitIdList = new ArrayList<>();
|
|
||||||
for (String s : parseStringToList(habitIdsGroup)) {
|
|
||||||
habitIdList.add(Long.parseLong(s.trim()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return habitIdList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeWidget(int id) {
|
public void removeWidget(int id) {
|
||||||
String habitIdKey = getHabitIdKey(id);
|
String habitIdKey = getHabitIdKey(id);
|
||||||
storage.remove(habitIdKey);
|
storage.remove(habitIdKey);
|
||||||
@@ -76,9 +55,4 @@ public class WidgetPreferences {
|
|||||||
private String getHabitIdKey(int id) {
|
private String getHabitIdKey(int id) {
|
||||||
return String.format("widget-%06d-habit", id);
|
return String.format("widget-%06d-habit", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> parseStringToList(@NotNull String str) {
|
|
||||||
return Arrays.asList(str.replace("[", "")
|
|
||||||
.replace("]", "").split(","));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user