Compare commits

...

10 Commits
v4.4 ... v4.4.1

Author SHA1 Message Date
InfinityDouki56
5d2395b569 Translated using Weblate (Filipino)
Currently translated at 92.4% (392 of 424 strings)

Translated using Weblate (Filipino)

Currently translated at 100.0% (8 of 8 strings)

Co-authored-by: InfinityDouki56 <ced.paltep10@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/fil/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fil/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2023-02-23 19:48:42 +02:00
Koitharu
29114ae8a7 Sync logger 2023-02-22 20:20:57 +02:00
Koitharu
47f80085d1 Temporary disable sync for release builds 2023-02-22 07:56:30 +02:00
Koitharu
73c1d2a616 Show error details for pages 2023-02-21 18:59:52 +02:00
InfinityDouki56
35366ac660 Translated using Weblate (Filipino)
Currently translated at 56.1% (238 of 424 strings)

Translated using Weblate (Filipino)

Currently translated at 0.0% (0 of 8 strings)

Added translation using Weblate (Filipino)

Added translation using Weblate (Filipino)

Co-authored-by: InfinityDouki56 <ced.paltep10@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/plurals/fil/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fil/
Translation: Kotatsu/Strings
Translation: Kotatsu/plurals
2023-02-21 18:32:13 +02:00
J. Lavoie
dc2dd4e3c9 Translated using Weblate (Greek)
Currently translated at 21.6% (92 of 424 strings)

Translated using Weblate (French)

Currently translated at 100.0% (424 of 424 strings)

Translated using Weblate (French)

Currently translated at 98.8% (419 of 424 strings)

Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/el/
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/fr/
Translation: Kotatsu/Strings
2023-02-21 18:32:13 +02:00
Koitharu
66817ae545 Fix search bar hint font 2023-02-17 20:03:57 +02:00
Koitharu
b6e3cb929b Fix explore buttons color 2023-02-17 19:43:38 +02:00
Koitharu
6f29259395 Add "Grid mode" option to explore options menu 2023-02-17 18:58:37 +02:00
Koitharu
c520699f9f Fix crash with invalid domain 2023-02-17 07:39:59 +02:00
32 changed files with 666 additions and 79 deletions

View File

@@ -15,8 +15,8 @@ android {
applicationId 'org.koitharu.kotatsu' applicationId 'org.koitharu.kotatsu'
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 33
versionCode 516 versionCode 517
versionName '4.4' versionName '4.4.1'
generatedDensities = [] generatedDensities = []
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -87,7 +87,7 @@ afterEvaluate {
} }
} }
dependencies { dependencies {
implementation('com.github.KotatsuApp:kotatsu-parsers:cf345d2d0c') { implementation('com.github.KotatsuApp:kotatsu-parsers:f4c47b5b84') {
exclude group: 'org.json', module: 'json' exclude group: 'org.json', module: 'json'
} }

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<bool name="leak_canary_add_launcher_icon" tools:node="replace">false</bool> <bool name="leak_canary_add_launcher_icon" tools:node="replace">false</bool>
</resources> <bool name="is_sync_enabled">true</bool>
</resources>

View File

@@ -1,11 +1,15 @@
package org.koitharu.kotatsu.core.exceptions.resolve package org.koitharu.kotatsu.core.exceptions.resolve
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import androidx.activity.result.ActivityResultCallback import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.collection.ArrayMap import androidx.collection.ArrayMap
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Headers import okhttp3.Headers
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -17,6 +21,7 @@ import org.koitharu.kotatsu.parsers.exception.NotFoundException
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity
import org.koitharu.kotatsu.utils.TaggedActivityResult import org.koitharu.kotatsu.utils.TaggedActivityResult
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.isSuccess import org.koitharu.kotatsu.utils.isSuccess
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
import kotlin.coroutines.resume import kotlin.coroutines.resume
@@ -95,5 +100,21 @@ class ExceptionResolver private constructor(
} }
fun canResolve(e: Throwable) = getResolveStringId(e) != 0 fun canResolve(e: Throwable) = getResolveStringId(e) != 0
fun showDetails(context: Context, e: Throwable) {
val stackTrace = e.stackTraceToString()
val dialog = MaterialAlertDialogBuilder(context)
.setTitle(e.getDisplayMessage(context.resources))
.setMessage(stackTrace)
.setPositiveButton(androidx.preference.R.string.copy) { _, _ ->
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboardManager.setPrimaryClip(
ClipData.newPlainText(context.getString(R.string.error), stackTrace),
)
}
.setNegativeButton(R.string.close, null)
.create()
dialog.show()
}
} }
} }

View File

@@ -68,6 +68,12 @@ class FileLogger(
postFlush() postFlush()
} }
inline fun log(messageProducer: () -> String) {
if (isEnabled) {
log(messageProducer())
}
}
suspend fun flush() { suspend fun flush() {
if (!isEnabled) { if (!isEnabled) {
return return

View File

@@ -5,3 +5,7 @@ import javax.inject.Qualifier
@Qualifier @Qualifier
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)
annotation class TrackerLogger annotation class TrackerLogger
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class SyncLogger

View File

@@ -21,11 +21,20 @@ object LoggersModule {
settings: AppSettings, settings: AppSettings,
) = FileLogger(context, settings, "tracker") ) = FileLogger(context, settings, "tracker")
@Provides
@SyncLogger
fun provideSyncLogger(
@ApplicationContext context: Context,
settings: AppSettings,
) = FileLogger(context, settings, "sync")
@Provides @Provides
@ElementsIntoSet @ElementsIntoSet
fun provideAllLoggers( fun provideAllLoggers(
@TrackerLogger trackerLogger: FileLogger, @TrackerLogger trackerLogger: FileLogger,
@SyncLogger syncLogger: FileLogger,
): Set<@JvmSuppressWildcards FileLogger> = arraySetOf( ): Set<@JvmSuppressWildcards FileLogger> = arraySetOf(
trackerLogger, trackerLogger,
syncLogger,
) )
} }

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.network
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import dagger.Lazy import dagger.Lazy
import okhttp3.Headers
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@@ -11,6 +12,7 @@ import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.util.mergeWith import org.koitharu.kotatsu.parsers.util.mergeWith
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
import java.util.Locale import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@@ -39,12 +41,18 @@ class CommonHeadersInterceptor @Inject constructor(
headersBuilder[CommonHeaders.USER_AGENT] = userAgentFallback headersBuilder[CommonHeaders.USER_AGENT] = userAgentFallback
} }
if (headersBuilder[CommonHeaders.REFERER] == null && repository != null) { if (headersBuilder[CommonHeaders.REFERER] == null && repository != null) {
headersBuilder[CommonHeaders.REFERER] = "https://${repository.domain}/" headersBuilder.trySet(CommonHeaders.REFERER, "https://${repository.domain}/")
} }
val newRequest = request.newBuilder().headers(headersBuilder.build()).build() val newRequest = request.newBuilder().headers(headersBuilder.build()).build()
return repository?.intercept(ProxyChain(chain, newRequest)) ?: chain.proceed(newRequest) return repository?.intercept(ProxyChain(chain, newRequest)) ?: chain.proceed(newRequest)
} }
private fun Headers.Builder.trySet(name: String, value: String) = try {
set(name, value)
} catch (e: IllegalArgumentException) {
e.printStackTraceDebug()
}
private class ProxyChain( private class ProxyChain(
private val delegate: Interceptor.Chain, private val delegate: Interceptor.Chain,
private val request: Request, private val request: Request,

View File

@@ -36,6 +36,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.search.ui.MangaListActivity import org.koitharu.kotatsu.search.ui.MangaListActivity
import org.koitharu.kotatsu.settings.SettingsActivity import org.koitharu.kotatsu.settings.SettingsActivity
import org.koitharu.kotatsu.suggestions.ui.SuggestionsActivity import org.koitharu.kotatsu.suggestions.ui.SuggestionsActivity
import org.koitharu.kotatsu.utils.ext.addMenuProvider
import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import javax.inject.Inject import javax.inject.Inject
@@ -70,6 +71,7 @@ class ExploreFragment :
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing) val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
paddingHorizontal = spacing paddingHorizontal = spacing
} }
addMenuProvider(ExploreMenuProvider(view.context, viewModel))
viewModel.content.observe(viewLifecycleOwner) { viewModel.content.observe(viewLifecycleOwner) {
exploreAdapter?.items = it exploreAdapter?.items = it
} }
@@ -162,6 +164,7 @@ class ExploreFragment :
} else { } else {
LinearLayoutManager(requireContext()) LinearLayoutManager(requireContext())
} }
activity?.invalidateOptionsMenu()
} }
private inner class SourceMenuListener( private inner class SourceMenuListener(

View File

@@ -0,0 +1,34 @@
package org.koitharu.kotatsu.explore.ui
import android.content.Context
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.core.view.MenuProvider
import org.koitharu.kotatsu.R
class ExploreMenuProvider(
private val context: Context,
private val viewModel: ExploreViewModel,
) : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.opt_explore, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_grid -> {
viewModel.setGridMode(!menuItem.isChecked)
true
}
else -> false
}
}
override fun onPrepareMenu(menu: Menu) {
super.onPrepareMenu(menu)
menu.findItem(R.id.action_grid)?.isChecked = viewModel.isGrid.value == true
}
}

