diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fdab5a4c..2cd54e87 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -79,6 +79,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ updateAppWidget(context, appWidgetManager, appWidgetId)
+ }
+ super.onUpdate(context, appWidgetManager, appWidgetIds)
+ }
+
+ override fun onDeleted(context: Context, appWidgetIds: IntArray) {
+ super.onDeleted(context, appWidgetIds)
+ }
+
+ override fun onEnabled(context: Context) {
+ super.onEnabled(context)
+ }
+
+ override fun onDisabled(context: Context) {
+ super.onDisabled(context)
+ }
+
+ companion object {
+ private fun downloadImageAsBitmap(imageUrl: String): Bitmap? {
+ var bitmap: Bitmap? = null
+
+ runBlocking(Dispatchers.IO) {
+ var inputStream: InputStream? = null
+ var urlConnection: HttpURLConnection? = null
+ try {
+ val url = URL(imageUrl)
+ urlConnection = url.openConnection() as HttpURLConnection
+ urlConnection.requestMethod = "GET"
+ urlConnection.connect()
+
+ if (urlConnection.responseCode == HttpURLConnection.HTTP_OK) {
+ inputStream = urlConnection.inputStream
+ bitmap = BitmapFactory.decodeStream(inputStream)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ } finally {
+ inputStream?.close()
+ urlConnection?.disconnect()
+ }
+ }
+ return bitmap?.let { BitmapUtil.roundCorners(it) }
+ }
+
+ @OptIn(DelicateCoroutinesApi::class)
+ fun updateAppWidget(
+ context: Context,
+ appWidgetManager: AppWidgetManager,
+ appWidgetId: Int
+ ) {
+
+ val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
+ val backgroundColor =
+ prefs.getInt(PREF_BACKGROUND_COLOR, Color.parseColor("#80000000"))
+ val backgroundFade = prefs.getInt(PREF_BACKGROUND_FADE, Color.parseColor("#00000000"))
+ val titleTextColor = prefs.getInt(PREF_TITLE_TEXT_COLOR, Color.WHITE)
+
+ val gradientDrawable = ResourcesCompat.getDrawable(
+ context.resources,
+ R.drawable.linear_gradient_black,
+ null
+ ) as GradientDrawable
+ gradientDrawable.colors = intArrayOf(backgroundColor, backgroundFade)
+ val widgetSizeProvider = WidgetSizeProvider(context)
+ var (width, height) = widgetSizeProvider.getWidgetsSize(appWidgetId)
+ if (width > 0 && height > 0) {
+ gradientDrawable.cornerRadius = 64f
+ } else {
+ width = 300
+ height = 300
+ }
+
+ launchIO {
+ val userPref = PrefManager.getVal(PrefName.AnilistUserId, "")
+ val userId = if (userPref.isNotEmpty()) userPref.toInt() else Anilist.userid
+ ?: if (Anilist.query.getUserData()) Anilist.userid else null
+ userId?.let {
+ val respond = Anilist.query.getUserProfile(it)
+ respond?.data?.user?.let { user ->
+ withContext(Dispatchers.Main) {
+ val views = RemoteViews(context.packageName, R.layout.statistics_widget).apply {
+ setImageViewBitmap(
+ R.id.backgroundView,
+ BitmapUtil.convertDrawableToBitmap(
+ gradientDrawable,
+ width,
+ height
+ )
+ )
+ setTextColor(R.id.topLeftItem, titleTextColor)
+ setTextColor(R.id.topLeftLabel, titleTextColor)
+ setTextColor(R.id.topRightItem, titleTextColor)
+ setTextColor(R.id.topRightLabel, titleTextColor)
+ setTextColor(R.id.bottomLeftItem, titleTextColor)
+ setTextColor(R.id.bottomLeftLabel, titleTextColor)
+ setTextColor(R.id.bottomRightItem, titleTextColor)
+ setTextColor(R.id.bottomRightLabel, titleTextColor)
+
+ setImageViewBitmap(
+ R.id.userAvatar,
+ user.avatar?.medium?.let { it1 -> downloadImageAsBitmap(it1) }
+ )
+ setTextViewText(
+ R.id.userLabel,
+ context.getString(R.string.user_stats, user.name)
+ )
+
+ setTextViewText(
+ R.id.topLeftItem,
+ user.statistics.anime.count.toString()
+ )
+ setTextViewText(
+ R.id.topLeftLabel,
+ context.getString(R.string.anime_watched)
+ )
+
+ setTextViewText(
+ R.id.topRightItem,
+ user.statistics.anime.episodesWatched.toString()
+ )
+ setTextViewText(
+ R.id.topRightLabel,
+ context.getString(R.string.episodes_watched)
+ )
+
+ setTextViewText(
+ R.id.bottomLeftItem,
+ user.statistics.manga.count.toString()
+ )
+ setTextViewText(
+ R.id.bottomLeftLabel,
+ context.getString(R.string.manga_read)
+ )
+
+ setTextViewText(
+ R.id.bottomRightItem,
+ user.statistics.manga.chaptersRead.toString()
+ )
+ setTextViewText(
+ R.id.bottomRightLabel,
+ context.getString(R.string.chapters_read)
+ )
+
+ val intent = Intent(context, ProfileActivity::class.java)
+ .putExtra("userId", it)
+ val pendingIntent = PendingIntent.getActivity(
+ context, 0, intent, PendingIntent.FLAG_IMMUTABLE
+ )
+ setOnClickPendingIntent(R.id.widgetContainer, pendingIntent)
+ }
+ // Instruct the widget manager to update the widget
+ appWidgetManager.updateAppWidget(appWidgetId, views)
+ }
+ } ?: showLoginCascade(context, appWidgetManager, appWidgetId)
+ } ?: showLoginCascade(context, appWidgetManager, appWidgetId)
+ }
+ }
+
+ private suspend fun showLoginCascade(
+ context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int
+ ) {
+
+ withContext(Dispatchers.Main) {
+ val views = RemoteViews(context.packageName, R.layout.statistics_widget)
+
+ views.setTextViewText(R.id.topLeftItem, "")
+ views.setTextViewText(
+ R.id.topLeftLabel,
+ context.getString(R.string.please)
+ )
+
+ views.setTextViewText(R.id.topRightItem, "")
+ views.setTextViewText(
+ R.id.topRightLabel,
+ context.getString(R.string.log_in)
+ )
+
+ views.setTextViewText(
+ R.id.bottomLeftItem,
+ context.getString(R.string.or_join)
+ )
+ views.setTextViewText(R.id.bottomLeftLabel, "")
+
+ views.setTextViewText(
+ R.id.bottomRightItem,
+ context.getString(R.string.anilist)
+ )
+ views.setTextViewText(R.id.bottomRightLabel, "")
+
+ val intent = Intent(context, MainActivity::class.java)
+ val pendingIntent = PendingIntent.getActivity(
+ context, 0, intent, PendingIntent.FLAG_IMMUTABLE
+ )
+ views.setOnClickPendingIntent(R.id.widgetContainer, pendingIntent)
+
+ appWidgetManager.updateAppWidget(appWidgetId, views)
+ }
+ }
+
+ const val PREFS_NAME = "ani.dantotsu.widgets.ResumableWidget"
+ const val PREF_BACKGROUND_COLOR = "background_color"
+ const val PREF_BACKGROUND_FADE = "background_fade"
+ const val PREF_TITLE_TEXT_COLOR = "title_text_color"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/app/src/main/res/drawable-nodpi/example_appwidget_preview.png
deleted file mode 100644
index 52c4ef28..00000000
Binary files a/app/src/main/res/drawable-nodpi/example_appwidget_preview.png and /dev/null differ
diff --git a/app/src/main/res/drawable-nodpi/statistics_widget_preview.png b/app/src/main/res/drawable-nodpi/statistics_widget_preview.png
new file mode 100644
index 00000000..85d3aaef
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/statistics_widget_preview.png differ
diff --git a/app/src/main/res/drawable-nodpi/upcoming_widget_preview.png b/app/src/main/res/drawable-nodpi/upcoming_widget_preview.png
new file mode 100644
index 00000000..fcfa6e7d
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/upcoming_widget_preview.png differ
diff --git a/app/src/main/res/drawable/ic_camera_roll_24.xml b/app/src/main/res/drawable/ic_camera_roll_24.xml
new file mode 100644
index 00000000..1c4b99e3
--- /dev/null
+++ b/app/src/main/res/drawable/ic_camera_roll_24.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/widget_stats_rounded.xml b/app/src/main/res/drawable/widget_stats_rounded.xml
new file mode 100644
index 00000000..c4fbc849
--- /dev/null
+++ b/app/src/main/res/drawable/widget_stats_rounded.xml
@@ -0,0 +1,27 @@
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/statistics_widget.xml b/app/src/main/res/layout/statistics_widget.xml
new file mode 100644
index 00000000..c043623c
--- /dev/null
+++ b/app/src/main/res/layout/statistics_widget.xml
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/statistics_widget_configure.xml b/app/src/main/res/layout/statistics_widget_configure.xml
new file mode 100644
index 00000000..0905d170
--- /dev/null
+++ b/app/src/main/res/layout/statistics_widget_configure.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 065f0e6b..f7e02089 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -9,6 +9,7 @@
@color/bg_black
#A8000000
#80000000
+ #80FFFFFF
#fff
#00BFAEAE
#ACACAC
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 989da759..9b694ebc 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -820,6 +820,17 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
donate :)
Do it!
Password
+
+ Track progress directly from your home screen
+ Anime Watched
+ Manga Read
+ Loading…
+ %1$s\'s Stats
+
+ Please
+ log in
+ or join
+
Top background color
Bottom Background Color
Countdown Text Color
diff --git a/app/src/main/res/xml-v31/statistics_widget_info.xml b/app/src/main/res/xml-v31/statistics_widget_info.xml
new file mode 100644
index 00000000..5ede252a
--- /dev/null
+++ b/app/src/main/res/xml-v31/statistics_widget_info.xml
@@ -0,0 +1,15 @@
+
+
diff --git a/app/src/main/res/xml-v31/upcoming_widget_info.xml b/app/src/main/res/xml-v31/upcoming_widget_info.xml
index e8376331..a7f86b35 100644
--- a/app/src/main/res/xml-v31/upcoming_widget_info.xml
+++ b/app/src/main/res/xml-v31/upcoming_widget_info.xml
@@ -6,7 +6,7 @@
android:initialLayout="@layout/upcoming_widget"
android:minWidth="160dp"
android:minHeight="80dp"
- android:previewImage="@drawable/example_appwidget_preview"
+ android:previewImage="@drawable/upcoming_widget_preview"
android:previewLayout="@layout/upcoming_widget"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="3600000"
diff --git a/app/src/main/res/xml/statistics_widget_info.xml b/app/src/main/res/xml/statistics_widget_info.xml
new file mode 100644
index 00000000..6dc9ec4b
--- /dev/null
+++ b/app/src/main/res/xml/statistics_widget_info.xml
@@ -0,0 +1,14 @@
+
+
diff --git a/app/src/main/res/xml/upcoming_widget_info.xml b/app/src/main/res/xml/upcoming_widget_info.xml
index e82356cc..e177f753 100644
--- a/app/src/main/res/xml/upcoming_widget_info.xml
+++ b/app/src/main/res/xml/upcoming_widget_info.xml
@@ -6,7 +6,7 @@
android:initialLayout="@layout/upcoming_widget"
android:minWidth="160dp"
android:minHeight="80dp"
- android:previewImage="@drawable/example_appwidget_preview"
+ android:previewImage="@drawable/upcoming_widget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="3600000"
android:widgetCategory="home_screen"/>
\ No newline at end of file