Update suggestions after config changes #831
This commit is contained in:
@@ -20,7 +20,7 @@ class CaptchaNotifier(
|
|||||||
) : EventListener {
|
) : EventListener {
|
||||||
|
|
||||||
fun notify(exception: CloudFlareProtectedException) {
|
fun notify(exception: CloudFlareProtectedException) {
|
||||||
if (!context.checkNotificationPermission()) {
|
if (!context.checkNotificationPermission(CHANNEL_ID)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val manager = NotificationManagerCompat.from(context)
|
val manager = NotificationManagerCompat.from(context)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import android.content.ContextWrapper
|
|||||||
import android.content.OperationApplicationException
|
import android.content.OperationApplicationException
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.SyncResult
|
import android.content.SyncResult
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||||
import android.content.pm.ResolveInfo
|
import android.content.pm.ResolveInfo
|
||||||
import android.database.SQLException
|
import android.database.SQLException
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
@@ -216,10 +216,19 @@ fun Context.findActivity(): Activity? = when (this) {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.checkNotificationPermission(): Boolean = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
fun Context.checkNotificationPermission(channelId: String?): Boolean {
|
||||||
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
val hasPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
} else {
|
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PERMISSION_GRANTED
|
||||||
NotificationManagerCompat.from(this).areNotificationsEnabled()
|
} else {
|
||||||
|
NotificationManagerCompat.from(this).areNotificationsEnabled()
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasPermission && channelId != null) {
|
||||||
|
val channel = NotificationManagerCompat.from(this).getNotificationChannel(channelId)
|
||||||
|
if (channel != null && channel.importance == NotificationManagerCompat.IMPORTANCE_NONE) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasPermission
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class ImportWorker @AssistedInject constructor(
|
|||||||
val result = runCatchingCancellable {
|
val result = runCatchingCancellable {
|
||||||
importer.import(uri).manga
|
importer.import(uri).manga
|
||||||
}
|
}
|
||||||
if (applicationContext.checkNotificationPermission()) {
|
if (applicationContext.checkNotificationPermission(CHANNEL_ID)) {
|
||||||
val notification = buildNotification(result)
|
val notification = buildNotification(result)
|
||||||
notificationManager.notify(uri.hashCode(), notification)
|
notificationManager.notify(uri.hashCode(), notification)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.content.SharedPreferences
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
@@ -15,8 +16,7 @@ import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SuggestionsSettingsFragment :
|
class SuggestionsSettingsFragment : BasePreferenceFragment(R.string.suggestions),
|
||||||
BasePreferenceFragment(R.string.suggestions),
|
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -48,16 +48,17 @@ class SuggestionsSettingsFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
if (key == AppSettings.KEY_SUGGESTIONS && settings.isSuggestionsEnabled) {
|
if (settings.isSuggestionsEnabled && (key == AppSettings.KEY_SUGGESTIONS
|
||||||
onSuggestionsEnabled()
|
|| key == AppSettings.KEY_SUGGESTIONS_EXCLUDE_TAGS
|
||||||
|
|| key == AppSettings.KEY_SUGGESTIONS_EXCLUDE_NSFW)
|
||||||
|
) {
|
||||||
|
updateSuggestions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSuggestionsEnabled() {
|
private fun updateSuggestions() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch(Dispatchers.Default) {
|
||||||
if (repository.isEmpty()) {
|
suggestionsScheduler.startNow()
|
||||||
suggestionsScheduler.startNow()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ class SuggestionsViewModel @Inject constructor(
|
|||||||
override fun onRetry() = Unit
|
override fun onRetry() = Unit
|
||||||
|
|
||||||
fun updateSuggestions() {
|
fun updateSuggestions() {
|
||||||
suggestionsScheduler.startNow()
|
launchJob(Dispatchers.Default) {
|
||||||
|
suggestionsScheduler.startNow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package org.koitharu.kotatsu.suggestions.ui
|
package org.koitharu.kotatsu.suggestions.ui
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.Manifest
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ServiceInfo
|
import android.content.pm.ServiceInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.FloatRange
|
import androidx.annotation.FloatRange
|
||||||
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.core.app.NotificationChannelCompat
|
import androidx.core.app.NotificationChannelCompat
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
@@ -50,6 +51,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
|
|||||||
import org.koitharu.kotatsu.core.util.ext.almostEquals
|
import org.koitharu.kotatsu.core.util.ext.almostEquals
|
||||||
import org.koitharu.kotatsu.core.util.ext.asArrayList
|
import org.koitharu.kotatsu.core.util.ext.asArrayList
|
||||||
import org.koitharu.kotatsu.core.util.ext.awaitUniqueWorkInfoByName
|
import org.koitharu.kotatsu.core.util.ext.awaitUniqueWorkInfoByName
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.awaitWorkInfosByTag
|
||||||
import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
|
import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
|
||||||
import org.koitharu.kotatsu.core.util.ext.flatten
|
import org.koitharu.kotatsu.core.util.ext.flatten
|
||||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||||
@@ -189,7 +191,9 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
.sortedBy { it.relevance }
|
.sortedBy { it.relevance }
|
||||||
.take(MAX_RESULTS)
|
.take(MAX_RESULTS)
|
||||||
suggestionRepository.replace(suggestions)
|
suggestionRepository.replace(suggestions)
|
||||||
if (appSettings.isSuggestionsNotificationAvailable && applicationContext.checkNotificationPermission()) {
|
if (appSettings.isSuggestionsNotificationAvailable
|
||||||
|
&& applicationContext.checkNotificationPermission(MANGA_CHANNEL_ID)
|
||||||
|
) {
|
||||||
for (i in 0..3) {
|
for (i in 0..3) {
|
||||||
try {
|
try {
|
||||||
val manga = suggestions[Random.nextInt(0, suggestions.size / 3)]
|
val manga = suggestions[Random.nextInt(0, suggestions.size / 3)]
|
||||||
@@ -252,7 +256,7 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
e.printStackTraceDebug()
|
e.printStackTraceDebug()
|
||||||
}.getOrDefault(emptyList())
|
}.getOrDefault(emptyList())
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@RequiresPermission(Manifest.permission.POST_NOTIFICATIONS)
|
||||||
private suspend fun showNotification(manga: Manga) {
|
private suspend fun showNotification(manga: Manga) {
|
||||||
val channel = NotificationChannelCompat.Builder(MANGA_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_DEFAULT)
|
val channel = NotificationChannelCompat.Builder(MANGA_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_DEFAULT)
|
||||||
.setName(applicationContext.getString(R.string.suggestions))
|
.setName(applicationContext.getString(R.string.suggestions))
|
||||||
@@ -393,7 +397,10 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
.any { !it.state.isFinished }
|
.any { !it.state.isFinished }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startNow() {
|
suspend fun startNow() {
|
||||||
|
if (workManager.awaitWorkInfosByTag(TAG_ONESHOT).any { !it.state.isFinished }) {
|
||||||
|
return
|
||||||
|
}
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
.build()
|
.build()
|
||||||
@@ -402,7 +409,7 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
.addTag(TAG_ONESHOT)
|
.addTag(TAG_ONESHOT)
|
||||||
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||||
.build()
|
.build()
|
||||||
workManager.enqueue(request)
|
workManager.enqueue(request).await()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createConstraints() = Constraints.Builder()
|
private fun createConstraints() = Constraints.Builder()
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.onEachIndexed { index, it ->
|
}.onEachIndexed { index, it ->
|
||||||
if (applicationContext.checkNotificationPermission()) {
|
if (applicationContext.checkNotificationPermission(WORKER_CHANNEL_ID)) {
|
||||||
notificationManager.notify(WORKER_NOTIFICATION_ID, createWorkerNotification(tracks.size, index + 1))
|
notificationManager.notify(WORKER_NOTIFICATION_ID, createWorkerNotification(tracks.size, index + 1))
|
||||||
}
|
}
|
||||||
when (it) {
|
when (it) {
|
||||||
@@ -197,7 +197,7 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
channelId: String?,
|
channelId: String?,
|
||||||
newChapters: List<MangaChapter>,
|
newChapters: List<MangaChapter>,
|
||||||
) {
|
) {
|
||||||
if (newChapters.isEmpty() || channelId == null || !applicationContext.checkNotificationPermission()) {
|
if (newChapters.isEmpty() || channelId == null || !applicationContext.checkNotificationPermission(channelId)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val id = manga.url.hashCode()
|
val id = manga.url.hashCode()
|
||||||
|
|||||||
Reference in New Issue
Block a user