Remove manga from trackers (#9535)
* Dialog for service tracker removal added, anilist query prepared * added API delete requests for Mal and Kitsu * implement and fix tracker delete for anilist, shikimori, mangaupdates * implement and test mal delete request * Update to dialog text to reflect current tracker * finish kitsu api request and block bangumi tracker removal * Change delete flag into interface, localise strings, clean up logs * Add shikimori delete compatibility for already existing entries * update track delete dialog prompt to include checkbox, update strings * Update i18n/src/main/res/values/strings.xml Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com> * Update i18n/src/main/res/values/strings.xml --------- Co-authored-by: unknown <zaghdane@fireflow.de> Co-authored-by: arkon <arkon@users.noreply.github.com> Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga.track
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -11,6 +12,7 @@ import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -48,6 +50,7 @@ import eu.kanade.presentation.track.TrackServiceSearch
|
||||
import eu.kanade.presentation.track.TrackStatusSelector
|
||||
import eu.kanade.presentation.util.Screen
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.track.DeletableTrackService
|
||||
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
@@ -157,7 +160,16 @@ data class TrackInfoDialogHomeScreen(
|
||||
}
|
||||
},
|
||||
onOpenInBrowser = { openTrackerInBrowser(context, it) },
|
||||
) { sm.unregisterTracking(it.service.id) }
|
||||
onRemoved = {
|
||||
navigator.push(
|
||||
TrackServiceRemoveScreen(
|
||||
mangaId = mangaId,
|
||||
track = it.track!!,
|
||||
serviceId = it.service.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +186,6 @@ data class TrackInfoDialogHomeScreen(
|
||||
private val mangaId: Long,
|
||||
private val sourceId: Long,
|
||||
private val getTracks: GetTracks = Injekt.get(),
|
||||
private val deleteTrack: DeleteTrack = Injekt.get(),
|
||||
) : StateScreenModel<Model.State>(State()) {
|
||||
|
||||
init {
|
||||
@@ -204,10 +215,6 @@ data class TrackInfoDialogHomeScreen(
|
||||
}
|
||||
}
|
||||
|
||||
fun unregisterTracking(serviceId: Long) {
|
||||
coroutineScope.launchNonCancellable { deleteTrack.await(mangaId, serviceId) }
|
||||
}
|
||||
|
||||
private suspend fun refreshTrackers() {
|
||||
val insertTrack = Injekt.get<InsertTrack>()
|
||||
val getMangaWithChapters = Injekt.get<GetMangaWithChapters>()
|
||||
@@ -723,3 +730,100 @@ data class TrackServiceSearchScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private data class TrackServiceRemoveScreen(
|
||||
private val mangaId: Long,
|
||||
private val track: Track,
|
||||
private val serviceId: Long,
|
||||
) : Screen() {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val sm = rememberScreenModel {
|
||||
Model(
|
||||
mangaId = mangaId,
|
||||
track = track,
|
||||
service = Injekt.get<TrackManager>().getService(serviceId)!!,
|
||||
)
|
||||
}
|
||||
val serviceName = stringResource(sm.getServiceNameRes())
|
||||
var removeRemoteTrack by remember { mutableStateOf(false) }
|
||||
AlertDialogContent(
|
||||
modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars),
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.track_delete_title, serviceName),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(R.string.track_delete_text, serviceName),
|
||||
)
|
||||
if (sm.isServiceDeletable()) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Checkbox(checked = removeRemoteTrack, onCheckedChange = { removeRemoteTrack = it })
|
||||
Text(text = stringResource(R.string.track_delete_remote_text, serviceName))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
buttons = {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
MaterialTheme.padding.small,
|
||||
Alignment.End,
|
||||
),
|
||||
) {
|
||||
TextButton(onClick = navigator::pop) {
|
||||
Text(text = stringResource(R.string.action_cancel))
|
||||
}
|
||||
FilledTonalButton(
|
||||
onClick = {
|
||||
sm.unregisterTracking(serviceId)
|
||||
if (removeRemoteTrack) sm.deleteMangaFromService()
|
||||
navigator.pop()
|
||||
},
|
||||
colors = ButtonDefaults.filledTonalButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||
contentColor = MaterialTheme.colorScheme.onErrorContainer,
|
||||
),
|
||||
) {
|
||||
Text(text = stringResource(R.string.action_ok))
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private class Model(
|
||||
private val mangaId: Long,
|
||||
private val track: Track,
|
||||
private val service: TrackService,
|
||||
private val deleteTrack: DeleteTrack = Injekt.get(),
|
||||
) : ScreenModel {
|
||||
|
||||
fun getServiceNameRes() = service.nameRes()
|
||||
|
||||
fun isServiceDeletable() = service is DeletableTrackService
|
||||
|
||||
fun deleteMangaFromService() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
(service as DeletableTrackService).delete(track.toDbTrack())
|
||||
}
|
||||
}
|
||||
|
||||
fun unregisterTracking(serviceId: Long) {
|
||||
coroutineScope.launchNonCancellable { deleteTrack.await(mangaId, serviceId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user