View File

@@ -69,6 +69,10 @@ class ExploreViewModel @Inject constructor(
} }
} }
fun setGridMode(value: Boolean) {
settings.isSourcesGridMode = value
}
private fun createContentFlow() = settings.observe() private fun createContentFlow() = settings.observe()
.filter { .filter {
it == AppSettings.KEY_SOURCES_HIDDEN || it == AppSettings.KEY_SOURCES_HIDDEN ||

View File

@@ -327,8 +327,10 @@ class MainActivity :
TrackWorker.setup(applicationContext) TrackWorker.setup(applicationContext)
SuggestionsWorker.setup(applicationContext) SuggestionsWorker.setup(applicationContext)
} }
MangaPrefetchService.prefetchLast(this@MainActivity) whenResumed {
requestNotificationsPermission() MangaPrefetchService.prefetchLast(this@MainActivity)
requestNotificationsPermission()
}
} }
} }

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.reader.ui.pager package org.koitharu.kotatsu.reader.ui.pager
import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
@@ -59,6 +60,11 @@ class PageHolderDelegate(
} }
} }
fun showErrorDetails(context: Context) {
val e = error ?: return
ExceptionResolver.showDetails(context, e)
}
fun onAttachedToWindow() { fun onAttachedToWindow() {
readerSettings.observeForever(this) readerSettings.observeForever(this)
} }
@@ -87,6 +93,7 @@ class PageHolderDelegate(
} }
override fun onImageLoadError(e: Throwable) { override fun onImageLoadError(e: Throwable) {
e.printStackTraceDebug()
val file = this.file val file = this.file
error = e error = e
if (state == State.LOADED && e is IOException && file != null && file.exists()) { if (state == State.LOADED && e is IOException && file != null && file.exists()) {

View File

@@ -33,8 +33,8 @@ open class PageHolder(
binding.ssiv.bindToLifecycle(owner) binding.ssiv.bindToLifecycle(owner)
binding.ssiv.isEagerLoadingEnabled = !isLowRamDevice(context) binding.ssiv.isEagerLoadingEnabled = !isLowRamDevice(context)
binding.ssiv.addOnImageEventListener(delegate) binding.ssiv.addOnImageEventListener(delegate)
@Suppress("LeakingThis")
bindingInfo.buttonRetry.setOnClickListener(this) bindingInfo.buttonRetry.setOnClickListener(this)
bindingInfo.buttonErrorDetails.setOnClickListener(this)
binding.textViewNumber.isVisible = settings.isPagesNumbersEnabled binding.textViewNumber.isVisible = settings.isPagesNumbersEnabled
} }
@@ -115,6 +115,7 @@ open class PageHolder(
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_retry -> delegate.retry(boundData?.toMangaPage() ?: return) R.id.button_retry -> delegate.retry(boundData?.toMangaPage() ?: return)
R.id.button_error_details -> delegate.showErrorDetails(v.context)
} }
} }

View File

@@ -19,7 +19,6 @@ import org.koitharu.kotatsu.utils.GoneOnInvisibleListener
import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.ext.hideCompat import org.koitharu.kotatsu.utils.ext.hideCompat
import org.koitharu.kotatsu.utils.ext.ifZero import org.koitharu.kotatsu.utils.ext.ifZero
import org.koitharu.kotatsu.utils.ext.setProgressCompat
import org.koitharu.kotatsu.utils.ext.showCompat import org.koitharu.kotatsu.utils.ext.showCompat
class WebtoonHolder( class WebtoonHolder(
@@ -40,6 +39,7 @@ class WebtoonHolder(
binding.ssiv.regionDecoderFactory = SkiaPooledImageRegionDecoder.Factory() binding.ssiv.regionDecoderFactory = SkiaPooledImageRegionDecoder.Factory()
binding.ssiv.addOnImageEventListener(delegate) binding.ssiv.addOnImageEventListener(delegate)
bindingInfo.buttonRetry.setOnClickListener(this) bindingInfo.buttonRetry.setOnClickListener(this)
bindingInfo.buttonErrorDetails.setOnClickListener(this)
} }
override fun onBind(data: ReaderPage) { override fun onBind(data: ReaderPage) {
@@ -104,6 +104,7 @@ class WebtoonHolder(
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_retry -> delegate.retry(boundData?.toMangaPage() ?: return) R.id.button_retry -> delegate.retry(boundData?.toMangaPage() ?: return)
R.id.button_error_details -> delegate.showErrorDetails(v.context)
} }
} }

View File

