diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 141c6ce1..860252df 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -30,6 +30,14 @@
+
+
+
+
+
+
+
diff --git a/android/app/src/main/kotlin/fr/ziedelth/jais/HomeWidgetProvider.kt b/android/app/src/main/kotlin/fr/ziedelth/jais/HomeWidgetProvider.kt
new file mode 100644
index 00000000..8933717b
--- /dev/null
+++ b/android/app/src/main/kotlin/fr/ziedelth/jais/HomeWidgetProvider.kt
@@ -0,0 +1,66 @@
+package fr.ziedelth.jais
+
+import android.appwidget.AppWidgetManager
+import android.content.Context
+import android.content.SharedPreferences
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.view.View
+import android.widget.RemoteViews
+
+import es.antonborri.home_widget.HomeWidgetBackgroundIntent
+import es.antonborri.home_widget.HomeWidgetLaunchIntent
+import es.antonborri.home_widget.HomeWidgetProvider
+
+class HomeWidgetProvider : HomeWidgetProvider() {
+ override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) {
+ appWidgetIds.forEach { widgetId ->
+ val views = RemoteViews(context.packageName, R.layout.home_widget_layout).apply {
+ // Open App on Widget Click
+ val pendingIntent = HomeWidgetLaunchIntent.getActivity(
+ context,
+ MainActivity::class.java)
+ setOnClickPendingIntent(R.id.home_widget_container, pendingIntent)
+
+ // Show Images saved with `renderFlutterWidget`
+ val image1 = widgetData.getString("image0", null)
+
+ if (image1 != null) {
+ setImageViewBitmap(R.id.widget_img1, BitmapFactory.decodeFile(image1))
+ setViewVisibility(R.id.widget_img1, View.VISIBLE)
+ } else {
+ setViewVisibility(R.id.widget_img1, View.GONE)
+ }
+
+ val image2 = widgetData.getString("image1", null)
+
+ if (image2 != null) {
+ setImageViewBitmap(R.id.widget_img2, BitmapFactory.decodeFile(image2))
+ setViewVisibility(R.id.widget_img2, View.VISIBLE)
+ } else {
+ setViewVisibility(R.id.widget_img2, View.GONE)
+ }
+
+ val image3 = widgetData.getString("image2", null)
+
+ if (image3 != null) {
+ setImageViewBitmap(R.id.widget_img3, BitmapFactory.decodeFile(image3))
+ setViewVisibility(R.id.widget_img3, View.VISIBLE)
+ } else {
+ setViewVisibility(R.id.widget_img3, View.GONE)
+ }
+
+ val image4 = widgetData.getString("image3", null)
+
+ if (image4 != null) {
+ setImageViewBitmap(R.id.widget_img4, BitmapFactory.decodeFile(image4))
+ setViewVisibility(R.id.widget_img4, View.VISIBLE)
+ } else {
+ setViewVisibility(R.id.widget_img4, View.GONE)
+ }
+ }
+
+ appWidgetManager.updateAppWidget(widgetId, views)
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/home_widget_background.xml b/android/app/src/main/res/drawable/home_widget_background.xml
new file mode 100644
index 00000000..ca954faa
--- /dev/null
+++ b/android/app/src/main/res/drawable/home_widget_background.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/layout/home_widget_layout.xml b/android/app/src/main/res/layout/home_widget_layout.xml
new file mode 100644
index 00000000..bc12f2d5
--- /dev/null
+++ b/android/app/src/main/res/layout/home_widget_layout.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/xml/home_widget_provider.xml b/android/app/src/main/res/xml/home_widget_provider.xml
new file mode 100644
index 00000000..503011d8
--- /dev/null
+++ b/android/app/src/main/res/xml/home_widget_provider.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/lib/controllers/episode_tab_controller.dart b/lib/controllers/episode_tab_controller.dart
index 43dff544..2ee204fe 100644
--- a/lib/controllers/episode_tab_controller.dart
+++ b/lib/controllers/episode_tab_controller.dart
@@ -1,6 +1,12 @@
import 'package:flutter/material.dart';
+import 'package:home_widget/home_widget.dart';
import 'package:jais/controllers/animes/missing_anime_controller.dart';
import 'package:jais/controllers/episodes/episode_controller.dart';
+import 'package:jais/controllers/logger.dart';
+import 'package:jais/models/anime.dart';
+import 'package:jais/utils.dart';
+import 'package:jais/widgets/animes/anime_image.dart';
+import 'package:jais/widgets/animes/missing_anime_widget.dart';
class EpisodeTabController with ChangeNotifier {
late MissingAnimeController missingAnimeController;
@@ -17,8 +23,57 @@ class EpisodeTabController with ChangeNotifier {
episodeController.reset();
notify();
- missingAnimeController.load().whenComplete(() => notify());
- episodeController.load().whenComplete(() => notify());
+ missingAnimeController.load().whenComplete(() async {
+ notify();
+
+ try {
+ final List animeImages = [];
+
+ for (int i = 0; i < 4; i++) {
+ final MissingAnimeWidget? missingAnimeWidget =
+ missingAnimeController.list.elementAtOrNull(i)
+ as MissingAnimeWidget?;
+
+ if (missingAnimeWidget == null) {
+ break;
+ }
+
+ final Anime anime = missingAnimeWidget.missingAnime.anime;
+
+ animeImages.add(AnimeImage(
+ anime: anime,
+ width: Const.missingAnimeImageWith,
+ height: Const.missingAnimeImageHeight,
+ radius: 360,
+ ));
+ }
+
+ await Future.delayed(const Duration(seconds: 3));
+ info('EpisodeTabController', 'updateHomeWidget()');
+
+ // await HomeWidget.renderFlutterWidget(
+ // animeImage,
+ // logicalSize: const Size(Const.missingAnimeImageWith, Const.missingAnimeImageHeight),
+ // key: 'dashIcon',
+ // );
+
+ await Future.wait([
+ for (final AnimeImage image in animeImages)
+ HomeWidget.renderFlutterWidget(
+ image,
+ logicalSize: const Size(
+ Const.missingAnimeImageWith, Const.missingAnimeImageHeight),
+ key: 'image${animeImages.indexOf(image)}',
+ ),
+ ]);
+
+ await HomeWidget.updateWidget(name: 'HomeWidgetProvider');
+ } catch (exception, stackTrace) {
+ error('EpisodeTabController', '$exception', exception, stackTrace);
+ }
+ });
+
+ episodeController.load().whenComplete(notify);
}
void notify() {
diff --git a/lib/main.dart b/lib/main.dart
index a3a757b8..91987da4 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import 'package:home_widget/home_widget.dart';
import 'package:jais/controllers/animes/anime_detail_controller.dart';
import 'package:jais/controllers/animes/anime_diary_controller.dart';
import 'package:jais/controllers/animes/anime_search_controller.dart';
@@ -24,11 +25,22 @@ Future main() async {
);
}
-class MyApp extends StatelessWidget {
+class MyApp extends StatefulWidget {
+ const MyApp({super.key});
+
+ @override
+ State createState() => _MyAppState();
+}
+
+class _MyAppState extends State {
static const Color _mainWhiteThemeColor = Color(0xFFa32d26);
static const Color _mainDarkThemeColor = Color(0xFFfde5c9);
- const MyApp({super.key});
+ @override
+ void initState() {
+ super.initState();
+ HomeWidget.setAppGroupId('jais');
+ }
@override
Widget build(BuildContext context) {
diff --git a/pubspec.lock b/pubspec.lock
index 40eade60..104aaf03 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -384,6 +384,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
+ home_widget:
+ dependency: "direct main"
+ description:
+ name: home_widget
+ sha256: "9a0ed6094823b07025727a39d3dc2d3e02c5281372af22d72e611137e0b3c10d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.0"
html:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index a7c7c08b..ae054d42 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -14,6 +14,7 @@ dependencies:
firebase_messaging: ^14.6.5
flutter:
sdk: flutter
+ home_widget: ^0.3.0
http: ^1.1.0
intl: ^0.18.1
json_annotation: ^4.8.1