mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-14 21:18:51 -06:00
Implement score and frequency widgets for habit groups
This commit is contained in:
@@ -128,6 +128,15 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".widgets.activities.HabitAndGroupPickerDialog"
|
||||||
|
android:exported="true"
|
||||||
|
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">
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import android.net.Uri
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import org.isoron.uhabits.activities.habits.list.ListHabitsActivity
|
import org.isoron.uhabits.activities.habits.list.ListHabitsActivity
|
||||||
import org.isoron.uhabits.activities.habits.show.ShowHabitActivity
|
import org.isoron.uhabits.activities.habits.show.ShowHabitActivity
|
||||||
|
import org.isoron.uhabits.activities.habits.show.ShowHabitGroupActivity
|
||||||
import org.isoron.uhabits.core.AppScope
|
import org.isoron.uhabits.core.AppScope
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.HabitGroup
|
import org.isoron.uhabits.core.models.HabitGroup
|
||||||
@@ -124,6 +125,15 @@ class PendingIntentFactory
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showHabitGroupTemplate(): PendingIntent {
|
||||||
|
return getActivity(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
Intent(context, ShowHabitGroupActivity::class.java),
|
||||||
|
getIntentTemplateFlags()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun showHabitFillIn(habit: Habit) =
|
fun showHabitFillIn(habit: Habit) =
|
||||||
Intent().apply {
|
Intent().apply {
|
||||||
data = Uri.parse(habit.uriString)
|
data = Uri.parse(habit.uriString)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.widget.RemoteViews
|
|||||||
import org.isoron.uhabits.HabitsApplication
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.HabitGroup
|
||||||
import org.isoron.uhabits.core.models.HabitGroupList
|
import org.isoron.uhabits.core.models.HabitGroupList
|
||||||
import org.isoron.uhabits.core.models.HabitList
|
import org.isoron.uhabits.core.models.HabitList
|
||||||
import org.isoron.uhabits.core.models.HabitNotFoundException
|
import org.isoron.uhabits.core.models.HabitNotFoundException
|
||||||
@@ -114,12 +115,25 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
|
|||||||
val selectedHabits = ArrayList<Habit>(selectedIds.size)
|
val selectedHabits = ArrayList<Habit>(selectedIds.size)
|
||||||
for (id in selectedIds) {
|
for (id in selectedIds) {
|
||||||
val h = habits.getById(id) ?: habitGroups.getHabitByID(id)
|
val h = habits.getById(id) ?: habitGroups.getHabitByID(id)
|
||||||
?: throw HabitNotFoundException()
|
if (h != null) {
|
||||||
selectedHabits.add(h)
|
selectedHabits.add(h)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return selectedHabits
|
return selectedHabits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun getHabitGroupsFromWidgetId(widgetId: Int): List<HabitGroup> {
|
||||||
|
val selectedIds = widgetPrefs.getHabitIdsFromWidgetId(widgetId)
|
||||||
|
val selectedHabitGroups = ArrayList<HabitGroup>(selectedIds.size)
|
||||||
|
for (id in selectedIds) {
|
||||||
|
val hgr = habitGroups.getById(id)
|
||||||
|
if (hgr != null) {
|
||||||
|
selectedHabitGroups.add(hgr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedHabitGroups
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract fun getWidgetFromId(
|
protected abstract fun getWidgetFromId(
|
||||||
context: Context,
|
context: Context,
|
||||||
id: Int
|
id: Int
|
||||||
|
|||||||
@@ -25,32 +25,51 @@ import android.view.View
|
|||||||
import org.isoron.platform.gui.toInt
|
import org.isoron.platform.gui.toInt
|
||||||
import org.isoron.uhabits.activities.common.views.FrequencyChart
|
import org.isoron.uhabits.activities.common.views.FrequencyChart
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.HabitGroup
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardPresenter
|
||||||
import org.isoron.uhabits.core.ui.views.WidgetTheme
|
import org.isoron.uhabits.core.ui.views.WidgetTheme
|
||||||
import org.isoron.uhabits.widgets.views.GraphWidgetView
|
import org.isoron.uhabits.widgets.views.GraphWidgetView
|
||||||
|
|
||||||
class FrequencyWidget(
|
class FrequencyWidget private constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
widgetId: Int,
|
widgetId: Int,
|
||||||
private val habit: Habit,
|
private val habit: Habit?,
|
||||||
|
private val habitGroup: HabitGroup?,
|
||||||
private val firstWeekday: Int,
|
private val firstWeekday: Int,
|
||||||
stacked: Boolean = false
|
stacked: Boolean
|
||||||
) : BaseWidget(context, widgetId, stacked) {
|
) : BaseWidget(context, widgetId, stacked) {
|
||||||
|
|
||||||
|
constructor(context: Context, widgetId: Int, habit: Habit, firstWeekday: Int, stacked: Boolean = false) : this(context, widgetId, habit, null, firstWeekday, stacked)
|
||||||
|
constructor(context: Context, widgetId: Int, habitGroup: HabitGroup, firstWeekday: Int, stacked: Boolean = false) : this(context, widgetId, null, habitGroup, firstWeekday, stacked)
|
||||||
|
|
||||||
override val defaultHeight: Int = 200
|
override val defaultHeight: Int = 200
|
||||||
override val defaultWidth: Int = 200
|
override val defaultWidth: Int = 200
|
||||||
|
|
||||||
override fun getOnClickPendingIntent(context: Context): PendingIntent =
|
override fun getOnClickPendingIntent(context: Context): PendingIntent {
|
||||||
pendingIntentFactory.showHabit(habit)
|
return if (habit != null) {
|
||||||
|
pendingIntentFactory.showHabit(habit)
|
||||||
|
} else {
|
||||||
|
pendingIntentFactory.showHabitGroup(habitGroup!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun refreshData(v: View) {
|
override fun refreshData(v: View) {
|
||||||
val widgetView = v as GraphWidgetView
|
val widgetView = v as GraphWidgetView
|
||||||
widgetView.setTitle(habit.name)
|
widgetView.setTitle(habit?.name ?: habitGroup!!.name)
|
||||||
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||||
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
||||||
|
val color = habit?.color ?: habitGroup!!.color
|
||||||
|
val isNumerical = habit?.isNumerical ?: true
|
||||||
|
val frequency = if (habit != null) {
|
||||||
|
habit.originalEntries.computeWeekdayFrequency(habit.isNumerical)
|
||||||
|
} else {
|
||||||
|
FrequencyCardPresenter.getFrequenciesFromHabitGroup(habitGroup!!)
|
||||||
|
}
|
||||||
(widgetView.dataView as FrequencyChart).apply {
|
(widgetView.dataView as FrequencyChart).apply {
|
||||||
setFirstWeekday(firstWeekday)
|
setFirstWeekday(firstWeekday)
|
||||||
setColor(WidgetTheme().color(habit.color).toInt())
|
setColor(WidgetTheme().color(color).toInt())
|
||||||
setIsNumerical(habit.isNumerical)
|
setIsNumerical(isNumerical)
|
||||||
setFrequency(habit.originalEntries.computeWeekdayFrequency(habit.isNumerical))
|
setFrequency(frequency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,15 +24,29 @@ 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 {
|
||||||
val habits = getHabitsFromWidgetId(id)
|
val habits = getHabitsFromWidgetId(id)
|
||||||
return if (habits.size == 1) {
|
if (habits.isNotEmpty()) {
|
||||||
FrequencyWidget(
|
return if (habits.size == 1) {
|
||||||
context,
|
FrequencyWidget(
|
||||||
id,
|
context,
|
||||||
habits[0],
|
id,
|
||||||
preferences.firstWeekdayInt
|
habits[0],
|
||||||
)
|
preferences.firstWeekdayInt
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
|
val habitGroups = getHabitGroupsFromWidgetId(id)
|
||||||
|
return if (habitGroups.size == 1) {
|
||||||
|
FrequencyWidget(
|
||||||
|
context,
|
||||||
|
id,
|
||||||
|
habitGroups[0],
|
||||||
|
preferences.firstWeekdayInt
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
StackWidget(context, id, StackWidgetType.FREQUENCY, habitGroups, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,42 +25,62 @@ import android.view.View
|
|||||||
import org.isoron.platform.gui.toInt
|
import org.isoron.platform.gui.toInt
|
||||||
import org.isoron.uhabits.activities.common.views.ScoreChart
|
import org.isoron.uhabits.activities.common.views.ScoreChart
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.HabitGroup
|
||||||
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
|
||||||
import org.isoron.uhabits.core.ui.views.WidgetTheme
|
import org.isoron.uhabits.core.ui.views.WidgetTheme
|
||||||
import org.isoron.uhabits.widgets.views.GraphWidgetView
|
import org.isoron.uhabits.widgets.views.GraphWidgetView
|
||||||
|
|
||||||
class ScoreWidget(
|
class ScoreWidget private constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
id: Int,
|
id: Int,
|
||||||
private val habit: Habit,
|
private val habit: Habit?,
|
||||||
stacked: Boolean = false
|
private val habitGroup: HabitGroup?,
|
||||||
|
stacked: Boolean
|
||||||
) : BaseWidget(context, id, stacked) {
|
) : BaseWidget(context, id, stacked) {
|
||||||
|
constructor(context: Context, id: Int, habit: Habit, stacked: Boolean = false) : this(context, id, habit, null, stacked)
|
||||||
|
constructor(context: Context, id: Int, habitGroup: HabitGroup, stacked: Boolean = false) : this(context, id, null, habitGroup, stacked)
|
||||||
|
|
||||||
override val defaultHeight: Int = 300
|
override val defaultHeight: Int = 300
|
||||||
override val defaultWidth: Int = 300
|
override val defaultWidth: Int = 300
|
||||||
|
|
||||||
override fun getOnClickPendingIntent(context: Context): PendingIntent =
|
override fun getOnClickPendingIntent(context: Context): PendingIntent {
|
||||||
pendingIntentFactory.showHabit(habit)
|
return if (habit != null) {
|
||||||
|
pendingIntentFactory.showHabit(habit)
|
||||||
|
} else {
|
||||||
|
pendingIntentFactory.showHabitGroup(habitGroup!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun refreshData(view: View) {
|
override fun refreshData(view: View) {
|
||||||
val viewModel = ScoreCardPresenter.buildState(
|
val viewModel = if (habit != null) {
|
||||||
habit = habit,
|
ScoreCardPresenter.buildState(
|
||||||
firstWeekday = prefs.firstWeekdayInt,
|
habit = habit,
|
||||||
spinnerPosition = prefs.scoreCardSpinnerPosition,
|
firstWeekday = prefs.firstWeekdayInt,
|
||||||
theme = WidgetTheme()
|
spinnerPosition = prefs.scoreCardSpinnerPosition,
|
||||||
)
|
theme = WidgetTheme()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ScoreCardPresenter.buildState(
|
||||||
|
habitGroup = habitGroup!!,
|
||||||
|
firstWeekday = prefs.firstWeekdayInt,
|
||||||
|
spinnerPosition = prefs.scoreCardSpinnerPosition,
|
||||||
|
theme = WidgetTheme()
|
||||||
|
)
|
||||||
|
}
|
||||||
val widgetView = view as GraphWidgetView
|
val widgetView = view as GraphWidgetView
|
||||||
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||||
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
||||||
|
val color = habit?.color ?: habitGroup!!.color
|
||||||
(widgetView.dataView as ScoreChart).apply {
|
(widgetView.dataView as ScoreChart).apply {
|
||||||
setIsTransparencyEnabled(true)
|
setIsTransparencyEnabled(true)
|
||||||
setBucketSize(viewModel.bucketSize)
|
setBucketSize(viewModel.bucketSize)
|
||||||
setColor(WidgetTheme().color(habit.color).toInt())
|
setColor(WidgetTheme().color(color).toInt())
|
||||||
setScores(viewModel.scores)
|
setScores(viewModel.scores)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun buildView() =
|
override fun buildView() =
|
||||||
GraphWidgetView(context, ScoreChart(context)).apply {
|
GraphWidgetView(context, ScoreChart(context)).apply {
|
||||||
setTitle(habit.name)
|
setTitle(habit?.name ?: habitGroup!!.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,19 @@ import android.content.Context
|
|||||||
class ScoreWidgetProvider : BaseWidgetProvider() {
|
class ScoreWidgetProvider : BaseWidgetProvider() {
|
||||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||||
val habits = getHabitsFromWidgetId(id)
|
val habits = getHabitsFromWidgetId(id)
|
||||||
return if (habits.size == 1) {
|
if (habits.isNotEmpty()) {
|
||||||
ScoreWidget(context, id, habits[0])
|
return if (habits.size == 1) {
|
||||||
|
ScoreWidget(context, id, habits[0])
|
||||||
|
} else {
|
||||||
|
StackWidget(context, id, StackWidgetType.SCORE, habits)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
StackWidget(context, id, StackWidgetType.SCORE, habits)
|
val habitGroups = getHabitGroupsFromWidgetId(id)
|
||||||
|
return if (habitGroups.size == 1) {
|
||||||
|
ScoreWidget(context, id, habitGroups[0])
|
||||||
|
} else {
|
||||||
|
StackWidget(context, id, StackWidgetType.SCORE, habitGroups, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,14 +28,20 @@ import android.view.View
|
|||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import org.isoron.platform.utils.StringUtils
|
import org.isoron.platform.utils.StringUtils
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.HabitGroup
|
||||||
|
|
||||||
class StackWidget(
|
class StackWidget private constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
widgetId: Int,
|
widgetId: Int,
|
||||||
private val widgetType: StackWidgetType,
|
private val widgetType: StackWidgetType,
|
||||||
private val habits: List<Habit>,
|
private val habits: List<Habit>?,
|
||||||
stacked: Boolean = true
|
private val habitGroups: List<HabitGroup>?,
|
||||||
|
stacked: Boolean
|
||||||
) : BaseWidget(context, widgetId, stacked) {
|
) : BaseWidget(context, widgetId, stacked) {
|
||||||
|
|
||||||
|
constructor(context: Context, widgetId: Int, widgetType: StackWidgetType, habits: List<Habit>, stacked: Boolean = true) : this(context, widgetId, widgetType, habits, null, stacked)
|
||||||
|
constructor(context: Context, widgetId: Int, widgetType: StackWidgetType, habitGroups: List<HabitGroup>, stacked: Boolean = true, isHabitGroups: Boolean = false) : this(context, widgetId, widgetType, null, habitGroups, stacked)
|
||||||
|
|
||||||
override val defaultHeight: Int = 0
|
override val defaultHeight: Int = 0
|
||||||
override val defaultWidth: Int = 0
|
override val defaultWidth: Int = 0
|
||||||
|
|
||||||
@@ -55,7 +61,11 @@ class StackWidget(
|
|||||||
val remoteViews =
|
val remoteViews =
|
||||||
RemoteViews(context.packageName, StackWidgetType.getStackWidgetLayoutId(widgetType))
|
RemoteViews(context.packageName, StackWidgetType.getStackWidgetLayoutId(widgetType))
|
||||||
val serviceIntent = Intent(context, StackWidgetService::class.java)
|
val serviceIntent = Intent(context, StackWidgetService::class.java)
|
||||||
val habitIds = StringUtils.joinLongs(habits.map { it.id!! }.toLongArray())
|
val habitIds = if (habits != null) {
|
||||||
|
StringUtils.joinLongs(habits.map { it.id!! }.toLongArray())
|
||||||
|
} else {
|
||||||
|
StringUtils.joinLongs(habitGroups!!.map { it.id!! }.toLongArray())
|
||||||
|
}
|
||||||
|
|
||||||
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
|
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
|
||||||
serviceIntent.putExtra(StackWidgetService.WIDGET_TYPE, widgetType.value)
|
serviceIntent.putExtra(StackWidgetService.WIDGET_TYPE, widgetType.value)
|
||||||
@@ -73,9 +83,14 @@ class StackWidget(
|
|||||||
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
||||||
StackWidgetType.getStackWidgetEmptyViewId(widgetType)
|
StackWidgetType.getStackWidgetEmptyViewId(widgetType)
|
||||||
)
|
)
|
||||||
|
val pendingIntentTemplate = if (habits != null) {
|
||||||
|
StackWidgetType.getPendingIntentTemplate(pendingIntentFactory, widgetType, habits)
|
||||||
|
} else {
|
||||||
|
StackWidgetType.getPendingIntentTemplate(pendingIntentFactory, widgetType, true)
|
||||||
|
}
|
||||||
remoteViews.setPendingIntentTemplate(
|
remoteViews.setPendingIntentTemplate(
|
||||||
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
||||||
StackWidgetType.getPendingIntentTemplate(pendingIntentFactory, widgetType, habits)
|
pendingIntentTemplate
|
||||||
)
|
)
|
||||||
return remoteViews
|
return remoteViews
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import org.isoron.uhabits.R
|
|||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.Timestamp
|
import org.isoron.uhabits.core.models.Timestamp
|
||||||
import org.isoron.uhabits.intents.PendingIntentFactory
|
import org.isoron.uhabits.intents.PendingIntentFactory
|
||||||
import java.lang.IllegalStateException
|
|
||||||
|
|
||||||
enum class StackWidgetType(val value: Int) {
|
enum class StackWidgetType(val value: Int) {
|
||||||
CHECKMARK(0), FREQUENCY(1), SCORE(2), // habit strength widget
|
CHECKMARK(0), FREQUENCY(1), SCORE(2), // habit strength widget
|
||||||
@@ -95,6 +94,17 @@ enum class StackWidgetType(val value: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getPendingIntentTemplate(
|
||||||
|
factory: PendingIntentFactory,
|
||||||
|
widgetType: StackWidgetType,
|
||||||
|
isHabitGroups: Boolean
|
||||||
|
): PendingIntent {
|
||||||
|
return when (widgetType) {
|
||||||
|
CHECKMARK, HISTORY, STREAKS, TARGET -> throw RuntimeException()
|
||||||
|
FREQUENCY, SCORE -> factory.showHabitGroupTemplate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getIntentFillIn(
|
fun getIntentFillIn(
|
||||||
factory: PendingIntentFactory,
|
factory: PendingIntentFactory,
|
||||||
widgetType: StackWidgetType,
|
widgetType: StackWidgetType,
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ class NumericalHabitPickerDialog : HabitPickerDialog() {
|
|||||||
override fun getEmptyMessage() = R.string.no_numerical_habits
|
override fun getEmptyMessage() = R.string.no_numerical_habits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HabitAndGroupPickerDialog : HabitPickerDialog() {
|
||||||
|
override fun shouldShowGroups(): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
open class HabitPickerDialog : Activity() {
|
open class HabitPickerDialog : Activity() {
|
||||||
|
|
||||||
private var widgetId = 0
|
private var widgetId = 0
|
||||||
@@ -51,6 +55,8 @@ open class HabitPickerDialog : Activity() {
|
|||||||
|
|
||||||
protected open fun shouldHideNumerical() = false
|
protected open fun shouldHideNumerical() = false
|
||||||
protected open fun shouldHideBoolean() = false
|
protected open fun shouldHideBoolean() = false
|
||||||
|
|
||||||
|
protected open fun shouldShowGroups() = false
|
||||||
protected open fun getEmptyMessage() = R.string.no_habits
|
protected open fun getEmptyMessage() = R.string.no_habits
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -75,6 +81,10 @@ open class HabitPickerDialog : Activity() {
|
|||||||
|
|
||||||
for (hgr in habitGroupList) {
|
for (hgr in habitGroupList) {
|
||||||
if (hgr.isArchived) continue
|
if (hgr.isArchived) continue
|
||||||
|
if (shouldShowGroups()) {
|
||||||
|
habitIds.add(hgr.id!!)
|
||||||
|
habitNames.add(hgr.name)
|
||||||
|
}
|
||||||
|
|
||||||
for (h in hgr.habitList) {
|
for (h in hgr.habitList) {
|
||||||
if (h.isArchived) continue
|
if (h.isArchived) continue
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
android:previewImage="@drawable/widget_preview_frequency"
|
android:previewImage="@drawable/widget_preview_frequency"
|
||||||
android:resizeMode="vertical|horizontal"
|
android:resizeMode="vertical|horizontal"
|
||||||
android:updatePeriodMillis="3600000"
|
android:updatePeriodMillis="3600000"
|
||||||
android:configure="org.isoron.uhabits.widgets.activities.HabitPickerDialog"
|
android:configure="org.isoron.uhabits.widgets.activities.HabitAndGroupPickerDialog"
|
||||||
android:widgetCategory="home_screen">
|
android:widgetCategory="home_screen">
|
||||||
|
|
||||||
</appwidget-provider>
|
</appwidget-provider>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
android:previewImage="@drawable/widget_preview_score"
|
android:previewImage="@drawable/widget_preview_score"
|
||||||
android:resizeMode="vertical|horizontal"
|
android:resizeMode="vertical|horizontal"
|
||||||
android:updatePeriodMillis="3600000"
|
android:updatePeriodMillis="3600000"
|
||||||
android:configure="org.isoron.uhabits.widgets.activities.HabitPickerDialog"
|
android:configure="org.isoron.uhabits.widgets.activities.HabitAndGroupPickerDialog"
|
||||||
android:widgetCategory="home_screen">
|
android:widgetCategory="home_screen">
|
||||||
|
|
||||||
</appwidget-provider>
|
</appwidget-provider>
|
||||||
@@ -54,14 +54,7 @@ class FrequencyCardPresenter {
|
|||||||
firstWeekday: Int,
|
firstWeekday: Int,
|
||||||
theme: Theme
|
theme: Theme
|
||||||
): FrequencyCardState {
|
): FrequencyCardState {
|
||||||
val normalizedEntries = habitGroup.habitList.map {
|
val frequencies = getFrequenciesFromHabitGroup(habitGroup)
|
||||||
it.computedEntries.normalizeEntries(it.isNumerical, it.frequency, it.targetValue)
|
|
||||||
}
|
|
||||||
val frequencies = normalizedEntries.map {
|
|
||||||
it.computeWeekdayFrequency(isNumerical = true)
|
|
||||||
}.reduce { acc, hashMap ->
|
|
||||||
mergeMaps(acc, hashMap) { value1, value2 -> addArray(value1, value2) }
|
|
||||||
}
|
|
||||||
|
|
||||||
return FrequencyCardState(
|
return FrequencyCardState(
|
||||||
color = habitGroup.color,
|
color = habitGroup.color,
|
||||||
@@ -72,6 +65,18 @@ class FrequencyCardPresenter {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFrequenciesFromHabitGroup(habitGroup: HabitGroup): HashMap<Timestamp, Array<Int>> {
|
||||||
|
val normalizedEntries = habitGroup.habitList.map {
|
||||||
|
it.computedEntries.normalizeEntries(it.isNumerical, it.frequency, it.targetValue)
|
||||||
|
}
|
||||||
|
val frequencies = normalizedEntries.map {
|
||||||
|
it.computeWeekdayFrequency(isNumerical = true)
|
||||||
|
}.reduce { acc, hashMap ->
|
||||||
|
mergeMaps(acc, hashMap) { value1, value2 -> addArray(value1, value2) }
|
||||||
|
}
|
||||||
|
return frequencies
|
||||||
|
}
|
||||||
|
|
||||||
private fun <K, V> mergeMaps(map1: HashMap<K, V>, map2: HashMap<K, V>, mergeFunction: (V, V) -> V): HashMap<K, V> {
|
private fun <K, V> mergeMaps(map1: HashMap<K, V>, map2: HashMap<K, V>, mergeFunction: (V, V) -> V): HashMap<K, V> {
|
||||||
val result = map1 // Step 1
|
val result = map1 // Step 1
|
||||||
for ((key, value) in map2) { // Step 2
|
for ((key, value) in map2) { // Step 2
|
||||||
|
|||||||
Reference in New Issue
Block a user