diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bbe4c266b..922560e99 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -62,8 +62,14 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt
index 54b8152d8..4127264fa 100644
--- a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt
@@ -25,8 +25,10 @@ import org.koitharu.kotatsu.core.local.cookies.persistence.SharedPrefsCookiePers
import org.koitharu.kotatsu.core.parser.UserAgentInterceptor
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.domain.MangaLoaderContext
+import org.koitharu.kotatsu.domain.favourites.FavouritesRepository
import org.koitharu.kotatsu.ui.tracker.TrackerJobService
import org.koitharu.kotatsu.ui.utils.AppCrashHandler
+import org.koitharu.kotatsu.ui.widget.WidgetUpdater
import org.koitharu.kotatsu.utils.CacheUtils
import java.util.concurrent.TimeUnit
@@ -47,6 +49,8 @@ class KotatsuApp : Application() {
Thread.setDefaultUncaughtExceptionHandler(AppCrashHandler(applicationContext))
TrackerJobService.setup(this)
AppCompatDelegate.setDefaultNightMode(AppSettings(this).theme)
+ val widgetUpdater = WidgetUpdater(applicationContext)
+ FavouritesRepository.subscribe(widgetUpdater)
}
private fun initKoin() {
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt
index 1e91e3da3..ec9623306 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt
@@ -172,7 +172,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
companion object {
private const val EXTRA_MANGA = "manga"
- private const val EXTRA_MANGA_ID = "manga_id"
+ const val EXTRA_MANGA_ID = "manga_id"
const val ACTION_MANGA_VIEW = "${BuildConfig.APPLICATION_ID}.action.VIEW_MANGA"
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/WidgetUpdater.kt b/app/src/main/java/org/koitharu/kotatsu/ui/widget/WidgetUpdater.kt
new file mode 100644
index 000000000..fd398e734
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/widget/WidgetUpdater.kt
@@ -0,0 +1,21 @@
+package org.koitharu.kotatsu.ui.widget
+
+import android.appwidget.AppWidgetManager
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener
+import org.koitharu.kotatsu.ui.widget.shelf.ShelfWidgetProvider
+
+class WidgetUpdater(private val context: Context) : OnFavouritesChangeListener {
+
+ override fun onFavouritesChanged(mangaId: Long) {
+ val intent = Intent(context, ShelfWidgetProvider::class.java)
+ intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
+ val ids = AppWidgetManager.getInstance(context)
+ .getAppWidgetIds(ComponentName(context, ShelfWidgetProvider::class.java))
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
+ context.sendBroadcast(intent)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfListFactory.kt b/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfListFactory.kt
new file mode 100644
index 000000000..4f8cc74e1
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfListFactory.kt
@@ -0,0 +1,62 @@
+package org.koitharu.kotatsu.ui.widget.shelf
+
+import android.content.Context
+import android.content.Intent
+import android.widget.RemoteViews
+import android.widget.RemoteViewsService
+import androidx.core.graphics.drawable.toBitmap
+import coil.Coil
+import coil.api.get
+import kotlinx.coroutines.runBlocking
+import okio.IOException
+import org.koitharu.kotatsu.R
+import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.domain.favourites.FavouritesRepository
+import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
+
+class ShelfListFactory(context: Context, private val intent: Intent) : RemoteViewsService.RemoteViewsFactory {
+
+ private val packageName = context.packageName
+
+ private val dataSet = ArrayList()
+
+ override fun onCreate() {
+ }
+
+ override fun getLoadingView() = null
+
+ override fun getItemId(position: Int) = dataSet[position].id
+
+ override fun onDataSetChanged() {
+ dataSet.clear()
+ val data = runBlocking { FavouritesRepository().getAllManga(0) }
+ dataSet.addAll(data)
+ }
+
+ override fun hasStableIds() = true
+
+ override fun getViewAt(position: Int): RemoteViews {
+ val views = RemoteViews(packageName, R.layout.item_shelf)
+ val item = dataSet[position]
+ views.setTextViewText(R.id.textView_title, item.title)
+ try {
+ val cover = runBlocking {
+ Coil.loader().get(item.coverUrl).toBitmap()
+ }
+ views.setImageViewBitmap(R.id.imageView_cover, cover)
+ } catch (e: IOException) {
+ views.setImageViewResource(R.id.imageView_cover, R.drawable.ic_placeholder)
+ }
+ val intent = Intent()
+ intent.putExtra(MangaDetailsActivity.EXTRA_MANGA_ID, item.id)
+ views.setOnClickFillInIntent(R.id.rootLayout, intent)
+ return views
+ }
+
+ override fun getCount() = dataSet.size
+
+ override fun getViewTypeCount() = 1
+
+ override fun onDestroy() {
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetProvider.kt b/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetProvider.kt
new file mode 100644
index 000000000..d84dcd882
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetProvider.kt
@@ -0,0 +1,39 @@
+package org.koitharu.kotatsu.ui.widget.shelf
+
+import android.app.PendingIntent
+import android.appwidget.AppWidgetManager
+import android.appwidget.AppWidgetProvider
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.widget.RemoteViews
+import org.koitharu.kotatsu.R
+import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
+
+class ShelfWidgetProvider : AppWidgetProvider() {
+
+ override fun onUpdate(
+ context: Context,
+ appWidgetManager: AppWidgetManager,
+ appWidgetIds: IntArray
+ ) {
+ appWidgetIds.forEach { id ->
+ val views = RemoteViews(context.packageName, R.layout.widget_shelf)
+ val adapter = Intent(context, ShelfWidgetService::class.java)
+ adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
+ adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME))
+ views.setRemoteAdapter(R.id.gridView, adapter)
+ val intent = Intent(context, MangaDetailsActivity::class.java)
+ intent.action = MangaDetailsActivity.ACTION_MANGA_VIEW
+ views.setPendingIntentTemplate(R.id.gridView, PendingIntent.getActivity(
+ context,
+ 0,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT
+ ))
+ views.setEmptyView(R.id.gridView, R.id.textView_holder)
+ appWidgetManager.updateAppWidget(id, views)
+ }
+ appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.gridView)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetService.kt b/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetService.kt
new file mode 100644
index 000000000..8882c7f6b
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetService.kt
@@ -0,0 +1,11 @@
+package org.koitharu.kotatsu.ui.widget.shelf
+
+import android.content.Intent
+import android.widget.RemoteViewsService
+
+class ShelfWidgetService : RemoteViewsService() {
+
+ override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
+ return ShelfListFactory(this, intent)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-nodpi/ic_appwidget_shelf.png b/app/src/main/res/drawable-nodpi/ic_appwidget_shelf.png
new file mode 100644
index 000000000..de6a3094a
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/ic_appwidget_shelf.png differ
diff --git a/app/src/main/res/layout/item_shelf.xml b/app/src/main/res/layout/item_shelf.xml
new file mode 100644
index 000000000..e9d5575a9
--- /dev/null
+++ b/app/src/main/res/layout/item_shelf.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/widget_shelf.xml b/app/src/main/res/layout/widget_shelf.xml
new file mode 100644
index 000000000..0a5661fba
--- /dev/null
+++ b/app/src/main/res/layout/widget_shelf.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index d2e4aa52a..bb6e330ff 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -118,4 +118,5 @@
Загрузить
Читать с начала
Перезапустить
+ Полка с мангой
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3649b9f39..ac12e5bc0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -119,4 +119,5 @@
Download
Read from start
Restart
+ Manga shelf
\ No newline at end of file
diff --git a/app/src/main/res/xml/widget_shelf.xml b/app/src/main/res/xml/widget_shelf.xml
new file mode 100644
index 000000000..2dab58bf4
--- /dev/null
+++ b/app/src/main/res/xml/widget_shelf.xml
@@ -0,0 +1,12 @@
+
+
diff --git a/build.gradle b/build.gradle
index aebf163b7..30ef65d92 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ buildscript {
}
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.0-alpha04'
+ classpath 'com.android.tools.build:gradle:4.1.0-alpha05'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong