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