diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt index c20e80d46..fb4117920 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt @@ -22,6 +22,7 @@ import com.habitrpg.android.habitica.models.user.User import io.reactivex.Flowable import retrofit2.http.* +@JvmSuppressWildcards interface ApiService { @get:GET("status") val status: Flowable> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt index 6e98dacd2..cabb4db41 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt @@ -16,6 +16,7 @@ import java.util.* interface TaskRepository : BaseRepository { fun getTasks(taskType: String, userID: String): Flowable> fun getTasks(userId: String): Flowable> + fun getCurrentUserTasks(taskType: String): Flowable> fun getTasksOfType(taskType: String): Flowable> fun saveTasks(userId: String, order: TasksOrder, tasks: TaskList) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt index ff2d006a9..c9bf87c2f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt @@ -32,6 +32,9 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli override fun getTasks(userId: String): Flowable> = this.localRepository.getTasks(userId) + override fun getCurrentUserTasks(taskType: String): Flowable> = + this.localRepository.getTasks(taskType, userID) + override fun saveTasks(userId: String, order: TasksOrder, tasks: TaskList) { localRepository.saveTasks(userId, order, tasks) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt index d5c942446..ed002e14e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt @@ -1,6 +1,5 @@ package com.habitrpg.android.habitica.interactors -import android.graphics.Bitmap import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import com.habitrpg.android.habitica.R @@ -12,8 +11,8 @@ import com.habitrpg.android.habitica.helpers.SoundManager import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.AvatarView -import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import io.reactivex.Flowable import io.reactivex.functions.Consumer import org.greenrobot.eventbus.EventBus @@ -62,13 +61,9 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut val event = ShareEvent() event.sharedMessage = requestValues.activity.getString(R.string.share_levelup, requestValues.newLevel) + " https://habitica.com/social/level-UP" - val avatarView = AvatarView(requestValues.activity, true, true, true) + val avatarView = AvatarView(requestValues.activity, showBackground = true, showMount = true, showPet = true) avatarView.setAvatar(requestValues.user) - avatarView.onAvatarImageReady(object : AvatarView.Consumer { - override fun accept(t: Bitmap?) { - event.shareImage = t - } - }) + avatarView.onAvatarImageReady(Consumer { t -> event.shareImage = t }) val alert = HabiticaAlertDialog(requestValues.activity) alert.setTitle(requestValues.activity.getString(R.string.levelup_header, requestValues.newLevel)) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt index 6ccf799f0..d5a45e0e6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt @@ -188,10 +188,8 @@ open class User : RealmObject(), Avatar, VersionedObject { return (this.balance * 4).toInt() } - override fun getHourglassCount(): Int? { - return if (purchased != null) { - purchased?.plan?.consecutive?.trinkets - } else 0 + override fun getHourglassCount(): Int { + return purchased?.plan?.consecutive?.trinkets ?: 0 } override fun getCostume(): Outfit? { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt index 8d23f1de5..53ecec408 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt @@ -18,6 +18,7 @@ import com.facebook.imagepipeline.image.ImageInfo import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.models.Avatar +import io.reactivex.functions.Consumer import java.util.* import java.util.concurrent.atomic.AtomicInteger @@ -518,10 +519,6 @@ class AvatarView : View { PET } - interface Consumer { - fun accept(t: T) - } - companion object { const val IMAGE_URI_ROOT = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/" private const val TAG = "AvatarView" diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.java deleted file mode 100644 index 36b9cfe27..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.appwidget.AppWidgetManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.widget.RemoteViews; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.tasks.Task; - -public class AddTaskWidgetProvider extends BaseWidgetProvider { - - @Override - public int layoutResourceId() { - return R.layout.widget_add_task; - } - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - super.onUpdate(context, appWidgetManager, appWidgetIds); - // Get all ids - ComponentName thisWidget = new ComponentName(context, - AddTaskWidgetProvider.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)); - } - } - } - - @Override - public RemoteViews configureRemoteViews(RemoteViews remoteViews, int widgetId, int columns, int rows) { - - String selectedTaskType = getSelectedTaskType(widgetId); - String addText = ""; - int backgroundResource = R.drawable.widget_add_habit_background; - switch (selectedTaskType) { - case Task.TYPE_HABIT: - addText = this.getContext().getResources().getString(R.string.add_habit); - backgroundResource = R.drawable.widget_add_habit_background; - break; - case Task.TYPE_DAILY: - addText = this.getContext().getResources().getString(R.string.add_daily); - backgroundResource = R.drawable.widget_add_daily_background; - break; - case Task.TYPE_TODO: - addText = this.getContext().getResources().getString(R.string.add_todo); - backgroundResource = R.drawable.widget_add_todo_background; - break; - case Task.TYPE_REWARD: - addText = this.getContext().getResources().getString(R.string.add_reward); - backgroundResource = R.drawable.widget_add_reward_background; - break; - } - remoteViews.setTextViewText(R.id.add_task_text, addText); - remoteViews.setInt(R.id.add_task_icon, "setBackgroundResource", backgroundResource); - return remoteViews; - } - - private String getSelectedTaskType(int widgetId) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext()); - return preferences.getString("add_task_widget_" + widgetId, Task.TYPE_HABIT); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt new file mode 100644 index 000000000..95a5cfad9 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt @@ -0,0 +1,63 @@ +package com.habitrpg.android.habitica.widget + +import android.appwidget.AppWidgetManager +import android.content.ComponentName +import android.content.Context +import android.preference.PreferenceManager +import android.widget.RemoteViews +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.models.tasks.Task + +class AddTaskWidgetProvider : BaseWidgetProvider() { + + override fun layoutResourceId(): Int { + return R.layout.widget_add_task + } + + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { + super.onUpdate(context, appWidgetManager, appWidgetIds) + // Get all ids + val thisWidget = ComponentName(context, + AddTaskWidgetProvider::class.java) + val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) + + for (widgetId in allWidgetIds) { + val options = appWidgetManager.getAppWidgetOptions(widgetId) + appWidgetManager.partiallyUpdateAppWidget(widgetId, + sizeRemoteViews(context, options, widgetId)) + } + } + + override fun configureRemoteViews(remoteViews: RemoteViews, widgetId: Int, columns: Int, rows: Int): RemoteViews { + + val selectedTaskType = getSelectedTaskType(widgetId) + var addText: String? = "" + var backgroundResource = R.drawable.widget_add_habit_background + when (selectedTaskType) { + Task.TYPE_HABIT -> { + addText = context?.resources?.getString(R.string.add_habit) + backgroundResource = R.drawable.widget_add_habit_background + } + Task.TYPE_DAILY -> { + addText = context?.resources?.getString(R.string.add_daily) + backgroundResource = R.drawable.widget_add_daily_background + } + Task.TYPE_TODO -> { + addText = context?.resources?.getString(R.string.add_todo) + backgroundResource = R.drawable.widget_add_todo_background + } + Task.TYPE_REWARD -> { + addText = context?.resources?.getString(R.string.add_reward) + backgroundResource = R.drawable.widget_add_reward_background + } + } + remoteViews.setTextViewText(R.id.add_task_text, addText) + remoteViews.setInt(R.id.add_task_icon, "setBackgroundResource", backgroundResource) + return remoteViews + } + + private fun getSelectedTaskType(widgetId: Int): String { + val preferences = PreferenceManager.getDefaultSharedPreferences(this.context) + return preferences.getString("add_task_widget_$widgetId", Task.TYPE_HABIT) ?: "" + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.java deleted file mode 100644 index 1c76a8bd3..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.java +++ /dev/null @@ -1,154 +0,0 @@ -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.os.Build; -import android.os.Bundle; -import android.view.View; -import android.widget.RemoteViews; - -import androidx.annotation.NonNull; - -import com.habitrpg.android.habitica.HabiticaBaseApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.UserRepository; -import com.habitrpg.android.habitica.helpers.HealthFormatter; -import com.habitrpg.android.habitica.helpers.NumberAbbreviator; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.user.Stats; -import com.habitrpg.android.habitica.models.user.User; -import com.habitrpg.android.habitica.modules.AppModule; -import com.habitrpg.android.habitica.ui.AvatarView; -import com.habitrpg.android.habitica.ui.activities.MainActivity; -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper; - -import java.util.Objects; - -import javax.inject.Inject; -import javax.inject.Named; - -public class AvatarStatsWidgetProvider extends BaseWidgetProvider { - - private AppWidgetManager appWidgetManager; - - @Override - public int layoutResourceId() { - return R.layout.widget_avatar_stats; - } - - @Inject - @Named(AppModule.NAMED_USER_ID) - String userId; - @Inject - UserRepository userRepository; - private Boolean showManaBar = true; - - private void setUp() { - if (userRepository == null) { - Objects.requireNonNull(HabiticaBaseApplication.Companion.getUserComponent()).inject(this); - } - } - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - super.onUpdate(context, appWidgetManager, appWidgetIds); - this.setUp(); - this.appWidgetManager = appWidgetManager; - this.setContext(context); - - userRepository.getUser(userId).firstElement().subscribe(this::updateData, RxErrorHandler.Companion.handleEmptyError()); - } - - @NonNull - @Override - public RemoteViews configureRemoteViews(@NonNull RemoteViews remoteViews, int widgetId, int columns, int rows) { - if (columns > 3) { - remoteViews.setViewVisibility(R.id.avatar_view, View.VISIBLE); - } else { - remoteViews.setViewVisibility(R.id.avatar_view, View.GONE); - } - - showManaBar = rows > 1; - if (rows > 1) { - remoteViews.setViewVisibility(R.id.mp_wrapper, View.VISIBLE); - remoteViews.setViewVisibility(R.id.detail_info_view, View.VISIBLE); - } else { - remoteViews.setViewVisibility(R.id.mp_wrapper, View.GONE); - remoteViews.setViewVisibility(R.id.detail_info_view, View.GONE); - } - - return remoteViews; - } - - private void updateData(User user) { - if (user == null || user.getStats() == null) { - return; - } - Stats stats = user.getStats(); - ComponentName thisWidget = new ComponentName(getContext(), AvatarStatsWidgetProvider.class); - int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); - Double currentHealth = HealthFormatter.format(stats.getHp()); - String currentHealthString = HealthFormatter.formatToString(stats.getHp()); - String healthValueString = currentHealthString + "/" + stats.getMaxHealth(); - String expValueString = "" + stats.getExp().intValue() + "/" + stats.getToNextLevel(); - String mpValueString = "" + stats.getMp().intValue() + "/" + stats.getMaxMP(); - - for (int widgetId : allWidgetIds) { - RemoteViews remoteViews = new RemoteViews(getContext().getPackageName(), R.layout.widget_avatar_stats); - - remoteViews.setTextViewText(R.id.TV_hp_value, healthValueString); - remoteViews.setTextViewText(R.id.exp_TV_value, expValueString); - remoteViews.setTextViewText(R.id.mp_TV_value, mpValueString); - - remoteViews.setImageViewBitmap(R.id.ic_hp_header, HabiticaIconsHelper.imageOfHeartDarkBg()); - remoteViews.setImageViewBitmap(R.id.ic_exp_header, HabiticaIconsHelper.imageOfExperience()); - remoteViews.setImageViewBitmap(R.id.ic_mp_header, HabiticaIconsHelper.imageOfMagic()); - - remoteViews.setProgressBar(R.id.hp_bar, stats.getMaxHealth(), currentHealth.intValue(), false); - remoteViews.setProgressBar(R.id.exp_bar, stats.getToNextLevel(), stats.getExp().intValue(), false); - remoteViews.setProgressBar(R.id.mp_bar, stats.getMaxMP(), stats.getMp().intValue(), false); - remoteViews.setViewVisibility(R.id.mp_wrapper, showManaBar && ( stats.getHabitClass() == null || stats.getLvl() < 10 || user.getPreferences().getDisableClasses()) ? View.GONE : View.VISIBLE); - - remoteViews.setTextViewText(R.id.gold_tv, NumberAbbreviator.INSTANCE.abbreviate(getContext(), stats.getGp())); - remoteViews.setTextViewText(R.id.gems_tv, String.valueOf((int) (user.getBalance() * 4))); - int hourGlassCount = user.getHourglassCount(); - if (hourGlassCount == 0) { - remoteViews.setViewVisibility(R.id.hourglass_icon, View.GONE); - remoteViews.setViewVisibility(R.id.hourglasses_tv, View.GONE); - } else { - remoteViews.setImageViewBitmap(R.id.hourglass_icon, HabiticaIconsHelper.imageOfHourglass()); - remoteViews.setViewVisibility(R.id.hourglass_icon, View.VISIBLE); - remoteViews.setTextViewText(R.id.hourglasses_tv, String.valueOf(hourGlassCount)); - remoteViews.setViewVisibility(R.id.hourglasses_tv, View.VISIBLE); - } - remoteViews.setImageViewBitmap(R.id.gem_icon, HabiticaIconsHelper.imageOfGem()); - remoteViews.setImageViewBitmap(R.id.gold_icon, HabiticaIconsHelper.imageOfGold()); - remoteViews.setTextViewText(R.id.lvl_tv, getContext().getString(R.string.user_level, user.getStats().getLvl())); - - AvatarView avatarView = new AvatarView(getContext(), true, true, true); - - avatarView.setAvatar(user); - RemoteViews finalRemoteViews = remoteViews; - avatarView.onAvatarImageReady(bitmap -> { - finalRemoteViews.setImageViewBitmap(R.id.avatar_view, bitmap); - appWidgetManager.partiallyUpdateAppWidget(allWidgetIds, finalRemoteViews); - }); - - //If user click on life and xp: open the app - Intent openAppIntent = new Intent(getContext().getApplicationContext(), MainActivity.class); - PendingIntent openApp = PendingIntent.getActivity(getContext(), 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); - remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp); - - - if (Build.VERSION.SDK_INT >= 16) { - Bundle options = appWidgetManager.getAppWidgetOptions(widgetId); - remoteViews = sizeRemoteViews(getContext(), options, widgetId); - } - - appWidgetManager.updateAppWidget(widgetId, remoteViews); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt new file mode 100644 index 000000000..b817fe4b5 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt @@ -0,0 +1,134 @@ +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.view.View +import android.widget.RemoteViews +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.helpers.HealthFormatter +import com.habitrpg.android.habitica.helpers.NumberAbbreviator +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.android.habitica.ui.activities.MainActivity +import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import io.reactivex.functions.Consumer + +class AvatarStatsWidgetProvider : BaseWidgetProvider() { + + private var appWidgetManager: AppWidgetManager? = null + + private var showManaBar: Boolean = true + + override fun layoutResourceId(): Int { + return R.layout.widget_avatar_stats + } + + private fun setUp() { + if (!hasInjected) { + hasInjected = true + HabiticaBaseApplication.userComponent?.inject(this) + } + } + + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { + super.onUpdate(context, appWidgetManager, appWidgetIds) + this.setUp() + this.appWidgetManager = appWidgetManager + this.context = context + + userRepository?.getUser()?.firstElement()?.subscribe(Consumer { this.updateData(it) }, RxErrorHandler.handleEmptyError()) + } + + override fun configureRemoteViews(remoteViews: RemoteViews, widgetId: Int, columns: Int, rows: Int): RemoteViews { + if (columns > 3) { + remoteViews.setViewVisibility(R.id.avatar_view, View.VISIBLE) + } else { + remoteViews.setViewVisibility(R.id.avatar_view, View.GONE) + } + + showManaBar = rows > 1 + if (rows > 1) { + remoteViews.setViewVisibility(R.id.mp_wrapper, View.VISIBLE) + remoteViews.setViewVisibility(R.id.detail_info_view, View.VISIBLE) + } else { + remoteViews.setViewVisibility(R.id.mp_wrapper, View.GONE) + remoteViews.setViewVisibility(R.id.detail_info_view, View.GONE) + } + + return remoteViews + } + + private fun updateData(user: User?) { + val context = context + val appWidgetManager = appWidgetManager + val stats = user?.stats + if (user == null || stats == null || context == null || appWidgetManager == null) { + return + } + val thisWidget = ComponentName(context, AvatarStatsWidgetProvider::class.java) + val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) + val currentHealth = HealthFormatter.format(stats.hp ?: 0.0) + val currentHealthString = HealthFormatter.formatToString(stats.hp ?: 0.0) + val healthValueString = currentHealthString + "/" + stats.maxHealth + val expValueString = "" + stats.exp?.toInt() + "/" + stats.toNextLevel + val mpValueString = "" + stats.mp?.toInt() + "/" + stats.maxMP + + for (widgetId in allWidgetIds) { + var remoteViews = RemoteViews(context.packageName, R.layout.widget_avatar_stats) + + remoteViews.setTextViewText(R.id.TV_hp_value, healthValueString) + remoteViews.setTextViewText(R.id.exp_TV_value, expValueString) + remoteViews.setTextViewText(R.id.mp_TV_value, mpValueString) + + remoteViews.setImageViewBitmap(R.id.ic_hp_header, HabiticaIconsHelper.imageOfHeartDarkBg()) + remoteViews.setImageViewBitmap(R.id.ic_exp_header, HabiticaIconsHelper.imageOfExperience()) + remoteViews.setImageViewBitmap(R.id.ic_mp_header, HabiticaIconsHelper.imageOfMagic()) + + remoteViews.setProgressBar(R.id.hp_bar, stats.maxHealth ?: 0, currentHealth.toInt(), false) + remoteViews.setProgressBar(R.id.exp_bar, stats.toNextLevel ?: 0, stats.exp?.toInt() ?: 0, false) + remoteViews.setProgressBar(R.id.mp_bar, stats.maxMP ?: 0, stats.mp?.toInt() ?: 0, false) + remoteViews.setViewVisibility(R.id.mp_wrapper, if (showManaBar && (stats.habitClass == null || (stats.lvl ?: 0) < 10 || user.preferences?.disableClasses == true)) View.GONE else View.VISIBLE) + + remoteViews.setTextViewText(R.id.gold_tv, NumberAbbreviator.abbreviate(context, stats.gp ?: 0.0)) + remoteViews.setTextViewText(R.id.gems_tv, (user.balance * 4).toInt().toString()) + val hourGlassCount = user.hourglassCount + if (hourGlassCount == 0) { + remoteViews.setViewVisibility(R.id.hourglass_icon, View.GONE) + remoteViews.setViewVisibility(R.id.hourglasses_tv, View.GONE) + } else { + remoteViews.setImageViewBitmap(R.id.hourglass_icon, HabiticaIconsHelper.imageOfHourglass()) + remoteViews.setViewVisibility(R.id.hourglass_icon, View.VISIBLE) + remoteViews.setTextViewText(R.id.hourglasses_tv, hourGlassCount.toString()) + remoteViews.setViewVisibility(R.id.hourglasses_tv, View.VISIBLE) + } + remoteViews.setImageViewBitmap(R.id.gem_icon, HabiticaIconsHelper.imageOfGem()) + remoteViews.setImageViewBitmap(R.id.gold_icon, HabiticaIconsHelper.imageOfGold()) + remoteViews.setTextViewText(R.id.lvl_tv, context.getString(R.string.user_level, user.stats?.lvl ?: 0)) + + val avatarView = AvatarView(context, showBackground = true, showMount = true, showPet = true) + + avatarView.setAvatar(user) + val finalRemoteViews = remoteViews + avatarView.onAvatarImageReady(Consumer { bitmap -> + finalRemoteViews.setImageViewBitmap(R.id.avatar_view, bitmap) + appWidgetManager.partiallyUpdateAppWidget(allWidgetIds, finalRemoteViews) + }) + + //If user click on life and xp: open the app + val openAppIntent = Intent(context.applicationContext, MainActivity::class.java) + val openApp = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT) + remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp) + + + val options = appWidgetManager.getAppWidgetOptions(widgetId) + remoteViews = sizeRemoteViews(context, options, widgetId) + + appWidgetManager.updateAppWidget(widgetId, remoteViews) + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt index bbc3ebcfc..9194e713a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt @@ -19,6 +19,8 @@ abstract class BaseWidgetProvider : AppWidgetProvider() { @Inject lateinit var userRepository: UserRepository + var hasInjected = false + protected var context: Context? = null /** @@ -62,7 +64,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() { return configureRemoteViews(remoteViews, widgetId, columns, rows) } - protected fun showToastForTaskDirection(context: Context, data: TaskScoringResult?, userID: String) { + protected fun showToastForTaskDirection(context: Context, data: TaskScoringResult?) { if (data != null) { val pair = NotifyUserUseCase.getNotificationAndAddStatsToUserAsText(context, data.experienceDelta!!, data.healthDelta!!, data.goldDelta!!, data.manaDelta!!) val toast = Toast.makeText(context, pair.first, Toast.LENGTH_LONG) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListFactory.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListFactory.java deleted file mode 100644 index a80251dc3..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.content.Context; -import android.content.Intent; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.tasks.Task; - - -public class DailiesListFactory extends TaskListFactory { - public DailiesListFactory(Context context, Intent intent) { - super(context, intent, Task.TYPE_DAILY, R.layout.widget_dailies_list_row, R.id.dailies_text); - } -} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListFactory.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListFactory.kt new file mode 100644 index 000000000..94cbf168b --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesListFactory.kt @@ -0,0 +1,10 @@ +package com.habitrpg.android.habitica.widget + +import android.content.Context +import android.content.Intent + +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.models.tasks.Task + + +class DailiesListFactory(context: Context, intent: Intent) : TaskListFactory(context, intent, Task.TYPE_DAILY, R.layout.widget_dailies_list_row, R.id.dailies_text) \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java deleted file mode 100644 index 31567dd72..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.content.Context; - -import com.habitrpg.android.habitica.HabiticaApplication; -import com.habitrpg.android.habitica.HabiticaBaseApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.api.HostConfig; -import com.habitrpg.android.habitica.data.ApiClient; - -import java.util.Objects; - -import javax.inject.Inject; - -public class DailiesWidgetProvider extends TaskListWidgetProvider { - - 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 - ApiClient apiClient; - @Inject - HostConfig hostConfig; - - private void setUp(Context context) { - if (apiClient == null) { - Objects.requireNonNull(HabiticaBaseApplication.Companion.getUserComponent()).inject(this); - } - } - - @Override - protected Class getServiceClass() { - return DailiesWidgetService.class; - } - - @Override - protected Class getProviderClass() { - return DailiesWidgetProvider.class; - } - - @Override - protected int getTitleResId() { - return R.string.dailies; - } -} - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.kt new file mode 100644 index 000000000..98a992543 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetProvider.kt @@ -0,0 +1,13 @@ +package com.habitrpg.android.habitica.widget + +import com.habitrpg.android.habitica.R + +class DailiesWidgetProvider : TaskListWidgetProvider() { + override val serviceClass: Class<*> + get() = DailiesWidgetService::class.java + override val providerClass: Class<*> + get() = DailiesWidgetProvider::class.java + override val titleResId: Int + get() = R.string.dailies +} + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java deleted file mode 100644 index 1119d6201..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.content.Intent; -import android.widget.RemoteViewsService; - - -public class DailiesWidgetService extends RemoteViewsService { - - @Override - public RemoteViewsFactory onGetViewFactory(Intent intent) { - return new DailiesListFactory(this.getApplicationContext(), intent); - } -} - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.kt new file mode 100644 index 000000000..d0fa4fbab --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/DailiesWidgetService.kt @@ -0,0 +1,13 @@ +package com.habitrpg.android.habitica.widget + +import android.content.Intent +import android.widget.RemoteViewsService + + +class DailiesWidgetService : RemoteViewsService() { + + override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { + return DailiesListFactory(this.applicationContext, intent) + } +} + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetProvider.java deleted file mode 100644 index c71546a90..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetProvider.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.appwidget.AppWidgetManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.widget.RemoteViews; - -import com.habitrpg.android.habitica.HabiticaBaseApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.TaskRepository; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.responses.TaskDirection; -import com.habitrpg.android.habitica.modules.AppModule; - -import java.util.Objects; - -import javax.inject.Inject; -import javax.inject.Named; - -public class HabitButtonWidgetProvider extends BaseWidgetProvider { - - public static final String HABIT_ACTION = "com.habitrpg.android.habitica.HABIT_ACTION"; - public static final String TASK_ID = "com.habitrpg.android.habitica.TASK_ID_ITEM"; - public static final String TASK_DIRECTION = "com.habitrpg.android.habitica.TASK_DIRECTION"; - @Inject - public TaskRepository taskRepository; - @Inject - @Named(AppModule.NAMED_USER_ID) - public String userId; - - private void setUp() { - if (taskRepository == null) { - Objects.requireNonNull(HabiticaBaseApplication.Companion.getUserComponent()).inject(this); - } - } - - @Override - public int layoutResourceId() { - return R.layout.widget_habit_button; - } - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - super.onUpdate(context, appWidgetManager, appWidgetIds); - setUp(); - ComponentName thisWidget = new ComponentName(context, - HabitButtonWidgetProvider.class); - int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); - - for (int widgetId : allWidgetIds) { - Bundle options = appWidgetManager.getAppWidgetOptions(widgetId); - appWidgetManager.partiallyUpdateAppWidget(widgetId, - sizeRemoteViews(context, options, widgetId)); - } - - // Build the intent to call the service - Intent intent = new Intent(context.getApplicationContext(), HabitButtonWidgetService.class); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds); - - try { - context.startService(intent); - } catch (IllegalStateException ignore) { - //TODO: Make this play more nicely with Android 8 - } - } - - @Override - public void onReceive(Context context, Intent intent) { - setUp(); - if (intent.getAction().equals(HABIT_ACTION)) { - AppWidgetManager mgr = AppWidgetManager.getInstance(context); - int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); - String taskId = intent.getStringExtra(TASK_ID); - String direction = intent.getStringExtra(TASK_DIRECTION); - - int[] ids = {appWidgetId}; - - if (taskId != null) { - getUserRepository().getUser(userId).firstElement().flatMap(user -> taskRepository.taskChecked(user, taskId, TaskDirection.UP.getText().equals(direction), false, null)) - .subscribe(taskDirectionData -> showToastForTaskDirection(context, taskDirectionData, userId), RxErrorHandler.Companion.handleEmptyError(), () -> this.onUpdate(context, mgr, ids)); - } - } - super.onReceive(context, intent); - } - - @Override - public RemoteViews configureRemoteViews(RemoteViews remoteViews, int widgetId, int columns, int rows) { - return remoteViews; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetProvider.kt new file mode 100644 index 000000000..73c1a759d --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetProvider.kt @@ -0,0 +1,84 @@ +package com.habitrpg.android.habitica.widget + +import android.appwidget.AppWidgetManager +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.widget.RemoteViews +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.TaskRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.responses.TaskDirection +import io.reactivex.functions.Action +import io.reactivex.functions.Consumer +import javax.inject.Inject + +class HabitButtonWidgetProvider : BaseWidgetProvider() { + @Inject + lateinit var taskRepository: TaskRepository + + private fun setUp() { + if (!hasInjected) { + hasInjected = true + HabiticaBaseApplication.userComponent?.inject(this) + } + } + + override fun layoutResourceId(): Int { + return R.layout.widget_habit_button + } + + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { + super.onUpdate(context, appWidgetManager, appWidgetIds) + setUp() + val thisWidget = ComponentName(context, + HabitButtonWidgetProvider::class.java) + val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) + + for (widgetId in allWidgetIds) { + val options = appWidgetManager.getAppWidgetOptions(widgetId) + appWidgetManager.partiallyUpdateAppWidget(widgetId, + sizeRemoteViews(context, options, widgetId)) + } + + // Build the intent to call the service + val intent = Intent(context.applicationContext, HabitButtonWidgetService::class.java) + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds) + + try { + context.startService(intent) + } catch (ignore: IllegalStateException) { + } + } + + override fun onReceive(context: Context, intent: Intent) { + setUp() + if (intent.action == HABIT_ACTION) { + val mgr = AppWidgetManager.getInstance(context) + val appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID) + val taskId = intent.getStringExtra(TASK_ID) + val direction = intent.getStringExtra(TASK_DIRECTION) + + val ids = intArrayOf(appWidgetId) + + if (taskId != null) { + userRepository.getUser().firstElement().flatMap { user -> taskRepository.taskChecked(user, taskId, TaskDirection.UP.text == direction, false, null) } + .subscribe(Consumer { taskDirectionData -> showToastForTaskDirection(context, taskDirectionData) }, RxErrorHandler.handleEmptyError(), Action { this.onUpdate(context, mgr, ids) }) + } + } + super.onReceive(context, intent) + } + + override fun configureRemoteViews(remoteViews: RemoteViews, widgetId: Int, columns: Int, rows: Int): RemoteViews { + return remoteViews + } + + companion object { + + const val HABIT_ACTION = "com.habitrpg.android.habitica.HABIT_ACTION" + const val TASK_ID = "com.habitrpg.android.habitica.TASK_ID_ITEM" + const val TASK_DIRECTION = "com.habitrpg.android.habitica.TASK_DIRECTION" + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetService.java deleted file mode 100644 index 5591cdfcc..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetService.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.app.PendingIntent; -import android.app.Service; -import android.appwidget.AppWidgetManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.IBinder; -import androidx.core.content.ContextCompat; -import android.text.SpannableStringBuilder; -import android.text.style.DynamicDrawableSpan; -import android.view.View; -import android.widget.RemoteViews; - -import com.habitrpg.android.habitica.HabiticaBaseApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.TaskRepository; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.responses.TaskDirection; -import com.habitrpg.android.habitica.models.tasks.Task; -import com.habitrpg.android.habitica.modules.AppModule; -import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; - -import net.pherth.android.emoji_library.EmojiHandler; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import javax.inject.Inject; -import javax.inject.Named; - -public class HabitButtonWidgetService extends Service { - @Inject - @Named(AppModule.NAMED_USER_ID) - public String userId; - @Inject - public SharedPreferences sharedPreferences; - @Inject - public Resources resources; - @Inject - public Context context; - @Inject - TaskRepository taskRepository; - private AppWidgetManager appWidgetManager; - - private Map taskMapping; - private int[] allWidgetIds; - - @Override - public int onStartCommand(final Intent intent, int flags, int startId) { - Objects.requireNonNull(HabiticaBaseApplication.Companion.getUserComponent()).inject(this); - this.appWidgetManager = AppWidgetManager.getInstance(this); - ComponentName thisWidget = new ComponentName(this, HabitButtonWidgetProvider.class); - allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); - makeTaskMapping(); - - for (String taskid : this.taskMapping.keySet()) { - taskRepository.getUnmanagedTask(taskid).firstElement().subscribe(this::updateData, RxErrorHandler.Companion.handleEmptyError()); - } - - stopSelf(); - - return START_STICKY; - } - - private void updateData(Task task) { - RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.widget_habit_button); - if (task != null && task.isValid()) { - CharSequence parsedText = MarkdownParser.INSTANCE.parseMarkdown(task.getText()); - - SpannableStringBuilder builder = new SpannableStringBuilder(parsedText); - EmojiHandler.addEmojis(this.context, builder, 16, DynamicDrawableSpan.ALIGN_BASELINE, 16, 0, -1, false); - - remoteViews.setTextViewText(R.id.habit_title, builder); - - if (!task.getUp()) { - remoteViews.setViewVisibility(R.id.btnPlusWrapper, View.GONE); - remoteViews.setOnClickPendingIntent(R.id.btnPlusWrapper, null); - } else { - remoteViews.setViewVisibility(R.id.btnPlusWrapper, View.VISIBLE); - remoteViews.setInt(R.id.btnPlus, "setBackgroundColor", ContextCompat.getColor(context, task.getLightTaskColor())); - remoteViews.setOnClickPendingIntent(R.id.btnPlusWrapper, getPendingIntent(task.getId(), TaskDirection.UP.getText(), taskMapping.get(task.getId()))); - } - if (!task.getDown()) { - remoteViews.setViewVisibility(R.id.btnMinusWrapper, View.GONE); - remoteViews.setOnClickPendingIntent(R.id.btnMinusWrapper, null); - } else { - remoteViews.setViewVisibility(R.id.btnMinusWrapper, View.VISIBLE); - remoteViews.setInt(R.id.btnMinus, "setBackgroundColor", ContextCompat.getColor(context, task.getMediumTaskColor())); - remoteViews.setOnClickPendingIntent(R.id.btnMinusWrapper, getPendingIntent(task.getId(), TaskDirection.DOWN.getText(), taskMapping.get(task.getId()))); - } - if (taskMapping.get(task.getId()) != null && remoteViews != null) { - appWidgetManager.updateAppWidget(taskMapping.get(task.getId()), remoteViews); - } - } - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - private void makeTaskMapping() { - this.taskMapping = new HashMap<>(); - for (int widgetId : allWidgetIds) { - String taskId = getTaskId(widgetId); - if (!taskId.equals("")) { - this.taskMapping.put(taskId, widgetId); - } - } - } - - private String getTaskId(int widgetId) { - return sharedPreferences.getString("habit_button_widget_" + widgetId, ""); - } - - private PendingIntent getPendingIntent(String taskId, String direction, int widgetId) { - Intent taskIntent = new Intent(context, HabitButtonWidgetProvider.class); - taskIntent.setAction(HabitButtonWidgetProvider.HABIT_ACTION); - taskIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); - taskIntent.putExtra(HabitButtonWidgetProvider.TASK_ID, taskId); - taskIntent.putExtra(HabitButtonWidgetProvider.TASK_DIRECTION, direction); - return PendingIntent.getBroadcast(context, widgetId + direction.hashCode(), taskIntent, - PendingIntent.FLAG_UPDATE_CURRENT); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetService.kt new file mode 100644 index 000000000..f9a955d51 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/HabitButtonWidgetService.kt @@ -0,0 +1,115 @@ +package com.habitrpg.android.habitica.widget + +import android.app.PendingIntent +import android.app.Service +import android.appwidget.AppWidgetManager +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.os.IBinder +import android.text.SpannableStringBuilder +import android.text.style.DynamicDrawableSpan +import android.view.View +import android.widget.RemoteViews +import androidx.core.content.ContextCompat +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.TaskRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.responses.TaskDirection +import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.android.habitica.ui.helpers.MarkdownParser +import io.reactivex.functions.Consumer +import net.pherth.android.emoji_library.EmojiHandler +import java.util.* +import javax.inject.Inject + +class HabitButtonWidgetService : Service() { + @Inject + lateinit var sharedPreferences: SharedPreferences + @Inject + lateinit var context: Context + @Inject + lateinit var taskRepository: TaskRepository + private var appWidgetManager: AppWidgetManager? = null + + private var taskMapping = mutableMapOf() + private var allWidgetIds: IntArray? = null + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + HabiticaBaseApplication.userComponent?.inject(this) + this.appWidgetManager = AppWidgetManager.getInstance(this) + val thisWidget = ComponentName(this, HabitButtonWidgetProvider::class.java) + allWidgetIds = appWidgetManager?.getAppWidgetIds(thisWidget) + makeTaskMapping() + + for (taskid in this.taskMapping.keys) { + taskRepository.getUnmanagedTask(taskid).firstElement().subscribe(Consumer { this.updateData(it) }, RxErrorHandler.handleEmptyError()) + } + + stopSelf() + + return Service.START_STICKY + } + + private fun updateData(task: Task?) { + val remoteViews = RemoteViews(this.packageName, R.layout.widget_habit_button) + if (task != null && task.isValid) { + val parsedText = MarkdownParser.parseMarkdown(task.text) + + val builder = SpannableStringBuilder(parsedText) + EmojiHandler.addEmojis(this.context, builder, 16, DynamicDrawableSpan.ALIGN_BASELINE, 16, 0, -1, false) + + remoteViews.setTextViewText(R.id.habit_title, builder) + + if (task.up != true) { + remoteViews.setViewVisibility(R.id.btnPlusWrapper, View.GONE) + remoteViews.setOnClickPendingIntent(R.id.btnPlusWrapper, null) + } else { + remoteViews.setViewVisibility(R.id.btnPlusWrapper, View.VISIBLE) + remoteViews.setInt(R.id.btnPlus, "setBackgroundColor", ContextCompat.getColor(context, task.lightTaskColor)) + remoteViews.setOnClickPendingIntent(R.id.btnPlusWrapper, getPendingIntent(task.id, TaskDirection.UP.text, taskMapping[task.id]!!)) + } + if (task.down != true) { + remoteViews.setViewVisibility(R.id.btnMinusWrapper, View.GONE) + remoteViews.setOnClickPendingIntent(R.id.btnMinusWrapper, null) + } else { + remoteViews.setViewVisibility(R.id.btnMinusWrapper, View.VISIBLE) + remoteViews.setInt(R.id.btnMinus, "setBackgroundColor", ContextCompat.getColor(context, task.mediumTaskColor)) + remoteViews.setOnClickPendingIntent(R.id.btnMinusWrapper, getPendingIntent(task.id, TaskDirection.DOWN.text, taskMapping[task.id]!!)) + } + if (taskMapping[task.id] != null) { + appWidgetManager?.updateAppWidget(taskMapping[task.id]!!, remoteViews) + } + } + } + + override fun onBind(intent: Intent): IBinder? { + return null + } + + private fun makeTaskMapping() { + this.taskMapping = HashMap() + for (widgetId in allWidgetIds!!) { + val taskId = getTaskId(widgetId) + if (taskId != "") { + this.taskMapping[taskId] = widgetId + } + } + } + + private fun getTaskId(widgetId: Int): String { + return sharedPreferences.getString("habit_button_widget_$widgetId", "") ?: "" + } + + private fun getPendingIntent(taskId: String?, direction: String, widgetId: Int): PendingIntent { + val taskIntent = Intent(context, HabitButtonWidgetProvider::class.java) + taskIntent.action = HabitButtonWidgetProvider.HABIT_ACTION + taskIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId) + taskIntent.putExtra(HabitButtonWidgetProvider.TASK_ID, taskId) + taskIntent.putExtra(HabitButtonWidgetProvider.TASK_DIRECTION, direction) + return PendingIntent.getBroadcast(context, widgetId + direction.hashCode(), taskIntent, + PendingIntent.FLAG_UPDATE_CURRENT) + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.java deleted file mode 100644 index fd570c747..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.appwidget.AppWidgetManager; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.text.SpannableStringBuilder; -import android.text.style.DynamicDrawableSpan; -import android.widget.RemoteViews; -import android.widget.RemoteViewsService; - -import com.habitrpg.android.habitica.HabiticaApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.TaskRepository; -import com.habitrpg.android.habitica.data.UserRepository; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.tasks.Task; -import com.habitrpg.android.habitica.modules.AppModule; -import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; - -import net.pherth.android.emoji_library.EmojiHandler; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import javax.inject.Inject; -import javax.inject.Named; - -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; - -public abstract class TaskListFactory implements RemoteViewsService.RemoteViewsFactory { - private final int widgetId; - @Inject - @Named(AppModule.NAMED_USER_ID) - public String userID; - @Inject - TaskRepository taskRepository; - @Inject - UserRepository userRepository; - private int listItemResId; - private int listItemTextResId; - private String taskType; - private List taskList = new ArrayList<>(); - private Context context = null; - private boolean reloadData; - - TaskListFactory(Context context, Intent intent, String taskType, int listItemResId, int listItemTextResId) { - this.context = context; - this.widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); - this.listItemResId = listItemResId; - this.listItemTextResId = listItemTextResId; - this.reloadData = false; - this.taskType = taskType; - - if (userID == null) { - Objects.requireNonNull(HabiticaApplication.Companion.getUserComponent()).inject(this); - } - this.loadData(); - } - - private void loadData() { - Handler mainHandler = new Handler(context.getMainLooper()); - mainHandler.post(() -> taskRepository.getTasks(taskType, userID) - .firstElement() - .toObservable() - .flatMap(Observable::fromIterable) - .filter(task -> (task.getType().equals(Task.TYPE_TODO) && !task.getCompleted()) || task.isDisplayedActive()) - .toList() - .flatMapMaybe(tasks -> taskRepository.getTaskCopies(tasks).firstElement()) - .subscribeOn(AndroidSchedulers.mainThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(tasks -> { - reloadData = false; - taskList = tasks; - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(widgetId, R.id.list_view); - }, RxErrorHandler.Companion.handleEmptyError())); - - } - - - @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(), listItemResId); - if (taskList.size() > position) { - Task task = taskList.get(position); - - CharSequence parsedText = MarkdownParser.INSTANCE.parseMarkdown(task.getText()); - - SpannableStringBuilder builder = new SpannableStringBuilder(parsedText); - EmojiHandler.addEmojis(this.context, builder, 16, DynamicDrawableSpan.ALIGN_BASELINE, 16, 0, -1, false); - - remoteView.setTextViewText(listItemTextResId, 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.widget_list_row, fillInIntent); - } - return remoteView; - } - - @Override - public RemoteViews getLoadingView() { - return new RemoteViews(context.getPackageName(), listItemResId); - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public long getItemId(int position) { - if (taskList.size() > position) { - Task task = taskList.get(position); - return task.getId().hashCode(); - } - return position; - } - - @Override - public boolean hasStableIds() { - return true; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt new file mode 100644 index 000000000..b96e9aa93 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt @@ -0,0 +1,114 @@ +package com.habitrpg.android.habitica.widget + +import android.appwidget.AppWidgetManager +import android.content.Context +import android.content.Intent +import android.os.Handler +import android.text.SpannableStringBuilder +import android.text.style.DynamicDrawableSpan +import android.widget.RemoteViews +import android.widget.RemoteViewsService +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.TaskRepository +import com.habitrpg.android.habitica.data.UserRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.android.habitica.ui.helpers.MarkdownParser +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.functions.Consumer +import net.pherth.android.emoji_library.EmojiHandler +import java.util.* +import javax.inject.Inject + +abstract class TaskListFactory internal constructor(val context: Context, intent: Intent, private val taskType: String, private val listItemResId: Int, private val listItemTextResId: Int) : RemoteViewsService.RemoteViewsFactory { + private val widgetId: Int = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0) + @Inject + lateinit var taskRepository: TaskRepository + @Inject + lateinit var userRepository: UserRepository + private var taskList: List = ArrayList() + private var reloadData: Boolean = false + + init { + this.reloadData = false + } + + private fun loadData() { + val mainHandler = Handler(context.mainLooper) + mainHandler.post { + taskRepository.getCurrentUserTasks(taskType) + .firstElement() + .toObservable() + .flatMap { Observable.fromIterable(it) } + .filter { task -> task.type == Task.TYPE_TODO && !task.completed || task.isDisplayedActive } + .toList() + .flatMapMaybe { tasks -> taskRepository.getTaskCopies(tasks).firstElement() } + .subscribeOn(AndroidSchedulers.mainThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(Consumer { tasks -> + reloadData = false + taskList = tasks + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(widgetId, R.id.list_view) + }, RxErrorHandler.handleEmptyError()) + } + + } + + override fun onCreate() { + HabiticaBaseApplication.userComponent?.inject(this) + this.loadData() + } + override fun onDestroy() {} + + override fun onDataSetChanged() { + if (this.reloadData) { + this.loadData() + } + this.reloadData = true + } + + override fun getCount(): Int { + return taskList.size + } + + override fun getViewAt(position: Int): RemoteViews { + val remoteView = RemoteViews(context.packageName, listItemResId) + if (taskList.size > position) { + val task = taskList[position] + + val parsedText = MarkdownParser.parseMarkdown(task.text) + + val builder = SpannableStringBuilder(parsedText) + EmojiHandler.addEmojis(this.context, builder, 16, DynamicDrawableSpan.ALIGN_BASELINE, 16, 0, -1, false) + + remoteView.setTextViewText(listItemTextResId, builder) + remoteView.setInt(R.id.checkbox_background, "setBackgroundResource", task.lightTaskColor) + val fillInIntent = Intent() + fillInIntent.putExtra(TaskListWidgetProvider.TASK_ID_ITEM, task.id) + remoteView.setOnClickFillInIntent(R.id.widget_list_row, fillInIntent) + } + return remoteView + } + + override fun getLoadingView(): RemoteViews { + return RemoteViews(context.packageName, listItemResId) + } + + override fun getViewTypeCount(): Int { + return 1 + } + + override fun getItemId(position: Int): Long { + if (taskList.size > position) { + val task = taskList[position] + return task.id.hashCode().toLong() + } + return position.toLong() + } + + override fun hasStableIds(): Boolean { + return true + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java deleted file mode 100644 index 22035b267..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java +++ /dev/null @@ -1,125 +0,0 @@ -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.HabiticaBaseApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.ApiClient; -import com.habitrpg.android.habitica.data.TaskRepository; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.modules.AppModule; -import com.habitrpg.android.habitica.ui.activities.MainActivity; - -import java.util.Objects; - -import javax.inject.Inject; -import javax.inject.Named; - -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 - ApiClient apiClient; - @Inject - @Named(AppModule.NAMED_USER_ID) - String userId; - @Inject - TaskRepository taskRepository; - - private void setUp(Context context) { - if (apiClient == null) { - Objects.requireNonNull(HabiticaBaseApplication.Companion.getUserComponent()).inject(this); - } - } - - protected abstract Class getServiceClass(); - - protected abstract Class getProviderClass(); - - protected abstract int getTitleResId(); - - - @Override - public void onReceive(Context context, Intent intent) { - setUp(context); - if (intent.getAction().equals(DAILY_ACTION)) { - int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); - String taskId = intent.getStringExtra(TASK_ID_ITEM); - - if (taskId != null) { - getUserRepository().getUser(userId).firstElement().flatMap(user -> taskRepository.taskChecked(user, taskId, true, false, null)) - .subscribe(taskDirectionData -> { - taskRepository.markTaskCompleted(taskId, true); - showToastForTaskDirection(context, taskDirectionData, userId); - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); - }, RxErrorHandler.Companion.handleEmptyError()); - } - } - super.onReceive(context, intent); - } - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - super.onUpdate(context, appWidgetManager, appWidgetIds); - setUp(context); - ComponentName thisWidget = new ComponentName(context, getProviderClass()); - 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 appWidgetId : appWidgetIds) { - Intent intent = new Intent(context, getServiceClass()); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); - RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_task_list); - rv.setRemoteAdapter(appWidgetId, R.id.list_view, intent); - rv.setEmptyView(R.id.list_view, R.id.emptyView); - rv.setTextViewText(R.id.widget_title, context.getString(getTitleResId())); - - // if the user click on the title: open App - Intent openAppIntent = new Intent(context.getApplicationContext(), MainActivity.class); - PendingIntent openApp = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); - rv.setOnClickPendingIntent(R.id.widget_title, openApp); - - Intent taskIntent = new Intent(context, getProviderClass()); - taskIntent.setAction(DAILY_ACTION); - taskIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - 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(appWidgetId, rv); - - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); - } - - super.onUpdate(context, appWidgetManager, appWidgetIds); - } - - @Override - public int layoutResourceId() { - return R.layout.widget_task_list; - } - - @Override - public RemoteViews configureRemoteViews(RemoteViews remoteViews, int widgetId, int columns, int rows) { - return remoteViews; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.kt new file mode 100644 index 000000000..5cd7c9d9a --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.kt @@ -0,0 +1,108 @@ +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.widget.RemoteViews +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.TaskRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.ui.activities.MainActivity +import io.reactivex.functions.Consumer +import javax.inject.Inject + +abstract class TaskListWidgetProvider : BaseWidgetProvider() { + + @Inject + lateinit var taskRepository: TaskRepository + + protected abstract val serviceClass: Class<*> + + protected abstract val providerClass: Class<*> + + protected abstract val titleResId: Int + + private fun setUp() { + if (!hasInjected) { + hasInjected = true + HabiticaBaseApplication.userComponent?.inject(this) + } + } + + override fun onReceive(context: Context, intent: Intent) { + setUp() + if (intent.action == DAILY_ACTION) { + val appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID) + val taskId = intent.getStringExtra(TASK_ID_ITEM) + + if (taskId != null) { + userRepository.getUser().firstElement().flatMap { user -> taskRepository.taskChecked(user, taskId, up = true, force = false, notifyFunc = null) } + .subscribe(Consumer { taskDirectionData -> + showToastForTaskDirection(context, taskDirectionData) + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view) + }, RxErrorHandler.handleEmptyError()) + } + } + super.onReceive(context, intent) + } + + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { + super.onUpdate(context, appWidgetManager, appWidgetIds) + setUp() + val thisWidget = ComponentName(context, providerClass) + val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) + + for (widgetId in allWidgetIds) { + val options = appWidgetManager.getAppWidgetOptions(widgetId) + appWidgetManager.partiallyUpdateAppWidget(widgetId, + sizeRemoteViews(context, options, widgetId)) + } + + for (appWidgetId in appWidgetIds) { + val intent = Intent(context, serviceClass) + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) + intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)) + val rv = RemoteViews(context.packageName, R.layout.widget_task_list) + rv.setRemoteAdapter(R.id.list_view, intent) + rv.setEmptyView(R.id.list_view, R.id.emptyView) + rv.setTextViewText(R.id.widget_title, context.getString(titleResId)) + + // if the user click on the title: open App + val openAppIntent = Intent(context.applicationContext, MainActivity::class.java) + val openApp = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT) + rv.setOnClickPendingIntent(R.id.widget_title, openApp) + + val taskIntent = Intent(context, providerClass) + taskIntent.action = DAILY_ACTION + taskIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) + intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)) + val toastPendingIntent = PendingIntent.getBroadcast(context, 0, taskIntent, + PendingIntent.FLAG_UPDATE_CURRENT) + rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent) + + appWidgetManager.updateAppWidget(appWidgetId, rv) + + AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view) + } + + super.onUpdate(context, appWidgetManager, appWidgetIds) + } + + override fun layoutResourceId(): Int { + return R.layout.widget_task_list + } + + override fun configureRemoteViews(remoteViews: RemoteViews, widgetId: Int, columns: Int, rows: Int): RemoteViews { + return remoteViews + } + + companion object { + const val DAILY_ACTION = "com.habitrpg.android.habitica.DAILY_ACTION" + const val TASK_ID_ITEM = "com.habitrpg.android.habitica.TASK_ID_ITEM" + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListFactory.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListFactory.java deleted file mode 100644 index 7007606ad..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListFactory.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import android.content.Context; -import android.content.Intent; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.tasks.Task; - -public class TodoListFactory extends TaskListFactory { - public TodoListFactory(Context context, Intent intent) { - super(context, intent, Task.TYPE_TODO, R.layout.widget_todo_list_row, R.id.todo_text); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListFactory.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListFactory.kt new file mode 100644 index 000000000..951305de5 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListFactory.kt @@ -0,0 +1,9 @@ +package com.habitrpg.android.habitica.widget + +import android.content.Context +import android.content.Intent + +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.models.tasks.Task + +class TodoListFactory(context: Context, intent: Intent) : TaskListFactory(context, intent, Task.TYPE_TODO, R.layout.widget_todo_list_row, R.id.todo_text) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java deleted file mode 100644 index aafd4e9e6..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.habitrpg.android.habitica.widget; - -import com.habitrpg.android.habitica.R; - -public class TodoListWidgetProvider extends TaskListWidgetProvider { - - @Override - protected Class getServiceClass() { - return TodosWidgetService.class; - } - - @Override - protected Class getProviderClass() { - return TodoListWidgetProvider.class; - } - - @Override - protected int getTitleResId() { - return R.string.todos; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.kt new file mode 100644 index 000000000..59bec3e44 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodoListWidgetProvider.kt @@ -0,0 +1,14 @@ +package com.habitrpg.android.habitica.widget + +import com.habitrpg.android.habitica.R + +class TodoListWidgetProvider : TaskListWidgetProvider() { + override val serviceClass: Class<*> + get() = TodosWidgetService::class.java + + override val providerClass: Class<*> + get() = TodoListWidgetProvider::class.java + + override val titleResId: Int + get() = R.string.todos +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java deleted file mode 100644 index c15af4164..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.java +++ /dev/null @@ -1,12 +0,0 @@ -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 TodoListFactory(this.getApplicationContext(), intent); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.kt new file mode 100644 index 000000000..56c427fdc --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TodosWidgetService.kt @@ -0,0 +1,11 @@ +package com.habitrpg.android.habitica.widget + +import android.content.Intent +import android.widget.RemoteViewsService + +class TodosWidgetService : RemoteViewsService() { + + override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { + return TodoListFactory(this.applicationContext, intent) + } +} diff --git a/shared/build.gradle b/shared/build.gradle index 8d01d504e..3b55245a7 100644 --- a/shared/build.gradle +++ b/shared/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'kotlin-multiplatform' apply plugin: 'kotlin-kapt' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { minSdkVersion 21 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" }