feat: view subscriptions in settings
This commit is contained in:
parent
f1d16ba16a
commit
6c1176a182
14 changed files with 221 additions and 15 deletions
|
@ -143,6 +143,8 @@ data class FileUrl(
|
|||
operator fun get(url: String?, headers: Map<String, String> = mapOf()): FileUrl? {
|
||||
return FileUrl(url ?: return null, headers)
|
||||
}
|
||||
|
||||
private const val serialVersionUID = 1L
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -294,6 +294,7 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
|
|||
val tDownloads = downloadManager.animeDownloadedTypes.filter { it.titleName.findValidName() == title }
|
||||
val download = tDownloads.firstOrNull() ?: continue
|
||||
val offlineAnimeModel = loadOfflineAnimeModel(download)
|
||||
if (offlineAnimeModel.title == "unknown") offlineAnimeModel.title = title
|
||||
newAnimeDownloads += offlineAnimeModel
|
||||
}
|
||||
downloads = newAnimeDownloads
|
||||
|
|
|
@ -3,7 +3,7 @@ package ani.dantotsu.download.anime
|
|||
import android.net.Uri
|
||||
|
||||
data class OfflineAnimeModel(
|
||||
val title: String,
|
||||
var title: String,
|
||||
val score: String,
|
||||
val totalEpisode: String,
|
||||
val totalEpisodeList: String,
|
||||
|
|
|
@ -5,14 +5,18 @@ import ani.dantotsu.currContext
|
|||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaNameAdapter
|
||||
import ani.dantotsu.media.Selected
|
||||
import ani.dantotsu.media.emptyMedia
|
||||
import ani.dantotsu.parsers.AnimeParser
|
||||
import ani.dantotsu.parsers.AnimeSources
|
||||
import ani.dantotsu.parsers.BaseParser
|
||||
import ani.dantotsu.parsers.Episode
|
||||
import ani.dantotsu.parsers.MangaChapter
|
||||
import ani.dantotsu.parsers.MangaParser
|
||||
import ani.dantotsu.parsers.MangaSources
|
||||
import ani.dantotsu.parsers.ShowResponse
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.toast
|
||||
import ani.dantotsu.tryWithSuspend
|
||||
import ani.dantotsu.util.Logger
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
|
@ -50,16 +54,18 @@ class SubscriptionHelper {
|
|||
|
||||
suspend fun getEpisode(
|
||||
parser: AnimeParser,
|
||||
id: Int
|
||||
subscribeMedia: SubscribeMedia
|
||||
): Episode? {
|
||||
|
||||
val selected = loadSelected(id)
|
||||
val selected = loadSelected(subscribeMedia.id)
|
||||
val ep = withTimeoutOrNull(10 * 1000) {
|
||||
tryWithSuspend {
|
||||
val show = parser.loadSavedShowResponse(id) ?: throw Exception(
|
||||
val show = parser.loadSavedShowResponse(subscribeMedia.id)
|
||||
?: forceLoadShowResponse(subscribeMedia, selected, parser)
|
||||
?: throw Exception(
|
||||
currContext()?.getString(
|
||||
R.string.failed_to_load_data,
|
||||
id
|
||||
subscribeMedia.id
|
||||
)
|
||||
)
|
||||
show.sAnime?.let {
|
||||
|
@ -73,7 +79,7 @@ class SubscriptionHelper {
|
|||
|
||||
return ep?.apply {
|
||||
selected.latest = number.toFloat()
|
||||
saveSelected(id, selected)
|
||||
saveSelected(subscribeMedia.id, selected)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,15 +95,17 @@ class SubscriptionHelper {
|
|||
|
||||
suspend fun getChapter(
|
||||
parser: MangaParser,
|
||||
id: Int
|
||||
subscribeMedia: SubscribeMedia
|
||||
): MangaChapter? {
|
||||
val selected = loadSelected(id)
|
||||
val selected = loadSelected(subscribeMedia.id)
|
||||
val chp = withTimeoutOrNull(10 * 1000) {
|
||||
tryWithSuspend {
|
||||
val show = parser.loadSavedShowResponse(id) ?: throw Exception(
|
||||
val show = parser.loadSavedShowResponse(subscribeMedia.id)
|
||||
?: forceLoadShowResponse(subscribeMedia, selected, parser)
|
||||
?: throw Exception(
|
||||
currContext()?.getString(
|
||||
R.string.failed_to_load_data,
|
||||
id
|
||||
subscribeMedia.id
|
||||
)
|
||||
)
|
||||
show.sManga?.let {
|
||||
|
@ -111,10 +119,28 @@ class SubscriptionHelper {
|
|||
|
||||
return chp?.apply {
|
||||
selected.latest = MediaNameAdapter.findChapterNumber(number) ?: 0f
|
||||
saveSelected(id, selected)
|
||||
saveSelected(subscribeMedia.id, selected)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun forceLoadShowResponse(subscribeMedia: SubscribeMedia, selected: Selected, parser: BaseParser): ShowResponse? {
|
||||
val tempMedia = Media(
|
||||
id = subscribeMedia.id,
|
||||
name = null,
|
||||
nameRomaji = subscribeMedia.name,
|
||||
userPreferredName = subscribeMedia.name,
|
||||
isAdult = subscribeMedia.isAdult,
|
||||
isFav = false,
|
||||
isListPrivate = false,
|
||||
userScore = 0,
|
||||
userRepeat = 0,
|
||||
format = null,
|
||||
selected = selected
|
||||
)
|
||||
parser.autoSearch(tempMedia)
|
||||
return parser.loadSavedShowResponse(subscribeMedia.id)
|
||||
}
|
||||
|
||||
data class SubscribeMedia(
|
||||
val isAnime: Boolean,
|
||||
val isAdult: Boolean,
|
||||
|
@ -134,6 +160,19 @@ class SubscriptionHelper {
|
|||
) as? Map<Int, SubscribeMedia>)
|
||||
?: mapOf<Int, SubscribeMedia>().also { PrefManager.setCustomVal(SUBSCRIPTIONS, it) }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun deleteSubscription(id: Int, showSnack: Boolean = false) {
|
||||
val data = PrefManager.getNullableCustomVal(
|
||||
SUBSCRIPTIONS,
|
||||
null,
|
||||
Map::class.java
|
||||
) as? MutableMap<Int, SubscribeMedia>
|
||||
?: mutableMapOf()
|
||||
data.remove(id)
|
||||
PrefManager.setCustomVal(SUBSCRIPTIONS, data)
|
||||
if (showSnack) toast(R.string.subscription_deleted)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun saveSubscription(media: Media, subscribed: Boolean) {
|
||||
val data = PrefManager.getNullableCustomVal(
|
||||
|
|
|
@ -98,7 +98,7 @@ class SubscriptionNotificationTask : Task {
|
|||
val ep: Episode? =
|
||||
SubscriptionHelper.getEpisode(
|
||||
parser,
|
||||
media.id
|
||||
media
|
||||
)
|
||||
if (ep != null) context.getString(R.string.episode) + "${ep.number}${
|
||||
if (ep.title != null) " : ${ep.title}" else ""
|
||||
|
@ -113,7 +113,7 @@ class SubscriptionNotificationTask : Task {
|
|||
val ep: MangaChapter? =
|
||||
SubscriptionHelper.getChapter(
|
||||
parser,
|
||||
media.id
|
||||
media
|
||||
)
|
||||
if (ep != null) ep.number + " " + context.getString(R.string.just_released) to null
|
||||
else null
|
||||
|
|
|
@ -18,6 +18,7 @@ import ani.dantotsu.navBarHeight
|
|||
import ani.dantotsu.notifications.TaskScheduler
|
||||
import ani.dantotsu.notifications.anilist.AnilistNotificationWorker
|
||||
import ani.dantotsu.notifications.comment.CommentNotificationWorker
|
||||
import ani.dantotsu.notifications.subscription.SubscriptionHelper
|
||||
import ani.dantotsu.notifications.subscription.SubscriptionNotificationWorker
|
||||
import ani.dantotsu.openSettings
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
|
@ -102,6 +103,19 @@ class SettingsNotificationActivity : AppCompatActivity() {
|
|||
).scheduleAllTasks(context)
|
||||
}
|
||||
),
|
||||
Settings(
|
||||
type = 1,
|
||||
name = getString(R.string.view_subscriptions),
|
||||
desc = getString(R.string.view_subscriptions_desc),
|
||||
icon = R.drawable.ic_round_search_24,
|
||||
onClick = {
|
||||
val subscriptions = SubscriptionHelper.getSubscriptions()
|
||||
SubscriptionsBottomDialog.newInstance(subscriptions).show(
|
||||
supportFragmentManager,
|
||||
"subscriptions"
|
||||
)
|
||||
}
|
||||
),
|
||||
Settings(
|
||||
type = 1,
|
||||
name = getString(R.string.anilist_notification_filters),
|
||||
|
|
52
app/src/main/java/ani/dantotsu/settings/SubscriptionItem.kt
Normal file
52
app/src/main/java/ani/dantotsu/settings/SubscriptionItem.kt
Normal file
|
@ -0,0 +1,52 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import android.content.Intent
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ItemSubscriptionBinding
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.notifications.subscription.SubscriptionHelper
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import com.xwray.groupie.Item
|
||||
import com.xwray.groupie.viewbinding.BindableItem
|
||||
|
||||
class SubscriptionItem(
|
||||
val id: Int,
|
||||
private val media: SubscriptionHelper.Companion.SubscribeMedia,
|
||||
private val adapter: GroupieAdapter
|
||||
) : BindableItem<ItemSubscriptionBinding>() {
|
||||
private lateinit var binding: ItemSubscriptionBinding
|
||||
override fun bind(p0: ItemSubscriptionBinding, p1: Int) {
|
||||
val context = p0.root.context
|
||||
binding = p0
|
||||
val parserName = if (media.isAnime)
|
||||
SubscriptionHelper.getAnimeParser(media.id).name
|
||||
else
|
||||
SubscriptionHelper.getMangaParser(media.id).name
|
||||
val mediaName = media.name
|
||||
val showName = "$mediaName - $parserName"
|
||||
binding.subscriptionName.text = showName
|
||||
binding.root.setOnClickListener {
|
||||
ContextCompat.startActivity(
|
||||
context,
|
||||
Intent(context, MediaDetailsActivity::class.java).putExtra(
|
||||
"mediaId", media.id
|
||||
),
|
||||
null
|
||||
)
|
||||
}
|
||||
binding.deleteSubscription.setOnClickListener {
|
||||
SubscriptionHelper.deleteSubscription(id, true)
|
||||
adapter.remove(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayout(): Int {
|
||||
return R.layout.item_subscription
|
||||
}
|
||||
|
||||
override fun initializeViewBinding(p0: View): ItemSubscriptionBinding {
|
||||
return ItemSubscriptionBinding.bind(p0)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.BottomSheetDialogFragment
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.BottomSheetRecyclerBinding
|
||||
import ani.dantotsu.notifications.subscription.SubscriptionHelper
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
|
||||
class SubscriptionsBottomDialog : BottomSheetDialogFragment() {
|
||||
private var _binding: BottomSheetRecyclerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var subscriptions: Map<Int, SubscriptionHelper.Companion.SubscribeMedia> = mapOf()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = BottomSheetRecyclerBinding.inflate(inflater, container, false)
|
||||
return _binding?.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.repliesRecyclerView.adapter = adapter
|
||||
binding.repliesRecyclerView.layoutManager = LinearLayoutManager(
|
||||
context,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
val context = requireContext()
|
||||
binding.title.text = context.getString(R.string.subscriptions)
|
||||
binding.replyButton.visibility = View.GONE
|
||||
subscriptions.forEach { (id, media) ->
|
||||
adapter.add(SubscriptionItem(id, media, adapter))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(subscriptions: Map<Int, SubscriptionHelper.Companion.SubscribeMedia>): SubscriptionsBottomDialog {
|
||||
val dialog = SubscriptionsBottomDialog()
|
||||
dialog.subscriptions = subscriptions
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
}
|
|
@ -395,9 +395,11 @@ object PrefManager {
|
|||
val obj = ois.readObject() as T?
|
||||
obj
|
||||
} else {
|
||||
Logger.log("Serialized data is null (key: $key)")
|
||||
default
|
||||
}
|
||||
} catch (e: java.io.InvalidClassException) {
|
||||
Logger.log(e)
|
||||
try {
|
||||
getPrefLocation(location).edit().remove(key).apply()
|
||||
default
|
||||
|
|
|
@ -85,5 +85,7 @@ interface SAnime : Serializable {
|
|||
fun create(): SAnime {
|
||||
return SAnimeImpl()
|
||||
}
|
||||
|
||||
private const val serialVersionUID = 1L
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,5 +84,7 @@ interface SManga : Serializable {
|
|||
fun create(): SManga {
|
||||
return SMangaImpl()
|
||||
}
|
||||
|
||||
private const val serialVersionUID = 1L
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,12 +46,12 @@
|
|||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/notifications"
|
||||
android:textSize="28sp" />
|
||||
android:textSize="27sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="96dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:padding="24dp"
|
||||
app:srcCompat="@drawable/ic_round_notifications_none_24"
|
||||
|
|
32
app/src/main/res/layout/item_subscription.xml
Normal file
32
app/src/main/res/layout/item_subscription.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subscriptionName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/placeholder"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/deleteSubscription"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/delete"
|
||||
android:src="@drawable/ic_circle_cancel"
|
||||
app:tint="?attr/colorOnBackground" />
|
||||
|
||||
</LinearLayout>
|
|
@ -991,4 +991,8 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
|
|||
<string name="replies">Replies</string>
|
||||
<string name="open_rules">Open Rules</string>
|
||||
<string name="post_to_anilist_warning">By posting to AniList, you agree to the rules and guidelines of AniList</string>
|
||||
<string name="view_subscriptions">View Subscriptions</string>
|
||||
<string name="view_subscriptions_desc">View and edit all your subscriptions</string>
|
||||
<string name="subscriptions">Subscriptions</string>
|
||||
<string name="subscription_deleted">Subscription Deleted</string>
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue