Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 911e959fcf | |||
| a425cae73b | |||
| d12a9d329b |
@@ -52,3 +52,20 @@ When creating a fork, remember to:
|
||||
- To avoid having your data polluting the main app's analytics and crash report services:
|
||||
- If you want to use Firebase analytics, replace [`google-services.json`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/standard/google-services.json) with your own
|
||||
- If you want to use ACRA crash reporting, replace the `ACRA_URI` endpoint in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts) with your own
|
||||
|
||||
|
||||
### Supporting Cloud Sync - Google Drive Implementation
|
||||
1. Go to [Google Cloud Console](https://console.cloud.google.com)
|
||||
2. Create a new project
|
||||
3. Go to API & Services -> Library -> Google Drive API and click enable
|
||||
4. Go to API & Services -> Oauth consent screen
|
||||
5. Create it, fill in the app name, user support email, and developer contact information
|
||||
6. In the next screen, click add or remove scopes, and add the `.../auth/drive.appdata` and `.../auth/drive.file` scopes
|
||||
7. Don't add any test users and go back to the dashboard
|
||||
8. Click publish
|
||||
9. Go to API & Services -> Credentials
|
||||
10. Click Create credentials -> Oauth client ID
|
||||
11. Select Android, give it a name, and set eu.kanade.google.oauth as the package name
|
||||
12. To get the SHA-1 key, run `keytool -printcert -jarfile app-standard-universal-release.apk` on your apk, and copy the listed SHA-1
|
||||
13. Expand advanced settings, and enable Custom URL scheme
|
||||
14. After that just download the json, name it to `client_secrets.json` and put it in `app/src/main/assets/`
|
||||
@@ -73,7 +73,6 @@ class SyncPreferences(
|
||||
syncOnChapterOpen = preferenceStore.getBoolean("sync_on_chapter_open", false).get(),
|
||||
syncOnAppStart = preferenceStore.getBoolean("sync_on_app_start", false).get(),
|
||||
syncOnAppResume = preferenceStore.getBoolean("sync_on_app_resume", false).get(),
|
||||
syncOnLibraryUpdate = preferenceStore.getBoolean("sync_on_library_update", false).get(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -86,7 +85,5 @@ class SyncPreferences(
|
||||
.set(syncTriggerOptions.syncOnAppStart)
|
||||
preferenceStore.getBoolean("sync_on_app_resume", false)
|
||||
.set(syncTriggerOptions.syncOnAppResume)
|
||||
preferenceStore.getBoolean("sync_on_library_update", false)
|
||||
.set(syncTriggerOptions.syncOnLibraryUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +239,7 @@ fun LibraryBottomActionMenu(
|
||||
onClickCleanTitles: (() -> Unit)?,
|
||||
onClickMigrate: (() -> Unit)?,
|
||||
onClickAddToMangaDex: (() -> Unit)?,
|
||||
onClickResetInfo: (() -> Unit)?,
|
||||
// SY <--
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
@@ -267,7 +268,7 @@ fun LibraryBottomActionMenu(
|
||||
}
|
||||
}
|
||||
// SY -->
|
||||
val showOverflow = onClickCleanTitles != null || onClickAddToMangaDex != null
|
||||
val showOverflow = onClickCleanTitles != null || onClickAddToMangaDex != null || onClickResetInfo != null
|
||||
val configuration = LocalConfiguration.current
|
||||
val moveMarkPrev = remember { !configuration.isTabletUi() }
|
||||
var overFlowOpen by remember { mutableStateOf(false) }
|
||||
@@ -364,6 +365,12 @@ fun LibraryBottomActionMenu(
|
||||
onClick = onClickAddToMangaDex,
|
||||
)
|
||||
}
|
||||
if (onClickResetInfo != null) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = stringResource(SYMR.strings.reset_info)) },
|
||||
onClick = onClickResetInfo,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Button(
|
||||
|
||||
@@ -817,19 +817,11 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
||||
KEY_GROUP_EXTRA to groupExtra,
|
||||
// SY <--
|
||||
)
|
||||
val request = OneTimeWorkRequestBuilder<LibraryUpdateJob>()
|
||||
.addTag(TAG)
|
||||
.addTag(WORK_NAME_MANUAL)
|
||||
.setInputData(inputData)
|
||||
.build()
|
||||
wm.enqueueUniqueWork(WORK_NAME_MANUAL, ExistingWorkPolicy.KEEP, request)
|
||||
|
||||
val syncPreferences: SyncPreferences = Injekt.get()
|
||||
|
||||
// Only proceed with SyncDataJob if sync is enabled and the specific sync on library update flag is set
|
||||
val syncTriggerOpt = syncPreferences.getSyncTriggerOptions()
|
||||
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnLibraryUpdate
|
||||
) {
|
||||
// Always sync the data before library update if syncing is enabled.
|
||||
if (syncPreferences.isSyncEnabled()) {
|
||||
// Check if SyncDataJob is already running
|
||||
if (wm.isRunning(SyncDataJob.TAG_MANUAL)) {
|
||||
// SyncDataJob is already running
|
||||
@@ -842,7 +834,6 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
||||
.build()
|
||||
|
||||
// Chain SyncDataJob to run before LibraryUpdateJob
|
||||
val inputData = workDataOf(KEY_CATEGORY to category?.id)
|
||||
val libraryUpdateJob = OneTimeWorkRequestBuilder<LibraryUpdateJob>()
|
||||
.addTag(TAG)
|
||||
.addTag(WORK_NAME_MANUAL)
|
||||
@@ -853,7 +844,6 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
||||
.then(libraryUpdateJob)
|
||||
.enqueue()
|
||||
} else {
|
||||
val inputData = workDataOf(KEY_CATEGORY to category?.id)
|
||||
val request = OneTimeWorkRequestBuilder<LibraryUpdateJob>()
|
||||
.addTag(TAG)
|
||||
.addTag(WORK_NAME_MANUAL)
|
||||
|
||||
@@ -9,21 +9,18 @@ data class SyncTriggerOptions(
|
||||
val syncOnChapterOpen: Boolean = false,
|
||||
val syncOnAppStart: Boolean = false,
|
||||
val syncOnAppResume: Boolean = false,
|
||||
val syncOnLibraryUpdate: Boolean = false,
|
||||
) {
|
||||
fun asBooleanArray() = booleanArrayOf(
|
||||
syncOnChapterRead,
|
||||
syncOnChapterOpen,
|
||||
syncOnAppStart,
|
||||
syncOnAppResume,
|
||||
syncOnLibraryUpdate,
|
||||
)
|
||||
|
||||
fun anyEnabled() = syncOnChapterRead ||
|
||||
syncOnChapterOpen ||
|
||||
syncOnAppStart ||
|
||||
syncOnAppResume ||
|
||||
syncOnLibraryUpdate
|
||||
syncOnAppResume
|
||||
|
||||
companion object {
|
||||
val mainOptions = persistentListOf(
|
||||
@@ -47,11 +44,6 @@ data class SyncTriggerOptions(
|
||||
getter = SyncTriggerOptions::syncOnAppResume,
|
||||
setter = { options, enabled -> options.copy(syncOnAppResume = enabled) },
|
||||
),
|
||||
Entry(
|
||||
label = MR.strings.sync_on_library_update,
|
||||
getter = SyncTriggerOptions::syncOnLibraryUpdate,
|
||||
setter = { options, enabled -> options.copy(syncOnLibraryUpdate = enabled) },
|
||||
),
|
||||
)
|
||||
|
||||
fun fromBooleanArray(array: BooleanArray) = SyncTriggerOptions(
|
||||
@@ -59,7 +51,6 @@ data class SyncTriggerOptions(
|
||||
syncOnChapterOpen = array[1],
|
||||
syncOnAppStart = array[2],
|
||||
syncOnAppResume = array[3],
|
||||
syncOnLibraryUpdate = array[4],
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -750,6 +750,24 @@ class LibraryScreenModel(
|
||||
clearSelection()
|
||||
}
|
||||
}
|
||||
|
||||
fun resetInfo() {
|
||||
state.value.selection.fastForEach { (manga) ->
|
||||
val mangaInfo = CustomMangaInfo(
|
||||
id = manga.id,
|
||||
title = null,
|
||||
author = null,
|
||||
artist = null,
|
||||
thumbnailUrl = null,
|
||||
description = null,
|
||||
genre = null,
|
||||
status = null,
|
||||
)
|
||||
|
||||
setCustomMangaInfo.set(mangaInfo)
|
||||
}
|
||||
clearSelection()
|
||||
}
|
||||
// SY <--
|
||||
|
||||
/**
|
||||
@@ -1336,6 +1354,18 @@ class LibraryScreenModel(
|
||||
val showAddToMangadex: Boolean by lazy {
|
||||
selection.any { it.manga.source in mangaDexSourceIds }
|
||||
}
|
||||
|
||||
val showResetInfo: Boolean by lazy {
|
||||
selection.fastAny { (manga) ->
|
||||
manga.title != manga.ogTitle ||
|
||||
manga.author != manga.ogAuthor ||
|
||||
manga.artist != manga.ogArtist ||
|
||||
manga.thumbnailUrl != manga.ogThumbnailUrl ||
|
||||
manga.description != manga.ogDescription ||
|
||||
manga.genre != manga.ogGenre ||
|
||||
manga.status != manga.ogStatus
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
||||
fun getLibraryItemsByCategoryId(categoryId: Long): List<LibraryItem>? {
|
||||
|
||||
@@ -205,6 +205,7 @@ object LibraryTab : Tab {
|
||||
}
|
||||
},
|
||||
onClickAddToMangaDex = screenModel::syncMangaToDex.takeIf { state.showAddToMangadex },
|
||||
onClickResetInfo = screenModel::resetInfo.takeIf { state.showResetInfo },
|
||||
// SY <--
|
||||
)
|
||||
},
|
||||
|
||||
@@ -201,6 +201,7 @@ private fun onViewCreated(manga: Manga, context: Context, binding: EditMangaDial
|
||||
binding.mangaGenresTags.clearFocus()
|
||||
|
||||
binding.resetTags.setOnClickListener { resetTags(manga, binding, scope) }
|
||||
binding.resetInfo.setOnClickListener { resetInfo(manga, binding, scope) }
|
||||
}
|
||||
|
||||
private fun resetTags(manga: Manga, binding: EditMangaDialogBinding, scope: CoroutineScope) {
|
||||
@@ -217,6 +218,15 @@ private fun loadCover(manga: Manga, context: Context, binding: EditMangaDialogBi
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetInfo(manga: Manga, binding: EditMangaDialogBinding, scope: CoroutineScope) {
|
||||
binding.title.setText("")
|
||||
binding.mangaAuthor.setText("")
|
||||
binding.mangaArtist.setText("")
|
||||
binding.thumbnailUrl.setText("")
|
||||
binding.mangaDescription.setText("")
|
||||
resetTags(manga, binding, scope)
|
||||
}
|
||||
|
||||
private fun ChipGroup.setChips(items: List<String>, scope: CoroutineScope) {
|
||||
removeAllViews()
|
||||
|
||||
|
||||
@@ -139,6 +139,16 @@
|
||||
android:text="@string/reset_tags"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/reset_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/reset_info"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
|
||||
@@ -350,6 +350,7 @@
|
||||
<!-- Entry Info Edit -->
|
||||
<string name="reset_tags">Reset Tags</string>
|
||||
<string name="add_tag">Add Tag</string>
|
||||
<string name="reset_info">Reset Info</string>
|
||||
<string name="title_hint">Title: %1$s</string>
|
||||
<string name="description_hint">Description: %1$s</string>
|
||||
<string name="author_hint">Author: %1$s</string>
|
||||
|
||||
@@ -591,7 +591,6 @@
|
||||
<string name="sync_on_chapter_open">Sync on Chapter Open</string>
|
||||
<string name="sync_on_app_start">Sync on App Start</string>
|
||||
<string name="sync_on_app_resume">Sync on App Resume</string>
|
||||
<string name="sync_on_library_update">Sync on Library Update</string>
|
||||
<string name="sync_library">Sync library</string>
|
||||
|
||||
<!-- Advanced section -->
|
||||
|
||||
Reference in New Issue
Block a user