@@ -3,6 +3,9 @@ package org.koitharu.kotatsu.search.ui.widget
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Parcelable import android.os.Parcelable
import android.text.Spannable
import android.text.SpannableString
import android.text.style.TextAppearanceSpan
import android.util.AttributeSet import android.util.AttributeSet
import android.view.KeyEvent import android.view.KeyEvent
import android.view.MotionEvent import android.view.MotionEvent
@@ -12,11 +15,11 @@ import android.view.inputmethod.EditorInfo
import androidx.annotation.AttrRes import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatEditText import androidx.appcompat.widget.AppCompatEditText
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.material.R as materialR
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener
import org.koitharu.kotatsu.utils.ext.drawableEnd import org.koitharu.kotatsu.utils.ext.drawableEnd
import org.koitharu.kotatsu.utils.ext.drawableStart import org.koitharu.kotatsu.utils.ext.drawableStart
import com.google.android.material.R as materialR
private const val DRAWABLE_END = 2 private const val DRAWABLE_END = 2
@@ -31,6 +34,10 @@ class SearchEditText @JvmOverloads constructor(
private val voiceIcon = ContextCompat.getDrawable(context, R.drawable.ic_voice_input) private val voiceIcon = ContextCompat.getDrawable(context, R.drawable.ic_voice_input)
private var isEmpty = text.isNullOrEmpty() private var isEmpty = text.isNullOrEmpty()
init {
wrapHint()
}
var isVoiceSearchEnabled: Boolean = false var isVoiceSearchEnabled: Boolean = false
set(value) { set(value) {
field = value field = value
@@ -124,4 +131,16 @@ class SearchEditText @JvmOverloads constructor(
setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, null, icon, null) setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, null, icon, null)
} }
} }
}
private fun wrapHint() {
val rawHint = hint?.toString() ?: return
val formatted = SpannableString(rawHint)
formatted.setSpan(
TextAppearanceSpan(context, materialR.style.TextAppearance_Material3_SearchView),
0,
formatted.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE,
)
hint = formatted
}
}

View File

@@ -7,14 +7,24 @@ import org.koitharu.kotatsu.utils.EditTextValidator
class DomainValidator : EditTextValidator() { class DomainValidator : EditTextValidator() {
override fun validate(text: String): ValidationResult { override fun validate(text: String): ValidationResult {
if (text.isBlank()) { val trimmed = text.trim()
if (trimmed.isEmpty()) {
return ValidationResult.Success return ValidationResult.Success
} }
val host = text.trim().toCanonicalHost() return if (!checkCharacters(trimmed) || trimmed.toCanonicalHost() == null) {
return if (host == null) {
ValidationResult.Failed(context.getString(R.string.invalid_domain_message)) ValidationResult.Failed(context.getString(R.string.invalid_domain_message))
} else { } else {
ValidationResult.Success ValidationResult.Success
} }
} }
}
private fun checkCharacters(value: String): Boolean {
for (i in value.indices) {
val c = value[i]
if (c !in '\u0020'..'\u007e') {
return false
}
}
return true
}
}

View File

@@ -14,15 +14,17 @@ import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import org.koitharu.kotatsu.core.db.* import org.koitharu.kotatsu.core.db.*
import org.koitharu.kotatsu.core.logs.FileLogger
import org.koitharu.kotatsu.core.logs.SyncLogger
import java.util.concurrent.Callable import java.util.concurrent.Callable
abstract class SyncProvider : ContentProvider() { abstract class SyncProvider : ContentProvider() {
private val database by lazy { private val entryPoint by lazy {
val appContext = checkNotNull(context?.applicationContext) EntryPointAccessors.fromApplication(checkNotNull(context), SyncProviderEntryPoint::class.java)
val entryPoint = EntryPointAccessors.fromApplication(appContext, SyncProviderEntryPoint::class.java)
entryPoint.database()
} }
private val database by lazy { entryPoint.database }
private val logger by lazy { entryPoint.logger }
private val supportedTables = setOf( private val supportedTables = setOf(
TABLE_FAVOURITES, TABLE_FAVOURITES,
@@ -50,6 +52,7 @@ abstract class SyncProvider : ContentProvider() {
.selection(selection, selectionArgs) .selection(selection, selectionArgs)
.orderBy(sortOrder) .orderBy(sortOrder)
.create() .create()
logger.log("query: ${sqlQuery.sql}")
return database.openHelper.readableDatabase.query(sqlQuery) return database.openHelper.readableDatabase.query(sqlQuery)
} }
@@ -62,6 +65,7 @@ abstract class SyncProvider : ContentProvider() {
if (values == null || table == null) { if (values == null || table == null) {
return null return null
} }
logger.log { "insert: $table [$values]" }
val db = database.openHelper.writableDatabase val db = database.openHelper.writableDatabase
if (db.insert(table, SQLiteDatabase.CONFLICT_IGNORE, values) < 0) { if (db.insert(table, SQLiteDatabase.CONFLICT_IGNORE, values) < 0) {
db.update(table, values) db.update(table, values)
@@ -71,6 +75,7 @@ abstract class SyncProvider : ContentProvider() {
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int { override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
val table = getTableName(uri) ?: return 0 val table = getTableName(uri) ?: return 0
logger.log { "delete: $table ($selection) : ($selectionArgs)" }
return database.openHelper.writableDatabase.delete(table, selection, selectionArgs) return database.openHelper.writableDatabase.delete(table, selection, selectionArgs)
} }
@@ -79,6 +84,7 @@ abstract class SyncProvider : ContentProvider() {
if (values == null || table == null) { if (values == null || table == null) {
return 0 return 0
} }
logger.log { "update: $table ($selection) : ($selectionArgs) [$values]" }
return database.openHelper.writableDatabase return database.openHelper.writableDatabase
.update(table, SQLiteDatabase.CONFLICT_IGNORE, values, selection, selectionArgs) .update(table, SQLiteDatabase.CONFLICT_IGNORE, values, selection, selectionArgs)
} }
@@ -119,6 +125,10 @@ abstract class SyncProvider : ContentProvider() {
@EntryPoint @EntryPoint
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
interface SyncProviderEntryPoint { interface SyncProviderEntryPoint {
fun database(): MangaDatabase
val database: MangaDatabase
@get:SyncLogger
val logger: FileLogger
} }
} }

View File

@@ -6,6 +6,7 @@ import android.content.ContentProviderClient
import android.content.Context import android.content.Context
import android.content.SyncResult import android.content.SyncResult
import android.os.Bundle import android.os.Bundle
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.sync.domain.SyncController import org.koitharu.kotatsu.sync.domain.SyncController
import org.koitharu.kotatsu.sync.domain.SyncHelper import org.koitharu.kotatsu.sync.domain.SyncHelper
import org.koitharu.kotatsu.utils.ext.onError import org.koitharu.kotatsu.utils.ext.onError
@@ -20,6 +21,9 @@ class FavouritesSyncAdapter(context: Context) : AbstractThreadedSyncAdapter(cont
provider: ContentProviderClient, provider: ContentProviderClient,
syncResult: SyncResult, syncResult: SyncResult,
) { ) {
if (!context.resources.getBoolean(R.bool.is_sync_enabled)) {
return
}
val syncHelper = SyncHelper(context, account, provider) val syncHelper = SyncHelper(context, account, provider)
runCatchingCancellable { runCatchingCancellable {
syncHelper.syncFavourites(syncResult) syncHelper.syncFavourites(syncResult)

View File

@@ -6,6 +6,7 @@ import android.content.ContentProviderClient
import android.content.Context import android.content.Context
import android.content.SyncResult import android.content.SyncResult
import android.os.Bundle import android.os.Bundle
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.sync.domain.SyncController import org.koitharu.kotatsu.sync.domain.SyncController
import org.koitharu.kotatsu.sync.domain.SyncHelper import org.koitharu.kotatsu.sync.domain.SyncHelper
import org.koitharu.kotatsu.utils.ext.onError import org.koitharu.kotatsu.utils.ext.onError
@@ -20,6 +21,9 @@ class HistorySyncAdapter(context: Context) : AbstractThreadedSyncAdapter(context
provider: ContentProviderClient, provider: ContentProviderClient,
syncResult: SyncResult, syncResult: SyncResult,
) { ) {
if (!context.resources.getBoolean(R.bool.is_sync_enabled)) {
return
}
val syncHelper = SyncHelper(context, account, provider) val syncHelper = SyncHelper(context, account, provider)
runCatchingCancellable { runCatchingCancellable {
syncHelper.syncHistory(syncResult) syncHelper.syncHistory(syncResult)

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.08" android:color="?attr/elevationOverlayColor" />
</selector>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.08" android:color="@color/kotatsu_onSurface" />
</selector>

View File

@@ -2,6 +2,6 @@
<shape <shape
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="@color/toolbar_background_scrim" /> <solid android:color="@color/colored_button" />
<corners android:radius="100dp" /> <corners android:radius="100dp" />
</shape> </shape>

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
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"
tools:parentTag="android.widget.FrameLayout">
<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"
android:max="100"
tools:viewBindingType="android.widget.ProgressBar" />
<LinearLayout
android:id="@+id/layout_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="60dp"
android:layout_marginEnd="60dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/textView_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="12dp"
android:gravity="center_horizontal"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:drawableTopCompat="@drawable/ic_error_large"
tools:text="@tools:sample/lorem[6]" />
<Button
android:id="@+id/button_retry"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/try_again" />
</LinearLayout>
</merge>

View File

@@ -5,15 +5,13 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="android.widget.FrameLayout"> tools:parentTag="android.widget.FrameLayout">
<!-- https://github.com/material-components/material-components-android/issues/2028 --> <com.google.android.material.progressindicator.CircularProgressIndicator
<ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:indeterminate="true" android:indeterminate="true"
android:max="100" android:max="100" />
tools:viewBindingType="android.widget.ProgressBar" />
<LinearLayout <LinearLayout
android:id="@+id/layout_error" android:id="@+id/layout_error"
@@ -46,6 +44,12 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/try_again" /> android:text="@string/try_again" />
</LinearLayout> <Button
android:id="@+id/button_error_details"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/details" />
</merge> </LinearLayout>
</merge>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_grid"
android:checkable="true"
android:title="@string/show_in_grid_view"
android:titleCondensed="@string/grid" />
</menu>

View File

@@ -78,4 +78,12 @@
<string name="operation_not_supported">Αυτή η λειτουργία δεν υποστηρίζεται</string> <string name="operation_not_supported">Αυτή η λειτουργία δεν υποστηρίζεται</string>
<string name="read_mode">Λειτουργία ανάγνωσης</string> <string name="read_mode">Λειτουργία ανάγνωσης</string>
<string name="grid_size">Μέγεθος πλέγματος</string> <string name="grid_size">Μέγεθος πλέγματος</string>
<string name="theme_name_mamimi">Μαμίμι</string>
<string name="theme_name_kanade">Κανάντε</string>
<string name="nothing_here">Δεν υπάρχει τίποτα εδώ</string>
<string name="theme_name_miku">Μίκου</string>
<string name="theme_name_asuka">Άσουκα</string>
<string name="theme_name_mion">Μιόν</string>
<string name="theme_name_rikka">Ρίκκα</string>
<string name="theme_name_sakura">Σακούρα</string>
</resources> </resources>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="items">
<item quantity="one">%1$d aytem</item>
<item quantity="other">%1$d (na) aytem</item>
</plurals>
<plurals name="pages">
<item quantity="one">"Kabuuang %1$d pahina"</item>
<item quantity="other">Kabuuang %1$d (na) pahina</item>
</plurals>
<plurals name="minutes_ago">
<item quantity="one">%1$d minutong nakakalipas</item>
<item quantity="other">%1$d (na) minutong nakakalipas</item>
</plurals>
<plurals name="new_chapters">
<item quantity="one">%1$d bagong kabanata</item>
<item quantity="other">%1$d mga bagong kabanata</item>
</plurals>
<plurals name="chapters">
<item quantity="one">"%1$d kabanata"</item>
<item quantity="other">%1$d (na) kabanata</item>
</plurals>
<plurals name="chapters_from_x">
<item quantity="one">%1$d kabanata mula sa %2$d</item>
<item quantity="other">%1$d (na) kabanata mula sa %2$d</item>
</plurals>
<plurals name="hours_ago">
<item quantity="one">%1$d oras ang nakalipas</item>
<item quantity="other">%1$d (na) oras ang nakalipas</item>
</plurals>
<plurals name="days_ago">
<item quantity="one">%1$d araw ang nakalipas</item>
<item quantity="other">%1$d (na) araw ang nakalipas</item>
</plurals>
</resources>

View File

@@ -0,0 +1,411 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="updated">Na-update</string>
<string name="newest">Pinakabago</string>
<string name="light">Maliwanag</string>
<string name="by_rating">Marka</string>
<string name="filter">Pansala</string>
<string name="theme">Tema</string>
<string name="dark">Madilim</string>
<string name="automatic">Sundan ang sistema</string>
<string name="error_occurred">May nangyaring error</string>
<string name="network_error">Error sa network</string>
<string name="details">Mga detalye</string>
<string name="chapters">Mga kabanata</string>
<string name="list">Listahan</string>
<string name="page_saved">Na-save</string>
<string name="share_image">I-share ang larawan</string>
<string name="_import">Mag-angkat</string>
<string name="delete">Tanggalin</string>
<string name="operation_not_supported">Hindi suportado ang operasyong ito</string>
<string name="text_file_not_supported">Pumili ng ZIP o CBZ file.</string>
<string name="history_and_cache">Kasaysayan at cache</string>
<string name="no_description">Walang paglalarawan</string>
<string name="grid_size">Laki ng grid</string>
<string name="search_on_s">Hanapin sa %s</string>
<string name="delete_manga">Tanggalin ang manga</string>
<string name="text_delete_local_manga">Permanenteng tanggalin ang \"%s\" sa device\?</string>
<string name="reader_settings">Mga setting sa pagbasa</string>
<string name="switch_pages">Magpalit ng (mga) pahina</string>
<string name="volume_buttons">Pindutan ng volume</string>
<string name="_continue">Magpatuloy</string>
<string name="warning">Babala</string>
<string name="dont_ask_again">Huwag na magtanong muli</string>
<string name="cancelling_">Kinakansela…</string>
<string name="clear_thumbs_cache">I-clear ang cache ng mga thumbnail</string>
<string name="search_history_cleared">Na-clear</string>
<string name="gestures_only">Mga kilos lang</string>
<string name="application_update">Tingnan kung may mga bagong bersyon ng app</string>
<string name="app_update_available">Available ang isang bagong bersyon ng app</string>
<string name="open_in_browser">Buksan sa web browser</string>
<string name="large_manga_save_confirm">Ang manga na ito ay may %s. I-save ang lahat ng ito\?</string>
<string name="notifications">Mga abiso</string>
<string name="enabled_d_of_d" tools:ignore="PluralsCandidate">%1$d ng %2$d sa</string>
<string name="new_chapters">Bagong mga kabanata</string>
<string name="read_from_start">Basahin mula sa simula</string>
<string name="restart">I-restart</string>
<string name="categories_">Mga kategorya…</string>
<string name="rename">Palitan ang pangalan</string>
<string name="text_search_holder_secondary">Subukang i-reformulate ang query.</string>
<string name="text_history_holder_primary">Ang iyong nabasa ay ipapakita dito</string>
<string name="text_shelf_holder_primary">Ang iyong manga ay ipapakita dito</string>
<string name="text_local_holder_primary">Mag-save muna ng isang bagay</string>
<string name="text_local_holder_secondary">I-save ito mula sa mga online na source o mag import ng mga file.</string>
<string name="manga_shelf">Istante</string>
<string name="pages_animation">Animasyon ng pahina</string>
<string name="not_available">Hindi magagamit</string>
<string name="cannot_find_available_storage">Walang available na storage</string>
<string name="other_storage">Iba pang storage</string>
<string name="done">Tapos na</string>
<string name="all_favourites">Lahat ng paborito</string>
<string name="favourites_category_empty">Walang laman ang kategorya</string>
<string name="read_later">Basahin mamaya</string>
<string name="updates">Mga update</string>
<string name="search_results">Mga resulta ng paghahanap</string>
<string name="related">Kaugnay</string>
<string name="size_s">Laki: %s</string>
<string name="waiting_for_network">Naghihintay ng network…</string>
<string name="clear_updates_feed">I-clear ang feed ng mga update</string>
<string name="updates_feed_cleared">Na-clear</string>
<string name="update">Update</string>
<string name="feed_will_update_soon">Ang pag update ng feed ay magsisimula sa lalong madaling panahon</string>
<string name="track_sources">Maghanap ng mga update</string>
<string name="enter_password">Ilagay ang password</string>
<string name="protect_application_summary">Humingi ng password kapag sinimulan ang Kotatsu</string>
<string name="about">Tungkol rito</string>
<string name="check_for_updates">Maghanap ng update</string>
<string name="checking_for_updates">Naghahanap ng update…</string>
<string name="update_check_failed">Hindi makahanap ng mga update</string>
<string name="right_to_left">Kanan sa kaliwa</string>
<string name="create_category">Bagong Kategorya</string>
<string name="zoom_mode_fit_center">Pagkasyahin sa gitna</string>
<string name="zoom_mode_keep_start">Panatilihin sa simula</string>
<string name="black_dark_theme_summary">Gumagamit ng mas kaunting power sa mga AMOLED na screen</string>
<string name="backup_restore">I-backup at i-restore</string>
<string name="data_restored">Naibalik na</string>
<string name="preparing_">Naghahanda…</string>
<string name="report_github">Lumikha ng isyu sa GitHub</string>
<string name="file_not_found">Hindi nahanap ang file</string>
<string name="backup_information">Maaari kang lumikha ng backup ng iyong kasaysayan at mga paborito at ibalik ito</string>
<string name="just_now">Ngayon lang</string>
<string name="yesterday">Kahapon</string>
<string name="long_ago">Matagal na ang nakalipas</string>
<string name="today">Ngayong araw</string>
<string name="tap_to_try_again">I-tap para subukang muli</string>
<string name="captcha_solve">Lutasin</string>
<string name="cookies_cleared">Inalis ang lahat ng mga cookie</string>
<string name="chapters_checking_progress">Sinusuri ang mga bagong kabanata: %1$d ng %2$d</string>
<string name="clear_feed">I-clear ang feed</string>
<string name="check_for_new_chapters">Suriin ang mga bagong kabanata</string>
<string name="sign_in">Mag-sign in</string>
<string name="auth_required">Mag-sign in upang tingnan ang nilalamang ito</string>
<string name="default_s">Default: %s</string>
<string name="next">Susunod</string>
<string name="confirm">Kumpirmahin</string>
<string name="password_length_hint">Ang password ay dapat na 4 na character o higit pa</string>
<string name="search_only_on_s">Maghanap lamang sa %s</string>
<string name="other">Iba pa</string>
<string name="welcome">Maligayang pagdating</string>
<string name="backup_saved">Na-save ang backup</string>
<string name="read_more">Magbasa pa</string>
<string name="text_downloads_holder">Walang aktibong pag-download</string>
<string name="chapter_is_missing">Kulang ang kabanata</string>
<string name="about_feedback">Feedback</string>
<string name="about_feedback_4pda">Paksa sa 4PDA</string>
<string name="auth_not_supported_by">Ang pag-log in sa %s ay hindi suportado</string>
<string name="genres">Mga genre</string>
<string name="state_ongoing">Patuloy</string>
<string name="system_default">Default</string>
<string name="exclude_nsfw_from_history">Hindi isali ang NSFW manga mula sa kasaysayan</string>
<string name="show_pages_numbers">Mga pahinang may bilang</string>
<string name="importing_progress">Ini-import ang manga: %1$d ng %2$d</string>
<string name="screenshots_policy">Patakaran sa screenshot</string>
<string name="screenshots_allow">Payagan</string>
<string name="screenshots_block_all">Palaging i-block</string>
<string name="suggestions">Mga mungkahi</string>
<string name="suggestions_enable">Paganahin ang mga mungkahi</string>
<string name="text_suggestion_holder">Simulan ang pagbabasa ng manga at makakakuha ka ng mga personalized na mungkahi</string>
<string name="exclude_nsfw_from_suggestions">Huwag magmungkahi ng NSFW manga</string>
<string name="enabled">Pinagana</string>
<string name="find_genre">Maghanap ng genre</string>
<string name="onboard_text">Pumili ng mga wika na gusto mong basahin ang manga. Maaari mo itong baguhin sa ibang pagkakataon sa mga setting.</string>
<string name="open_menu">Buksan ang menu</string>
<string name="local_storage">Lokal na storage</string>
<string name="favourites">Mga paborito</string>
<string name="history">Nakaraan</string>
<string name="list_mode">Mode na listahan</string>
<string name="detailed_list">Detalyadong listahan</string>
<string name="grid">Grid</string>
<string name="settings">Mga setting</string>
<string name="remote_sources">Mga remote na source</string>
<string name="loading_">Naglo-load…</string>
<string name="close">Isara</string>
<string name="nothing_found">Walang nahanap</string>
<string name="remove">Tanggalin</string>
<string name="add_new_category">Bagong Kategorya</string>
<string name="enter_category_name">Ipasok ang pangalan ng kategorya</string>
<string name="read">Nabasa</string>
<string name="you_have_not_favourites_yet">Wala pang paborito</string>
<string name="add_to_favourites">I-paborito ito</string>
<string name="add">Idagdag</string>
<string name="save">I-save</string>
<string name="share">Ibahagi</string>
<string name="create_shortcut">Lumikha ng shortcut…</string>
<string name="share_s">Ibahagi sa %s</string>
<string name="search">Maghanap</string>
<string name="search_manga">Maghanap ng manga</string>
<string name="manga_downloading_">Nagda-download…</string>
<string name="processing_">Nagpoproseso…</string>
<string name="download_complete">Na-download</string>
<string name="downloads">Mga download</string>
<string name="by_name">Pangalan</string>
<string name="popular">Sikat</string>
<string name="pages">Mga pahina</string>
<string name="clear_history">I-clear ang kasaysayan</string>
<string name="clear_search_history">I-clear ang kasaysayan ng paghahanap</string>
<string name="network_consumption_warning">Maaari itong maglipat ng maraming data</string>
<string name="new_version_s">Bagong bersyon: %s</string>
<string name="passwords_mismatch">Hindi tumutugma sa mga password</string>
<string name="clear_cookies">I-clear ang mga cookie</string>
<string name="clear_pages_cache">I-clear ang page cache</string>
<string name="save_manga">I-save</string>
<string name="show_notification_app_update">Ipakita ang abiso kung may available na bagong bersyon</string>
<string name="download">I-download</string>
<string name="notifications_settings">Mga setting ng abiso</string>
<string name="notification_sound">Tunog ng abiso</string>
<string name="favourites_categories">Mga paboritong kategorya</string>
<string name="category_delete_confirm">Alisin ang kategoryang \"%s\" sa iyong mga paborito\?
\nMawawala ang lahat ng manga sa loob nito.</string>
<string name="remove_category">Tanggalin</string>
<string name="text_empty_holder_primary">Parang walang laman dito…</string>
<string name="text_categories_holder">Maaari kang gumamit ng mga kategorya upang ayusin ang iyong mga paborito. Pindutin ang «+» upang lumikha ng kategorya</string>
<string name="text_history_holder_secondary">Hanapin kung ano ang babasahin sa side menu.</string>
<string name="text_shelf_holder_secondary">Hanapin kung ano ang babasahin sa seksyong «Mag-explore»</string>
<string name="recent_manga">Kamakailan</string>
<string name="manga_save_location">Folder para sa mga download</string>
<string name="save_page">I-save ang pahina</string>
<string name="_s_deleted_from_local_storage">Natanggal ang \"%s\" sa lokal na storage</string>
<string name="history_is_empty">Wala pang kasaysayan</string>
<string name="wait_for_loading_finish">Hintaying matapos ang paglo-load…</string>
<string name="text_clear_history_prompt">Permanenteng i-clear ang lahat ng kasaysayan ng pagbabasa\?</string>
<string name="dont_check">Huwag suriin</string>
<string name="repeat_password">Ulitin ang password</string>
<string name="protect_application">Protektahan ang app</string>
<string name="wrong_password">Maling password</string>
<string name="app_version">Bersyon %s</string>
<string name="scale_mode">Mode ng scale</string>
<string name="no_update_available">Walang available na update</string>
<string name="reverse">Baliktarin</string>
<string name="group">Grupo</string>
<string name="silent">Tahimik</string>
<string name="zoom_mode_fit_width">Pagkasyahin sa lapad</string>
<string name="black_dark_theme">Itim</string>
<string name="create_backup">Lumikha ng data backup</string>
<string name="restore_backup">Ibalik mula sa backup</string>
<string name="data_restored_success">Naibalik ang lahat ng data</string>
<string name="data_restored_with_errors">Ang data ay naibalik, ngunit may mga error</string>
<string name="reader_mode_hint">Ang napiling pagsasaayos ay maaalala para sa manga na ito</string>
<string name="about_app_translation_summary">Isalin ang app na ito</string>
<string name="auth_complete">Awtorisado na</string>
<string name="captcha_required">Kinakailangan ang CAPTCHA</string>
<string name="text_clear_updates_feed_prompt">I-clear nang permanente ang lahat ng update history\?</string>
<string name="_and_x_more">…at %1$d higit pa</string>
<string name="protect_application_subtitle">Maglagay ng password para simulan ang app</string>
<string name="tracker_warning">Ang ilang device ay may iba\'t ibang gawi ng system, na maaaring masira ang mga gawain sa background.</string>
<string name="queued">Nakapila na</string>
<string name="chapter_is_missing_text">I-download o basahin ang nawawalang kabanata online.</string>
<string name="text_clear_cookies_prompt">Mala-log out ka mula sa lahat ng source</string>
<string name="state_finished">Tapos na</string>
<string name="text_clear_search_history_prompt">Alisin ang lahat ng kamakailang query sa paghahanap nang permanente\?</string>
<string name="about_app_translation">Pagsasalin</string>
<string name="error_empty_name">Kailangan mong maglagay ng pangalan</string>
<string name="date_format">Format ng petsa</string>
<string name="dynamic_theme">Dynamic na tema</string>
<string name="dynamic_theme_summary">Naglalapat ng temang ginawa sa scheme ng kulay ng iyong wallpaper</string>
<string name="screenshots_block_nsfw">I-block sa NSFW</string>
<string name="suggestions_summary">Magmungkahi ng manga batay sa iyong mga kagustuhan</string>
<string name="suggestions_info">Ang lahat ng data ay sinusuri nang lokal sa aparatong ito. Walang paglipat ng iyong personal na data sa anumang mga serbisyo</string>
<string name="disabled">Hindi pinagana</string>
<string name="filter_load_error">Hindi ma-load ang listahan ng mga genre</string>
<string name="reset_filter">I-reset ang filter</string>
<string name="text_feed_holder">Ang mga bagong kabanata ng iyong binabasa ay makikita dito</string>
<string name="rotate_screen">I-rotate ang screen</string>
<string name="zoom_mode_fit_height">Pagkasyahin sa tangkad</string>
<string name="never">Hindi kailanman</string>
<string name="only_using_wifi">Sa Wi-Fi lang</string>
<string name="close_menu">Isara ang menu</string>
<string name="computing_">Nagco-compute…</string>
<string name="chapter_d_of_d">Kabanata %1$d ng %2$d</string>
<string name="try_again">Subukan ulit</string>
<string name="sort_order">Pag-aayos ng order</string>
<string name="clear">I-clear</string>
<string name="_s_removed_from_history">Natanggal ang \"%s\" sa kasaysayan</string>
<string name="taps_on_edges">Mga taps ng gilid</string>
<string name="enabled_sources">Mga ginamit na source</string>
<string name="available_sources">Magagamit na mga source</string>
<string name="always">Lagi na lang</string>
<string name="preload_pages">I-preload ang mga pahina</string>
<string name="logged_in_as">Naka-log in bilang %s</string>
<string name="various_languages">Iba\'t ibang wika</string>
<string name="search_chapters">Maghanap ng kabanata</string>
<string name="percent_string_pattern">%1$s%%</string>
<string name="appearance">Hitsura</string>
<string name="suggestions_excluded_genres">Hindi isali ang mga genre</string>
<string name="suggestions_excluded_genres_summary">Tukuyin ang mga genre na hindi mo nais na makita sa mga mungkahi</string>
<string name="removal_completed">Nakumpleto na ang pagtanggal</string>
<string name="download_slowdown_summary">Tumutulong na maiwasan ang pag-block ng iyong IP address</string>
<string name="local_manga_processing">Naka-save na pagproseso ng manga</string>
<string name="account_already_exists">Mayroon nang account</string>
<string name="back">Bumalik</string>
<string name="sync">Pag-synchronize</string>
<string name="email_enter_hint">Ilagay ang iyong email upang magpatuloy</string>
<string name="hide">Itago</string>
<string name="new_sources_text">May mga bagong source ng manga</string>
<string name="show_notification_new_chapters_off">Hindi ka makakatanggap ng mga abiso ngunit ang mga bagong kabanata ay iha-highlight sa mga listahan</string>
<string name="notifications_enable">Paganahin ang mga abiso</string>
<string name="edit_category">Ayusin ang kategorya</string>
<string name="tracking">Tina-track</string>
<string name="empty_favourite_categories">Walang mga paboritong kategorya</string>
<string name="logout">Mag-log out</string>
<string name="bookmark_add">Magdagdag ng bookmark</string>
<string name="bookmark_removed">Tinanggal ang bookmark</string>
<string name="removed_from_history">Inalis sa kasaysayan</string>
<string name="dns_over_https">DNS sa HTTPS</string>
<string name="default_mode">Default na mode</string>
<string name="detect_reader_mode">Automatikong matukoy ang reader mode</string>
<string name="crash_text">May nangyaring mali. Mangyaring magsumite ng isang bug report sa mga developer upang matulungan kaming ayusin ito.</string>
<string name="send">Ipadala</string>
<string name="status_re_reading">Muling pagbabasa</string>
<string name="status_dropped">Binitawan</string>
<string name="appwidget_shelf_description">Manga mula sa iyong mga paborito</string>
<string name="appwidget_recent_description">Ang iyong kamakailang nabasa na manga</string>
<string name="data_deletion">Pagtanggal ng data</string>
<string name="show_reading_indicators_summary">Ipakita ang porsyento na nabasa sa kasaysayan at mga paborito</string>
<string name="show_all">Ipakita lahat</string>
<string name="select_range">Pumili ng saklaw</string>
<string name="clear_all_history">I-clear ang lahat ng kasaysayan</string>
<string name="no_bookmarks_summary">Maaari kang lumikha ng bookmark habang nagbabasa ng manga</string>
<string name="bookmarks_removed">Tinanggal ang mga bookmark</string>
<string name="random">Random</string>
<string name="no_manga_sources">Walang mga source ng manga</string>
<string name="no_manga_sources_text">Paganahin ang mga source ng manga upang basahin ang manga online</string>
<string name="reorder">Ayusin muli</string>
<string name="empty">Walang laman</string>
<string name="changelog">Changelog</string>
<string name="confirm_exit">Pindutin muli ang Bumalik upang lumabas</string>
<string name="exit_confirmation_summary">Pindutin ang Bumalik nang dalawang beses upang lumabas sa app</string>
<string name="exit_confirmation">Pagkumpirma ng paglabas</string>
<string name="saved_manga">Na-save na manga</string>
<string name="explore">Mag-Explore</string>
<string name="other_cache">Iba pang cache</string>
<string name="storage_usage">Paggamit ng storage</string>
<string name="available">Magagamit na</string>
<string name="memory_usage_pattern">%s - %s</string>
<string name="removed_from_favourites">Inalis sa mga paborito</string>
<string name="removed_from_s">Inalis mula sa \"%s\"</string>
<string name="options">Mga pagpipilian</string>
<string name="downloading_manga">Nagda-download ng manga</string>
<string name="incognito_mode">Incognito mode</string>
<string name="app_update_available_s">Magagamit ang pag update ng application: %s</string>
<string name="no_chapters">Walang mga kabanata</string>
<string name="automatic_scroll">Awtomatikong pag-scroll</string>
<string name="reader_info_pattern">Ch. %1$d/%2$d Pg. %3$d/%4$d</string>
<string name="reader_info_bar">Ipakita ang information bar sa pagbasa</string>
<string name="comics_archive">Archive ng mga comics</string>
<string name="folder_with_images">Folder na may mga larawan</string>
<string name="import_completed">Nakumpleto na ang pag-import</string>
<string name="import_will_start_soon">Magsisimula na ang pag-import</string>
<string name="feed">Feed</string>
<string name="history_shortcuts_summary">Gawing magagamit ang kamakailang manga sa pamamagitan ng mahabang pagpindot sa icon ng application</string>
<string name="history_shortcuts">Ipakita ang mga kamakailang manga shortcut</string>
<string name="reader_control_ltr">Ergonomic na kontrol sa mambabasa</string>
<string name="color_correction">Pagwawasto ng kulay</string>
<string name="brightness">Liwanag</string>
<string name="contrast">Kaibahan</string>
<string name="text_unsaved_changes_prompt">I-save o kalimutan ang mga hindi na-save na pagbabago\?</string>
<string name="discard">Kalimutan</string>
<string name="error_no_space_left">Walang natitirang espasyo sa device</string>
<string name="webtoon_zoom">Pag-zoom sa webtoon</string>
<string name="different_languages">Iba\'t ibang wika</string>
<string name="server_error">Server side error (%1$d). Subukang muli mamaya</string>
<string name="clear_new_chapters_counters">I-clear din ang impormasyon tungkol sa mga bagong kabanata</string>
<string name="prefetch_content">Preloading ng nilalaman</string>
<string name="mark_as_current">Markahan bilang kasalukuyan</string>
<string name="language">Wika</string>
<string name="share_logs">Ibahagi ang mga log</string>
<string name="show_suspicious_content">Magpakita ng kahina-hinalang nilalaman</string>
<string name="theme_name_dynamic">Dynamic</string>
<string name="show_in_grid_view">Ipakita sa grid view</string>
<string name="theme_name_asuka">Asuka</string>
<string name="theme_name_mion">Mion</string>
<string name="theme_name_rikka">Rikka</string>
<string name="theme_name_sakura">Sakura</string>
<string name="theme_name_mamimi">Mamimi</string>
<string name="theme_name_kanade">Kanade</string>
<string name="nothing_here">Wala naman dito</string>
<string name="services">Mga serbisyo</string>
<string name="allow_unstable_updates">Payagan ang mga hindi stable na update</string>
<string name="show_reading_indicators">Ipakita ang mga tagapagpahiwatig ng progress ng pagbabasa</string>
<string name="exclude_nsfw_from_history_summary">Manga na minarkahan bilang NSFW ay hindi kailanman idadagdag sa kasaysayan at ang iyong progress ay hindi mase-save</string>
<string name="clear_cookies_summary">Maaaring makatulong sa kaso ng ilang mga isyu. Ang lahat ng pahintulot ay mawawalan ng bisa</string>
<string name="invalid_domain_message">Imbalidong domain</string>
<string name="last_2_hours">Huling 2 oras</string>
<string name="history_cleared">Nabura ang kasaysayan</string>
<string name="manage">Pamahalaan</string>
<string name="no_bookmarks_yet">Wala pang bookmark</string>
<string name="nsfw">18+</string>
<string name="not_found_404">Hindi natagpuan o inalis ang nilalaman</string>
<string name="enable_logging_summary">Magtala ng ilang pagkilos para sa mga layunin ng pag-debug</string>
<string name="text_delete_local_manga_batch">Permanenteng tanggalin ang mga napiling item sa device\?</string>
<string name="chapters_empty">Walang mga kabanata sa manga na ito</string>
<string name="suggestions_updating">Nag-a-update ang mga mungkahi</string>
<string name="content">Nilalaman</string>
<string name="batch_manga_save_confirm">I-download ang lahat ng napiling manga at ang mga kabanata nito\? Maaari itong kumonsumo ng maraming trapiko at storage.</string>
<string name="parallel_downloads">Mga parallel na pag-download</string>
<string name="download_slowdown">Pagbagal ng pag-download</string>
<string name="chapters_will_removed_background">Tatanggalin ang mga chapters sa background. Maaari itong tumagal ng ilang oras</string>
<string name="canceled">Kinansela</string>
<string name="sync_title">I-sync ang iyong data</string>
<string name="check_new_chapters_title">Tingnan ang mga bagong kabanata at ipaalam ang tungkol dito</string>
<string name="name">Pangalan</string>
<string name="edit">I-edit</string>
<string name="bookmark_remove">Tanggalin ang bookmark</string>
<string name="show_notification_new_chapters_on">Makakatanggap ka ng mga abiso tungkol sa mga update ng manga na iyong binabasa</string>
<string name="undo">Mag-undo</string>
<string name="status_reading">Nagbabasa</string>
<string name="pages_cache">Cache ng mga pahina</string>
<string name="bookmarks">Mga bookmark</string>
<string name="categories_delete_confirm">Sigurado ka bang gusto mong tanggalin ang mga napiling paboritong kategorya\?
\nAng lahat ng manga sa loob nito ay mawawala at hindi na ito mababawi.</string>
<string name="bookmark_added">Idinagdag ang bookmark</string>
<string name="detect_reader_mode_summary">Awtomatikong matukoy kung ang manga ay webtoon</string>
<string name="disable_battery_optimization">Huwag paganahin ang pag-optimize ng baterya</string>
<string name="disable_battery_optimization_summary">Tumutulong sa mga pagsusuri sa mga update sa background</string>
<string name="status_planned">Nakaplano</string>
<string name="status_completed">Nakumpleto na</string>
<string name="status_on_hold">Naka-hold</string>
<string name="disable_all">Huwag paganahin ang lahat</string>
<string name="use_fingerprint">Gumamit ng fingerprint kung magagamit</string>
<string name="report">Ulat</string>
<string name="enter_email_text">Ilagay ang iyong email upang magpatuloy</string>
<string name="reset">I-reset</string>
<string name="allow_unstable_updates_summary">Magmungkahi ng mga update sa mga beta na bersyon ng app</string>
<string name="network_unavailable">Hindi magagamit ang network</string>
<string name="network_unavailable_hint">I-on ang Wi-Fi o mobile network para magbasa ng manga online</string>
<string name="off_short">Naka-off</string>
<string name="seconds_pattern">%ss</string>
<string name="reader_control_ltr_summary">Mag-tap sa kanang gilid o ang pagpindot sa kanang key ay palaging lilipat sa susunod na pahina</string>
<string name="reader_slider">Ipakita ang slider ng paglipat ng pahina</string>
<string name="manga_error_description_pattern">Mga detalye ng error:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Subukang &lt;a href=%2$s&gt;buksan ang manga sa isang web browser&lt;/a&gt; upang matiyak na magagamit ito sa source&lt;br&gt;nito 2. Kung magagamit ito, magpadala ng isang ulat ng error sa mga developer.</string>
<string name="enable_logging">Paganahin ang pag-log</string>
<string name="source_disabled">Hindi pinagana ang source</string>
<string name="importing_manga">Pag-import ng manga</string>
<string name="import_completed_hint">Maaari mong tanggalin ang orihinal na file mula sa storage upang makatipid ng espasyo</string>
<string name="color_correction_hint">Ang napiling mga setting ng kulay ay matatandaan para sa manga na ito</string>
<string name="webtoon_zoom_summary">Payagan ang pag-zoom in/zoom out na galaw sa webtoon mode (beta)</string>
<string name="compact">Compact</string>
<string name="scrobbling_empty_hint">Upang subaybayan ang pag unlad ng pagbabasa, piliin ang Menu → Track sa screen ng mga detalye ng manga.</string>
<string name="download_started">Nagsimula na ang pag-download</string>
<string name="color_theme">Scheme ng kulay</string>
<string name="theme_name_miku">Miku</string>
</resources>

View File

@@ -411,4 +411,14 @@
<string name="scrobbling_empty_hint">Pour suivre la progression de la lecture, sélectionnez Menu → Suivre sur l\'écran des détails du manga.</string> <string name="scrobbling_empty_hint">Pour suivre la progression de la lecture, sélectionnez Menu → Suivre sur l\'écran des détails du manga.</string>
<string name="services">Prestations de service</string> <string name="services">Prestations de service</string>
<string name="nothing_here">Il n\'y a rien ici</string> <string name="nothing_here">Il n\'y a rien ici</string>
<string name="theme_name_sakura">Sakura</string>
<string name="theme_name_rikka">Rikka</string>
<string name="theme_name_miku">Miku</string>
<string name="theme_name_asuka">Asuka</string>
<string name="theme_name_mion">Mion</string>
<string name="theme_name_mamimi">Mamimi</string>
<string name="allow_unstable_updates">Autoriser les mises à jour instables</string>
<string name="download_started">Téléchargement commencé</string>
<string name="theme_name_kanade">Kanade</string>
<string name="allow_unstable_updates_summary">Proposer des mises à jour des versions bêta de l\'application</string>
</resources> </resources>

View File

@@ -5,4 +5,5 @@
<bool name="light_navigation_bar">false</bool> <bool name="light_navigation_bar">false</bool>
<bool name="com_samsung_android_icon_container_has_icon_container">true</bool> <bool name="com_samsung_android_icon_container_has_icon_container">true</bool>
<bool name="is_color_themes_available">false</bool> <bool name="is_color_themes_available">false</bool>
<bool name="is_sync_enabled">false</bool>
</resources> </resources>

View File

@@ -86,7 +86,6 @@
<style name="Widget.Kotatsu.SearchView" parent="@style/Widget.AppCompat.SearchView"> <style name="Widget.Kotatsu.SearchView" parent="@style/Widget.AppCompat.SearchView">
<item name="iconifiedByDefault">false</item> <item name="iconifiedByDefault">false</item>
<item name="searchIcon">@null</item> <item name="searchIcon">@null</item>
<item name="hintTextAppearance">?textAppearanceBodyMedium</item>
<item name="queryBackground">@null</item> <item name="queryBackground">@null</item>
<item name="android:textColorHint">?attr/colorControlNormal</item> <item name="android:textColorHint">?attr/colorControlNormal</item>
<item name="android:textSize">18sp</item> <item name="android:textSize">18sp</item>
@@ -164,9 +163,10 @@
<item name="iconGravity">start</item> <item name="iconGravity">start</item>
<item name="android:insetTop">2dp</item> <item name="android:insetTop">2dp</item>
<item name="android:insetBottom">2dp</item> <item name="android:insetBottom">2dp</item>
<item name="iconTint">?attr/colorSecondary</item> <item name="iconTint">?attr/colorPrimaryDark</item>
<item name="android:gravity">start|center_vertical</item> <item name="android:gravity">start|center_vertical</item>
<item name="android:textAppearance">?textAppearanceButton</item> <item name="android:textAppearance">?textAppearanceButton</item>
<item name="backgroundTint">@color/colored_button</item>
</style> </style>
<style name="Widget.Kotatsu.TextView.Indicator" parent="Widget.MaterialComponents.TextView"> <style name="Widget.Kotatsu.TextView.Indicator" parent="Widget.MaterialComponents.TextView">

View File

@@ -4,6 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference <Preference
android:enabled="@bool/is_sync_enabled"
android:key="sync" android:key="sync"
android:persistent="false" android:persistent="false"
android:summary="@string/sync_title" android:summary="@string/sync_title"