Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f208ad15 | ||
|
|
c6983d794c | ||
|
|
8228153c83 | ||
|
|
844bd13a07 | ||
|
|
60a5620134 | ||
|
|
dd09a39077 | ||
|
|
1511bd3279 | ||
|
|
259c335607 | ||
|
|
86367b6d3b | ||
|
|
19b893738d | ||
|
|
d817ae0394 |
@@ -15,8 +15,8 @@ android {
|
|||||||
applicationId 'org.koitharu.kotatsu'
|
applicationId 'org.koitharu.kotatsu'
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 553
|
versionCode 554
|
||||||
versionName '5.2.1'
|
versionName '5.2.2'
|
||||||
generatedDensities = []
|
generatedDensities = []
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ afterEvaluate {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
//noinspection GradleDependency
|
//noinspection GradleDependency
|
||||||
implementation('com.github.KotatsuApp:kotatsu-parsers:f732582d55') {
|
implementation('com.github.KotatsuApp:kotatsu-parsers:86a82970fc') {
|
||||||
exclude group: 'org.json', module: 'json'
|
exclude group: 'org.json', module: 'json'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +104,7 @@ dependencies {
|
|||||||
//noinspection LifecycleAnnotationProcessorWithJava8
|
//noinspection LifecycleAnnotationProcessorWithJava8
|
||||||
kapt 'androidx.lifecycle:lifecycle-compiler:2.6.1'
|
kapt 'androidx.lifecycle:lifecycle-compiler:2.6.1'
|
||||||
|
|
||||||
|
// TODO https://issuetracker.google.com/issues/254846063
|
||||||
implementation 'androidx.work:work-runtime-ktx:2.8.1'
|
implementation 'androidx.work:work-runtime-ktx:2.8.1'
|
||||||
//noinspection GradleDependency
|
//noinspection GradleDependency
|
||||||
implementation('com.google.guava:guava:32.0.0-android') {
|
implementation('com.google.guava:guava:32.0.0-android') {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
|||||||
import org.koitharu.kotatsu.local.data.PagesCache
|
import org.koitharu.kotatsu.local.data.PagesCache
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
import org.koitharu.kotatsu.reader.domain.PageLoader
|
import org.koitharu.kotatsu.reader.domain.PageLoader
|
||||||
|
import org.koitharu.kotatsu.settings.work.WorkScheduleManager
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
@@ -51,6 +52,9 @@ class KotatsuApp : Application(), Configuration.Provider {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var appValidator: AppValidator
|
lateinit var appValidator: AppValidator
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var workScheduleManager: WorkScheduleManager
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
ACRA.errorReporter.putCustomData("isOriginalApp", appValidator.isOriginalApp.toString())
|
ACRA.errorReporter.putCustomData("isOriginalApp", appValidator.isOriginalApp.toString())
|
||||||
@@ -63,6 +67,7 @@ class KotatsuApp : Application(), Configuration.Provider {
|
|||||||
processLifecycleScope.launch(Dispatchers.Default) {
|
processLifecycleScope.launch(Dispatchers.Default) {
|
||||||
setupDatabaseObservers()
|
setupDatabaseObservers()
|
||||||
}
|
}
|
||||||
|
workScheduleManager.init()
|
||||||
WorkServiceStopHelper(applicationContext).setup()
|
WorkServiceStopHelper(applicationContext).setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ private const val SERVER_CLOUDFLARE = "cloudflare"
|
|||||||
class CloudFlareInterceptor : Interceptor {
|
class CloudFlareInterceptor : Interceptor {
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
val request = chain.request()
|
val response = chain.proceed(chain.request())
|
||||||
val response = chain.proceed(request)
|
|
||||||
if (response.code == HTTP_FORBIDDEN || response.code == HTTP_UNAVAILABLE) {
|
if (response.code == HTTP_FORBIDDEN || response.code == HTTP_UNAVAILABLE) {
|
||||||
if (response.header(HEADER_SERVER)?.startsWith(SERVER_CLOUDFLARE) == true) {
|
if (response.header(HEADER_SERVER)?.startsWith(SERVER_CLOUDFLARE) == true) {
|
||||||
|
val request = response.request
|
||||||
response.closeQuietly()
|
response.closeQuietly()
|
||||||
throw CloudFlareProtectedException(
|
throw CloudFlareProtectedException(
|
||||||
url = response.request.url.toString(),
|
url = request.url.toString(),
|
||||||
headers = request.headers,
|
headers = request.headers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ class WorkManagerHelper(
|
|||||||
return workManagerImpl.getWorkInfoById(id).await()
|
return workManagerImpl.getWorkInfoById(id).await()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getUniqueWorkInfoByName(name: String): List<WorkInfo> {
|
||||||
|
return workManagerImpl.getWorkInfosForUniqueWork(name).await().orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun updateWork(request: WorkRequest): WorkManager.UpdateResult {
|
suspend fun updateWork(request: WorkRequest): WorkManager.UpdateResult {
|
||||||
return workManagerImpl.updateWork(request).await()
|
return workManagerImpl.updateWork(request).await()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.core.net.toUri
|
|||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||||
import org.koitharu.kotatsu.core.util.ShareHelper
|
import org.koitharu.kotatsu.core.util.ShareHelper
|
||||||
@@ -17,12 +18,17 @@ import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
|||||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||||
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
||||||
|
import org.koitharu.kotatsu.filter.ui.FilterOwner
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterSheetFragment
|
import org.koitharu.kotatsu.filter.ui.FilterSheetFragment
|
||||||
|
import org.koitharu.kotatsu.filter.ui.model.FilterHeaderModel
|
||||||
|
import org.koitharu.kotatsu.filter.ui.model.FilterItem
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.remotelist.ui.RemoteListFragment
|
import org.koitharu.kotatsu.remotelist.ui.RemoteListFragment
|
||||||
|
|
||||||
class LocalListFragment : MangaListFragment() {
|
class LocalListFragment : MangaListFragment(), FilterOwner {
|
||||||
|
|
||||||
override val viewModel by viewModels<LocalListViewModel>()
|
override val viewModel by viewModels<LocalListViewModel>()
|
||||||
|
|
||||||
@@ -65,6 +71,24 @@ class LocalListFragment : MangaListFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val filterItems: StateFlow<List<ListModel>>
|
||||||
|
get() = viewModel.filterItems
|
||||||
|
|
||||||
|
override val header: StateFlow<FilterHeaderModel>
|
||||||
|
get() = viewModel.header
|
||||||
|
|
||||||
|
override fun applyFilter(tags: Set<MangaTag>) {
|
||||||
|
viewModel.applyFilter(tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSortItemClick(item: FilterItem.Sort) {
|
||||||
|
viewModel.onSortItemClick(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTagItemClick(item: FilterItem.Tag) {
|
||||||
|
viewModel.onTagItemClick(item)
|
||||||
|
}
|
||||||
|
|
||||||
private fun showDeletionConfirm(ids: Set<Long>, mode: ActionMode) {
|
private fun showDeletionConfirm(ids: Set<Long>, mode: ActionMode) {
|
||||||
MaterialAlertDialogBuilder(context ?: return)
|
MaterialAlertDialogBuilder(context ?: return)
|
||||||
.setTitle(R.string.delete_manga)
|
.setTitle(R.string.delete_manga)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import androidx.work.ExistingWorkPolicy
|
|||||||
import androidx.work.OneTimeWorkRequestBuilder
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.await
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
||||||
@@ -33,7 +34,7 @@ class LocalStorageCleanupWorker @AssistedInject constructor(
|
|||||||
|
|
||||||
private const val TAG = "cleanup"
|
private const val TAG = "cleanup"
|
||||||
|
|
||||||
fun enqueue(context: Context) {
|
suspend fun enqueue(context: Context) {
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiresBatteryNotLow(true)
|
.setRequiresBatteryNotLow(true)
|
||||||
.build()
|
.build()
|
||||||
@@ -42,7 +43,7 @@ class LocalStorageCleanupWorker @AssistedInject constructor(
|
|||||||
.addTag(TAG)
|
.addTag(TAG)
|
||||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.MINUTES)
|
.setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.MINUTES)
|
||||||
.build()
|
.build()
|
||||||
WorkManager.getInstance(context).enqueueUniqueWork(TAG, ExistingWorkPolicy.KEEP, request)
|
WorkManager.getInstance(context).enqueueUniqueWork(TAG, ExistingWorkPolicy.KEEP, request).await()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,8 +69,6 @@ import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionViewModel
|
|||||||
import org.koitharu.kotatsu.settings.newsources.NewSourcesDialogFragment
|
import org.koitharu.kotatsu.settings.newsources.NewSourcesDialogFragment
|
||||||
import org.koitharu.kotatsu.settings.onboard.OnboardDialogFragment
|
import org.koitharu.kotatsu.settings.onboard.OnboardDialogFragment
|
||||||
import org.koitharu.kotatsu.shelf.ui.ShelfFragment
|
import org.koitharu.kotatsu.shelf.ui.ShelfFragment
|
||||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
|
||||||
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.google.android.material.R as materialR
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
@@ -321,8 +319,6 @@ class MainActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
TrackWorker.setup(applicationContext)
|
|
||||||
SuggestionsWorker.setup(applicationContext)
|
|
||||||
LocalStorageCleanupWorker.enqueue(applicationContext)
|
LocalStorageCleanupWorker.enqueue(applicationContext)
|
||||||
}
|
}
|
||||||
withResumed {
|
withResumed {
|
||||||
|
|||||||
@@ -10,20 +10,26 @@ import androidx.appcompat.widget.SearchView
|
|||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||||
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
||||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||||
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
||||||
|
import org.koitharu.kotatsu.filter.ui.FilterOwner
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterSheetFragment
|
import org.koitharu.kotatsu.filter.ui.FilterSheetFragment
|
||||||
|
import org.koitharu.kotatsu.filter.ui.model.FilterHeaderModel
|
||||||
|
import org.koitharu.kotatsu.filter.ui.model.FilterItem
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.search.ui.SearchActivity
|
import org.koitharu.kotatsu.search.ui.SearchActivity
|
||||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class RemoteListFragment : MangaListFragment() {
|
class RemoteListFragment : MangaListFragment(), FilterOwner {
|
||||||
|
|
||||||
override val viewModel by viewModels<RemoteListViewModel>()
|
override val viewModel by viewModels<RemoteListViewModel>()
|
||||||
|
|
||||||
@@ -49,6 +55,24 @@ class RemoteListFragment : MangaListFragment() {
|
|||||||
viewModel.resetFilter()
|
viewModel.resetFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val filterItems: StateFlow<List<ListModel>>
|
||||||
|
get() = viewModel.filterItems
|
||||||
|
|
||||||
|
override val header: StateFlow<FilterHeaderModel>
|
||||||
|
get() = viewModel.header
|
||||||
|
|
||||||
|
override fun applyFilter(tags: Set<MangaTag>) {
|
||||||
|
viewModel.applyFilter(tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSortItemClick(item: FilterItem.Sort) {
|
||||||
|
viewModel.onSortItemClick(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTagItemClick(item: FilterItem.Tag) {
|
||||||
|
viewModel.onTagItemClick(item)
|
||||||
|
}
|
||||||
|
|
||||||
private inner class RemoteListMenuProvider :
|
private inner class RemoteListMenuProvider :
|
||||||
MenuProvider,
|
MenuProvider,
|
||||||
SearchView.OnQueryTextListener,
|
SearchView.OnQueryTextListener,
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import org.koitharu.kotatsu.databinding.ActivityMangaListBinding
|
|||||||
import org.koitharu.kotatsu.filter.ui.FilterHeaderFragment
|
import org.koitharu.kotatsu.filter.ui.FilterHeaderFragment
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterOwner
|
import org.koitharu.kotatsu.filter.ui.FilterOwner
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterSheetFragment
|
import org.koitharu.kotatsu.filter.ui.FilterSheetFragment
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
|
||||||
import org.koitharu.kotatsu.local.ui.LocalListFragment
|
import org.koitharu.kotatsu.local.ui.LocalListFragment
|
||||||
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
@@ -74,7 +73,10 @@ class MangaListActivity :
|
|||||||
|
|
||||||
private fun initList(source: MangaSource, tags: Set<MangaTag>?) {
|
private fun initList(source: MangaSource, tags: Set<MangaTag>?) {
|
||||||
val fm = supportFragmentManager
|
val fm = supportFragmentManager
|
||||||
if (fm.findFragmentById(R.id.container) == null) {
|
val existingFragment = fm.findFragmentById(R.id.container)
|
||||||
|
if (existingFragment is FilterOwner) {
|
||||||
|
initFilter(existingFragment)
|
||||||
|
} else {
|
||||||
fm.commit {
|
fm.commit {
|
||||||
setReorderingAllowed(true)
|
setReorderingAllowed(true)
|
||||||
val fragment = if (source == MangaSource.LOCAL) {
|
val fragment = if (source == MangaSource.LOCAL) {
|
||||||
@@ -83,17 +85,15 @@ class MangaListActivity :
|
|||||||
RemoteListFragment.newInstance(source)
|
RemoteListFragment.newInstance(source)
|
||||||
}
|
}
|
||||||
replace(R.id.container, fragment)
|
replace(R.id.container, fragment)
|
||||||
runOnCommit { initFilter() }
|
runOnCommit { initFilter(fragment) }
|
||||||
if (!tags.isNullOrEmpty() && fragment is RemoteListFragment) {
|
if (!tags.isNullOrEmpty()) {
|
||||||
runOnCommit(ApplyFilterRunnable(fragment, tags))
|
runOnCommit(ApplyFilterRunnable(fragment, tags))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
initFilter()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initFilter() {
|
private fun initFilter(filterOwner: FilterOwner) {
|
||||||
if (viewBinding.containerFilter != null) {
|
if (viewBinding.containerFilter != null) {
|
||||||
if (supportFragmentManager.findFragmentById(R.id.container_filter) == null) {
|
if (supportFragmentManager.findFragmentById(R.id.container_filter) == null) {
|
||||||
supportFragmentManager.commit {
|
supportFragmentManager.commit {
|
||||||
@@ -109,7 +109,6 @@ class MangaListActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val filterOwner = FilterOwner.from(this)
|
|
||||||
val chipSort = viewBinding.chipSort
|
val chipSort = viewBinding.chipSort
|
||||||
if (chipSort != null) {
|
if (chipSort != null) {
|
||||||
filterOwner.header.observe(this) {
|
filterOwner.header.observe(this) {
|
||||||
@@ -126,14 +125,12 @@ class MangaListActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ApplyFilterRunnable(
|
private class ApplyFilterRunnable(
|
||||||
private val fragment: MangaListFragment,
|
private val filterOwner: FilterOwner,
|
||||||
private val tags: Set<MangaTag>,
|
private val tags: Set<MangaTag>,
|
||||||
) : Runnable {
|
) : Runnable {
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
checkNotNull(FilterOwner.find(fragment)) {
|
filterOwner.applyFilter(tags)
|
||||||
"Cannot find FilterOwner"
|
|
||||||
}.applyFilter(tags)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.work
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
|
||||||
|
interface PeriodicWorkScheduler {
|
||||||
|
|
||||||
|
suspend fun schedule(context: Context)
|
||||||
|
|
||||||
|
suspend fun unschedule(context: Context)
|
||||||
|
|
||||||
|
suspend fun isScheduled(context: Context): Boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.work
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.processLifecycleScope
|
||||||
|
import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
||||||
|
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class WorkScheduleManager @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val settings: AppSettings,
|
||||||
|
) : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
|
when (key) {
|
||||||
|
AppSettings.KEY_TRACKER_ENABLED -> updateWorker(TrackWorker, settings.isTrackerEnabled)
|
||||||
|
AppSettings.KEY_SUGGESTIONS -> updateWorker(SuggestionsWorker, settings.isSuggestionsEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
settings.subscribe(this)
|
||||||
|
processLifecycleScope.launch(Dispatchers.Default) {
|
||||||
|
updateWorkerImpl(TrackWorker, settings.isTrackerEnabled)
|
||||||
|
updateWorkerImpl(SuggestionsWorker, settings.isSuggestionsEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateWorker(scheduler: PeriodicWorkScheduler, isEnabled: Boolean) {
|
||||||
|
processLifecycleScope.launch(Dispatchers.Default) {
|
||||||
|
updateWorkerImpl(scheduler, isEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun updateWorkerImpl(scheduler: PeriodicWorkScheduler, isEnabled: Boolean) {
|
||||||
|
if (scheduler.isScheduled(context) != isEnabled) {
|
||||||
|
if (isEnabled) {
|
||||||
|
scheduler.schedule(context)
|
||||||
|
} else {
|
||||||
|
scheduler.unschedule(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ import androidx.work.OutOfQuotaPolicy
|
|||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.await
|
||||||
import androidx.work.workDataOf
|
import androidx.work.workDataOf
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
@@ -38,6 +39,7 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.core.model.distinctById
|
import org.koitharu.kotatsu.core.model.distinctById
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.core.util.WorkManagerHelper
|
||||||
import org.koitharu.kotatsu.core.util.ext.almostEquals
|
import org.koitharu.kotatsu.core.util.ext.almostEquals
|
||||||
import org.koitharu.kotatsu.core.util.ext.asArrayList
|
import org.koitharu.kotatsu.core.util.ext.asArrayList
|
||||||
import org.koitharu.kotatsu.core.util.ext.flatten
|
import org.koitharu.kotatsu.core.util.ext.flatten
|
||||||
@@ -55,6 +57,7 @@ import org.koitharu.kotatsu.parsers.model.MangaTag
|
|||||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity.IntentBuilder
|
import org.koitharu.kotatsu.reader.ui.ReaderActivity.IntentBuilder
|
||||||
|
import org.koitharu.kotatsu.settings.work.PeriodicWorkScheduler
|
||||||
import org.koitharu.kotatsu.suggestions.domain.MangaSuggestion
|
import org.koitharu.kotatsu.suggestions.domain.MangaSuggestion
|
||||||
import org.koitharu.kotatsu.suggestions.domain.SuggestionRepository
|
import org.koitharu.kotatsu.suggestions.domain.SuggestionRepository
|
||||||
import org.koitharu.kotatsu.suggestions.domain.TagsBlacklist
|
import org.koitharu.kotatsu.suggestions.domain.TagsBlacklist
|
||||||
@@ -75,11 +78,11 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
) : CoroutineWorker(appContext, params) {
|
) : CoroutineWorker(appContext, params) {
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
|
trySetForeground()
|
||||||
if (!appSettings.isSuggestionsEnabled) {
|
if (!appSettings.isSuggestionsEnabled) {
|
||||||
suggestionRepository.clear()
|
suggestionRepository.clear()
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
trySetForeground()
|
|
||||||
val count = doWorkImpl()
|
val count = doWorkImpl()
|
||||||
val outputData = workDataOf(DATA_COUNT to count)
|
val outputData = workDataOf(DATA_COUNT to count)
|
||||||
return Result.success(outputData)
|
return Result.success(outputData)
|
||||||
@@ -303,7 +306,7 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object : PeriodicWorkScheduler {
|
||||||
|
|
||||||
private const val TAG = "suggestions"
|
private const val TAG = "suggestions"
|
||||||
private const val TAG_ONESHOT = "suggestions_oneshot"
|
private const val TAG_ONESHOT = "suggestions_oneshot"
|
||||||
@@ -324,7 +327,7 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
SortOrder.RATING,
|
SortOrder.RATING,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun setup(context: Context) {
|
override suspend fun schedule(context: Context) {
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.UNMETERED)
|
.setRequiredNetworkType(NetworkType.UNMETERED)
|
||||||
.setRequiresBatteryNotLow(true)
|
.setRequiresBatteryNotLow(true)
|
||||||
@@ -336,6 +339,19 @@ class SuggestionsWorker @AssistedInject constructor(
|
|||||||
.build()
|
.build()
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, request)
|
.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, request)
|
||||||
|
.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun unschedule(context: Context) {
|
||||||
|
WorkManager.getInstance(context)
|
||||||
|
.cancelUniqueWork(TAG)
|
||||||
|
.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun isScheduled(context: Context): Boolean {
|
||||||
|
return WorkManagerHelper(WorkManager.getInstance(context))
|
||||||
|
.getUniqueWorkInfoByName(TAG)
|
||||||
|
.any { !it.state.isFinished }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startNow(context: Context) {
|
fun startNow(context: Context) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import androidx.work.WorkInfo
|
|||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.WorkQuery
|
import androidx.work.WorkQuery
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.await
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
@@ -42,12 +43,14 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.core.logs.FileLogger
|
import org.koitharu.kotatsu.core.logs.FileLogger
|
||||||
import org.koitharu.kotatsu.core.logs.TrackerLogger
|
import org.koitharu.kotatsu.core.logs.TrackerLogger
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.core.util.WorkManagerHelper
|
||||||
import org.koitharu.kotatsu.core.util.ext.toBitmapOrNull
|
import org.koitharu.kotatsu.core.util.ext.toBitmapOrNull
|
||||||
import org.koitharu.kotatsu.core.util.ext.trySetForeground
|
import org.koitharu.kotatsu.core.util.ext.trySetForeground
|
||||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||||
|
import org.koitharu.kotatsu.settings.work.PeriodicWorkScheduler
|
||||||
import org.koitharu.kotatsu.tracker.domain.Tracker
|
import org.koitharu.kotatsu.tracker.domain.Tracker
|
||||||
import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates
|
import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@@ -67,6 +70,7 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
|
trySetForeground()
|
||||||
logger.log("doWork()")
|
logger.log("doWork()")
|
||||||
try {
|
try {
|
||||||
return doWorkImpl()
|
return doWorkImpl()
|
||||||
@@ -85,7 +89,6 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
if (!settings.isTrackerEnabled) {
|
if (!settings.isTrackerEnabled) {
|
||||||
return Result.success(workDataOf(0, 0))
|
return Result.success(workDataOf(0, 0))
|
||||||
}
|
}
|
||||||
trySetForeground()
|
|
||||||
val tracks = tracker.getAllTracks()
|
val tracks = tracker.getAllTracks()
|
||||||
logger.log("Total ${tracks.size} tracks")
|
logger.log("Total ${tracks.size} tracks")
|
||||||
if (tracks.isEmpty()) {
|
if (tracks.isEmpty()) {
|
||||||
@@ -234,7 +237,7 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object : PeriodicWorkScheduler {
|
||||||
|
|
||||||
private const val WORKER_CHANNEL_ID = "track_worker"
|
private const val WORKER_CHANNEL_ID = "track_worker"
|
||||||
private const val WORKER_NOTIFICATION_ID = 35
|
private const val WORKER_NOTIFICATION_ID = 35
|
||||||
@@ -244,14 +247,28 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
private const val DATA_KEY_SUCCESS = "success"
|
private const val DATA_KEY_SUCCESS = "success"
|
||||||
private const val DATA_KEY_FAILED = "failed"
|
private const val DATA_KEY_FAILED = "failed"
|
||||||
|
|
||||||
fun setup(context: Context) {
|
override suspend fun schedule(context: Context) {
|
||||||
val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
|
val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
|
||||||
val request = PeriodicWorkRequestBuilder<TrackWorker>(4, TimeUnit.HOURS)
|
val request = PeriodicWorkRequestBuilder<TrackWorker>(4, TimeUnit.HOURS)
|
||||||
.setConstraints(constraints)
|
.setConstraints(constraints)
|
||||||
.addTag(TAG)
|
.addTag(TAG)
|
||||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 30, TimeUnit.MINUTES)
|
.setBackoffCriteria(BackoffPolicy.LINEAR, 30, TimeUnit.MINUTES)
|
||||||
.build()
|
.build()
|
||||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, request)
|
WorkManager.getInstance(context)
|
||||||
|
.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, request)
|
||||||
|
.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun unschedule(context: Context) {
|
||||||
|
WorkManager.getInstance(context)
|
||||||
|
.cancelUniqueWork(TAG)
|
||||||
|
.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun isScheduled(context: Context): Boolean {
|
||||||
|
return WorkManagerHelper(WorkManager.getInstance(context))
|
||||||
|
.getUniqueWorkInfoByName(TAG)
|
||||||
|
.any { !it.state.isFinished }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startNow(context: Context) {
|
fun startNow(context: Context) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/barrier_top"
|
app:layout_constraintTop_toBottomOf="@id/barrier_top"
|
||||||
app:trackColor="?colorPrimaryContainer"
|
app:trackColor="?android:colorBackground"
|
||||||
tools:progress="25" />
|
tools:progress="25" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
<string name="vibration">Вібрацыя</string>
|
<string name="vibration">Вібрацыя</string>
|
||||||
<string name="favourites_categories">Катэгорыі абранага</string>
|
<string name="favourites_categories">Катэгорыі абранага</string>
|
||||||
<string name="remove_category">Выдаліць катэгорыю</string>
|
<string name="remove_category">Выдаліць катэгорыю</string>
|
||||||
<string name="manga_shelf">Паліца з мангай</string>
|
<string name="manga_shelf">Паліца</string>
|
||||||
<string name="recent_manga">Нядаўняя манга</string>
|
<string name="recent_manga">Нядаўняя манга</string>
|
||||||
<string name="pages_animation">Анімацыя гартання</string>
|
<string name="pages_animation">Анімацыя гартання</string>
|
||||||
<string name="manga_save_location">Месца спампоўвання мангі</string>
|
<string name="manga_save_location">Месца спампоўвання мангі</string>
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
<string name="screenshots_block_all">Заўсёды блакуйце</string>
|
<string name="screenshots_block_all">Заўсёды блакуйце</string>
|
||||||
<string name="screenshots_block_nsfw">Блок на NSFW</string>
|
<string name="screenshots_block_nsfw">Блок на NSFW</string>
|
||||||
<string name="filter_load_error">Немагчыма загрузіць спіс жанраў</string>
|
<string name="filter_load_error">Немагчыма загрузіць спіс жанраў</string>
|
||||||
<string name="disabled">Непрацаздольны</string>
|
<string name="disabled">Адключаны</string>
|
||||||
<string name="enabled">Уключаны</string>
|
<string name="enabled">Уключаны</string>
|
||||||
<string name="exclude_nsfw_from_suggestions">Не прапануйце мангу NSFW</string>
|
<string name="exclude_nsfw_from_suggestions">Не прапануйце мангу NSFW</string>
|
||||||
<string name="text_suggestion_holder">Пачніце чытаць мангу, і вы атрымаеце персаналізаваныя прапановы</string>
|
<string name="text_suggestion_holder">Пачніце чытаць мангу, і вы атрымаеце персаналізаваныя прапановы</string>
|
||||||
@@ -255,7 +255,7 @@
|
|||||||
<string name="edit">Змяніць</string>
|
<string name="edit">Змяніць</string>
|
||||||
<string name="edit_category">Змяніць катэгорыю</string>
|
<string name="edit_category">Змяніць катэгорыю</string>
|
||||||
<string name="bookmark_add">Дадаць закладку</string>
|
<string name="bookmark_add">Дадаць закладку</string>
|
||||||
<string name="undo">Адмяніць</string>
|
<string name="undo">Адмена</string>
|
||||||
<string name="disable_battery_optimization">Адключыць аптымізацыю акумулятара</string>
|
<string name="disable_battery_optimization">Адключыць аптымізацыю акумулятара</string>
|
||||||
<string name="disable_battery_optimization_summary">Дапамагае з фонавай праверкай абнаўленняў</string>
|
<string name="disable_battery_optimization_summary">Дапамагае з фонавай праверкай абнаўленняў</string>
|
||||||
<string name="crash_text">Штосьці пайшло не так. Калі ласка, адпраўце справаздачу пра памылку распрацоўшчыкам, каб дапамагчы нам яе выправіць.</string>
|
<string name="crash_text">Штосьці пайшло не так. Калі ласка, адпраўце справаздачу пра памылку распрацоўшчыкам, каб дапамагчы нам яе выправіць.</string>
|
||||||
@@ -327,7 +327,7 @@
|
|||||||
<string name="enable_logging_summary">Запішыце некаторыя дзеянні для адладкі</string>
|
<string name="enable_logging_summary">Запішыце некаторыя дзеянні для адладкі</string>
|
||||||
<string name="show_suspicious_content">Паказаць падазроны кантэнт</string>
|
<string name="show_suspicious_content">Паказаць падазроны кантэнт</string>
|
||||||
<string name="text_shelf_holder_primary">Ваша манга будзе адлюстроўвацца тут</string>
|
<string name="text_shelf_holder_primary">Ваша манга будзе адлюстроўвацца тут</string>
|
||||||
<string name="text_shelf_holder_secondary">Знайдзіце, што пачытаць, у раздзеле «Даследаваць»</string>
|
<string name="text_shelf_holder_secondary">Знайдзіце, што пачытаць, у раздзеле «Агляд»</string>
|
||||||
<string name="canceled">Адменена</string>
|
<string name="canceled">Адменена</string>
|
||||||
<string name="manage">Кіраваць</string>
|
<string name="manage">Кіраваць</string>
|
||||||
<string name="available">Даступны</string>
|
<string name="available">Даступны</string>
|
||||||
@@ -356,7 +356,7 @@
|
|||||||
<string name="random">Выпадковы</string>
|
<string name="random">Выпадковы</string>
|
||||||
<string name="reorder">Змяніць парадак</string>
|
<string name="reorder">Змяніць парадак</string>
|
||||||
<string name="empty">Пуста</string>
|
<string name="empty">Пуста</string>
|
||||||
<string name="explore">Дасьледуйце</string>
|
<string name="explore">Агляд</string>
|
||||||
<string name="confirm_exit">Націсніце \"Назад\" яшчэ раз, каб выйсці</string>
|
<string name="confirm_exit">Націсніце \"Назад\" яшчэ раз, каб выйсці</string>
|
||||||
<string name="exit_confirmation_summary">Двойчы націсніце \"Назад\", каб выйсці з праграмы</string>
|
<string name="exit_confirmation_summary">Двойчы націсніце \"Назад\", каб выйсці з праграмы</string>
|
||||||
<string name="exit_confirmation">Пацверджанне выхаду</string>
|
<string name="exit_confirmation">Пацверджанне выхаду</string>
|
||||||
@@ -425,7 +425,7 @@
|
|||||||
<string name="invert_colors">Інвертаваць колеры</string>
|
<string name="invert_colors">Інвертаваць колеры</string>
|
||||||
<string name="show_pages_numbers_summary">Паказаць нумары старонак у ніжнім куце</string>
|
<string name="show_pages_numbers_summary">Паказаць нумары старонак у ніжнім куце</string>
|
||||||
<string name="network">Сетка</string>
|
<string name="network">Сетка</string>
|
||||||
<string name="data_and_privacy">Дадзеныя і прыватнасць</string>
|
<string name="data_and_privacy">Дадзеныя і канфідэнцыяльнасць</string>
|
||||||
<string name="webtoon_zoom_summary">Дазволіць жэст для павелічэння ў рэжыме webtoon</string>
|
<string name="webtoon_zoom_summary">Дазволіць жэст для павелічэння ў рэжыме webtoon</string>
|
||||||
<string name="details_button_tip">Націсніце і ўтрымлівайце кнопку \"Чытаць\", каб убачыць дадатковыя параметры</string>
|
<string name="details_button_tip">Націсніце і ўтрымлівайце кнопку \"Чытаць\", каб убачыць дадатковыя параметры</string>
|
||||||
<string name="restore_summary">Аднавіць раней створаную рэзервовую копію</string>
|
<string name="restore_summary">Аднавіць раней створаную рэзервовую копію</string>
|
||||||
|
|||||||
@@ -422,4 +422,13 @@
|
|||||||
<string name="password">Mot de passe</string>
|
<string name="password">Mot de passe</string>
|
||||||
<string name="invalid_value_message">Valeur invalide</string>
|
<string name="invalid_value_message">Valeur invalide</string>
|
||||||
<string name="authorization_optional">Autorisation (optionnel)</string>
|
<string name="authorization_optional">Autorisation (optionnel)</string>
|
||||||
|
<string name="invalid_port_number">Numéro de port invalide</string>
|
||||||
|
<string name="restore_summary">Restaurer la sauvegarde précédemment créée</string>
|
||||||
|
<string name="webtoon_zoom_summary">Autoriser le geste de zoom avant en mode webtoon</string>
|
||||||
|
<string name="reader_info_bar_summary">Afficher l\'heure actuelle et la progression de la lecture en haut de l\'écran</string>
|
||||||
|
<string name="pages_animation_summary">Animation de tournage de page</string>
|
||||||
|
<string name="details_button_tip">Appuyez et maintenez le bouton Lire pour voir plus d\'options</string>
|
||||||
|
<string name="network">Réseau</string>
|
||||||
|
<string name="data_and_privacy">Données et confidentialité</string>
|
||||||
|
<string name="show_pages_numbers_summary">Afficher les numéros de page dans le coin inférieur</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -359,4 +359,5 @@
|
|||||||
<string name="allow_unstable_updates">Tillat ustøe oppdateringar</string>
|
<string name="allow_unstable_updates">Tillat ustøe oppdateringar</string>
|
||||||
<string name="downloads_wifi_only">Hent berre på WiFi</string>
|
<string name="downloads_wifi_only">Hent berre på WiFi</string>
|
||||||
<string name="downloads_wifi_only_summary">Stans all henting når du byter til eit mobilnettverk</string>
|
<string name="downloads_wifi_only_summary">Stans all henting når du byter til eit mobilnettverk</string>
|
||||||
|
<string name="find_similar">Finn liknande</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
<string name="download">Download</string>
|
<string name="download">Download</string>
|
||||||
<string name="notifications_settings">Configurações das notificações</string>
|
<string name="notifications_settings">Configurações das notificações</string>
|
||||||
<string name="light_indicator">Indicador LED</string>
|
<string name="light_indicator">Indicador LED</string>
|
||||||
<string name="remote_sources">Fontes remotas</string>
|
<string name="remote_sources">Fontes de mangá</string>
|
||||||
<string name="close">Fechar</string>
|
<string name="close">Fechar</string>
|
||||||
<string name="light">Claro</string>
|
<string name="light">Claro</string>
|
||||||
<string name="history">Histórico</string>
|
<string name="history">Histórico</string>
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
<string name="app_version">Versão %s</string>
|
<string name="app_version">Versão %s</string>
|
||||||
<string name="check_for_updates">Verifique se há atualizações</string>
|
<string name="check_for_updates">Verifique se há atualizações</string>
|
||||||
<string name="no_update_available">Nenhuma atualização disponível</string>
|
<string name="no_update_available">Nenhuma atualização disponível</string>
|
||||||
<string name="right_to_left">Da direita para a esquerda</string>
|
<string name="right_to_left">Da direita para a esquerda (←)</string>
|
||||||
<string name="create_category">Nova categoria</string>
|
<string name="create_category">Nova categoria</string>
|
||||||
<string name="scale_mode">Modo de escala</string>
|
<string name="scale_mode">Modo de escala</string>
|
||||||
<string name="zoom_mode_fit_center">Centro de ajuste</string>
|
<string name="zoom_mode_fit_center">Centro de ajuste</string>
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
<string name="screenshots_policy">Política de captura de ecrã</string>
|
<string name="screenshots_policy">Política de captura de ecrã</string>
|
||||||
<string name="screenshots_block_all">Sempre bloquear</string>
|
<string name="screenshots_block_all">Sempre bloquear</string>
|
||||||
<string name="suggestions_summary">Sugira mangá com base nas suas preferências</string>
|
<string name="suggestions_summary">Sugira mangá com base nas suas preferências</string>
|
||||||
<string name="suggestions_info">Todos os dados são analisados localmente neste dispositivo. Não há transferência dos seus dados pessoais para nenhum serviço</string>
|
<string name="suggestions_info">Todos os dados são analisados apenas localmente neste dispositivo e nunca são enviados para qualquer lugar.</string>
|
||||||
<string name="text_suggestion_holder">Comece a ler mangá e receberá sugestões personalizadas</string>
|
<string name="text_suggestion_holder">Comece a ler mangá e receberá sugestões personalizadas</string>
|
||||||
<string name="suggestions">Sugestões</string>
|
<string name="suggestions">Sugestões</string>
|
||||||
<string name="suggestions_enable">Ativar sugestões</string>
|
<string name="suggestions_enable">Ativar sugestões</string>
|
||||||
@@ -225,127 +225,127 @@
|
|||||||
<string name="percent_string_pattern">%1$s%%</string>
|
<string name="percent_string_pattern">%1$s%%</string>
|
||||||
<string name="text_shelf_holder_primary">O seu mangá será exibido aqui</string>
|
<string name="text_shelf_holder_primary">O seu mangá será exibido aqui</string>
|
||||||
<string name="color_correction">Correção de cor</string>
|
<string name="color_correction">Correção de cor</string>
|
||||||
<string name="server_error">Erro do lado do servidor (%1$d). Por favor, tente novamente mais tarde</string>
|
<string name="server_error">Erro do servidor (%1$d). Por favor, tente novamente mais tarde</string>
|
||||||
<string name="clear_new_chapters_counters">Também limpar informações sobre capítulos novos</string>
|
<string name="clear_new_chapters_counters">Apagar informações sobre novos capítulos</string>
|
||||||
<string name="hide">Esconder</string>
|
<string name="hide">Ocultar</string>
|
||||||
<string name="text_delete_local_manga_batch">Apagar itens selecionados do aparelho permanentemente\?</string>
|
<string name="text_delete_local_manga_batch">Excluir os itens selecionados do dispositivo permanentemente\?</string>
|
||||||
<string name="compact">Compactar</string>
|
<string name="compact">Compactar</string>
|
||||||
<string name="bookmark_added">Marcador adicionado</string>
|
<string name="bookmark_added">Marcador adicionado</string>
|
||||||
<string name="prefetch_content">Pré-carregamento de conteúdo</string>
|
<string name="prefetch_content">Pré-carregamento de conteúdo</string>
|
||||||
<string name="invalid_domain_message">Endereço inválido</string>
|
<string name="invalid_domain_message">Domínio inválido</string>
|
||||||
<string name="use_fingerprint">Usar impressão digital, se disponível</string>
|
<string name="use_fingerprint">Usar impressão digital, se estiver disponível</string>
|
||||||
<string name="appwidget_shelf_description">Mangás dos seus favoritos</string>
|
<string name="appwidget_shelf_description">Mangá dos seus favoritos</string>
|
||||||
<string name="appwidget_recent_description">Os seus mangás recentemente lidos</string>
|
<string name="appwidget_recent_description">Mangás lidos recentemente</string>
|
||||||
<string name="suggestions_excluded_genres_summary">Especifique os gêneros que não deseja ver nas sugestões</string>
|
<string name="suggestions_excluded_genres_summary">Especifique os gêneros que você não deseja ver nas sugestões</string>
|
||||||
<string name="removal_completed">Remoção concluída</string>
|
<string name="removal_completed">Remoção concluída</string>
|
||||||
<string name="check_new_chapters_title">Verifique se há novos capítulos e notifique sobre isso</string>
|
<string name="check_new_chapters_title">Verifique se há novos capítulos e notifique se houver</string>
|
||||||
<string name="default_mode">Modo padrão</string>
|
<string name="default_mode">Modo padrão</string>
|
||||||
<string name="mark_as_current">Marcar como atual</string>
|
<string name="mark_as_current">Marcar como atual</string>
|
||||||
<string name="error_no_space_left">Não há espaço disponível no aparelho</string>
|
<string name="error_no_space_left">Não há espaço disponível no dispositivo</string>
|
||||||
<string name="different_languages">Idiomas diferentes</string>
|
<string name="different_languages">Idiomas diferentes</string>
|
||||||
<string name="network_unavailable">A rede não está disponível</string>
|
<string name="network_unavailable">A rede não está disponível</string>
|
||||||
<string name="network_unavailable_hint">Ative o Wi-Fi ou a rede móvel para ler mangá online</string>
|
<string name="network_unavailable_hint">Ative o Wi-Fi ou a rede móvel para ler o mangá online</string>
|
||||||
<string name="name">Nome</string>
|
<string name="name">Nome</string>
|
||||||
<string name="logout">Terminar sessão</string>
|
<string name="logout">Sair</string>
|
||||||
<string name="edit">Editar</string>
|
<string name="edit">Editar</string>
|
||||||
<string name="edit_category">Editar categoria</string>
|
<string name="edit_category">Editar categoria</string>
|
||||||
<string name="tracking">Monitoramento</string>
|
<string name="tracking">Monitoramento</string>
|
||||||
<string name="empty_favourite_categories">Nenhuma categoria favorita</string>
|
<string name="empty_favourite_categories">Nenhuma categoria favorita</string>
|
||||||
<string name="removed_from_history">Removido do histórico</string>
|
<string name="removed_from_history">Removido do histórico</string>
|
||||||
<string name="send">Enviar</string>
|
<string name="send">Enviar</string>
|
||||||
<string name="text_shelf_holder_secondary">Encontre o que ler na secção <«Explorar»</string>
|
<string name="text_shelf_holder_secondary">Encontre o que ler na secção «Explorar»</string>
|
||||||
<string name="suggestions_excluded_genres">Excluir gêneros</string>
|
<string name="suggestions_excluded_genres">Excluir gêneros</string>
|
||||||
<string name="download_slowdown">Lentidão de descarga</string>
|
<string name="download_slowdown">Download lento</string>
|
||||||
<string name="download_slowdown_summary">Ajuda a evitar o bloqueio do seu endereço IP</string>
|
<string name="download_slowdown_summary">Ajude a evitar o bloqueio do seu endereço IP</string>
|
||||||
<string name="local_manga_processing">Processamento de mangá gravado</string>
|
<string name="local_manga_processing">Processando mangá salvo</string>
|
||||||
<string name="chapters_will_removed_background">Os capítulos serão removidos em segundo plano. Pode levar algum tempo</string>
|
<string name="chapters_will_removed_background">Os capítulos serão removidos em segundo plano</string>
|
||||||
<string name="canceled">Cancelado</string>
|
<string name="canceled">Cancelado</string>
|
||||||
<string name="email_enter_hint">Digite o seu e-mail para continuar</string>
|
<string name="email_enter_hint">Digite seu e-mail para continuar</string>
|
||||||
<string name="new_sources_text">Novas fontes de mangá estão disponíveis</string>
|
<string name="new_sources_text">Novas fontes de mangá estão disponíveis</string>
|
||||||
<string name="show_notification_new_chapters_on">Receberá notificações sobre atualizações do mangá que está lendo</string>
|
<string name="show_notification_new_chapters_on">Você receberá notificações sobre atualizações do mangá que está lendo</string>
|
||||||
<string name="notifications_enable">Ativar notificações</string>
|
<string name="notifications_enable">Ativar notificações</string>
|
||||||
<string name="crash_text">Algo deu errado. Por favor, envie um relatório de bug para ajudar os programadores a consertarem isso.</string>
|
<string name="crash_text">Algo deu errado. Por favor, envie um relatório de bug para os desenvolvedores para nos ajudar a corrigi-lo.</string>
|
||||||
<string name="status_planned">Planejado</string>
|
<string name="status_planned">Planejado</string>
|
||||||
<string name="status_reading">Lendo</string>
|
<string name="status_reading">Leitura</string>
|
||||||
<string name="status_re_reading">Relendo</string>
|
<string name="status_re_reading">Relendo</string>
|
||||||
<string name="status_completed">Concluído</string>
|
<string name="status_completed">Concluído</string>
|
||||||
<string name="status_on_hold">Em espera</string>
|
<string name="status_on_hold">Em espera</string>
|
||||||
<string name="show_reading_indicators">Mostrar indicadores de progresso de leitura</string>
|
<string name="show_reading_indicators">Mostrar indicadores de progresso de leitura</string>
|
||||||
<string name="data_deletion">Exclusão de dados</string>
|
<string name="data_deletion">Exclusão de dados</string>
|
||||||
<string name="clear_cookies_summary">Pode ajudar no caso de alguns problemas. Todas as autorizações serão invalidadas</string>
|
<string name="clear_cookies_summary">Pode ajudar em caso de alguns problemas. Todas as autorizações serão invalidadas</string>
|
||||||
<string name="show_all">Mostrar tudo</string>
|
<string name="show_all">Mostrar tudo</string>
|
||||||
<string name="clear_all_history">Limpar todo o histórico</string>
|
<string name="clear_all_history">Apagar todo o histórico</string>
|
||||||
<string name="last_2_hours">Ultimas 2 horas</string>
|
<string name="last_2_hours">Últimas 2 horas</string>
|
||||||
<string name="categories_delete_confirm">Tem certeza que deseja apagar as categorias favoritas selecionadas\?
|
<string name="categories_delete_confirm">Tem certeza de que deseja excluir as categorias favoritas selecionadas\?
|
||||||
\nTodos os mangás serão perdidos e isso não pode ser desfeito.</string>
|
\nTodos os mangás serão perdidos e isso não poderá ser desfeito.</string>
|
||||||
<string name="reorder">Reordenar</string>
|
<string name="reorder">Reorganizar</string>
|
||||||
<string name="empty">Vazio</string>
|
<string name="empty">Vazio</string>
|
||||||
<string name="explore">Explorar</string>
|
<string name="explore">Explorar</string>
|
||||||
<string name="comics_archive">Arquivo de banda desenhada</string>
|
<string name="comics_archive">Arquivos de quadrinhos</string>
|
||||||
<string name="folder_with_images">Pasta com imagens</string>
|
<string name="folder_with_images">Pasta com imagens</string>
|
||||||
<string name="importing_manga">Importando mangá(s)</string>
|
<string name="importing_manga">Importando mangá</string>
|
||||||
<string name="saved_manga">Mangás gravados</string>
|
<string name="saved_manga">Mangás salvos</string>
|
||||||
<string name="history_shortcuts">Mostrar atalhos de mangás recentes</string>
|
<string name="history_shortcuts">Mostrar atalhos de mangá recentes</string>
|
||||||
<string name="history_shortcuts_summary">Torne os mangás recentes visíveis pressionando o ícone da aplicação</string>
|
<string name="history_shortcuts_summary">Disponibilizar mangás recentes pressionando por um curto período de tempo o ícone do aplicativo</string>
|
||||||
<string name="brightness">Luminosidade</string>
|
<string name="brightness">Brilho</string>
|
||||||
<string name="contrast">Contraste</string>
|
<string name="contrast">Contraste</string>
|
||||||
<string name="reset">Redefinir</string>
|
<string name="reset">Redefinir</string>
|
||||||
<string name="text_unsaved_changes_prompt">Gravar ou descartar alterações não gravadas\?</string>
|
<string name="text_unsaved_changes_prompt">Salvar ou descartar alterações não salvas\?</string>
|
||||||
<string name="select_range">Selecionar intervalo</string>
|
<string name="select_range">Selecionar intervalo</string>
|
||||||
<string name="reader_slider">Mostrar controle deslizante de troca de página</string>
|
<string name="reader_slider">Mostrar controle de leitura deslizante</string>
|
||||||
<string name="source_disabled">Fonte desativada</string>
|
<string name="source_disabled">Fonte desativada</string>
|
||||||
<string name="account_already_exists">Essa conta já existe</string>
|
<string name="account_already_exists">Essa conta já existe</string>
|
||||||
<string name="back">Voltar</string>
|
<string name="back">Voltar</string>
|
||||||
<string name="sync">Sincronização</string>
|
<string name="sync">Sincronização</string>
|
||||||
<string name="sync_title">Sincronize os seus dados</string>
|
<string name="sync_title">Sincronizar os seus dados</string>
|
||||||
<string name="show_notification_new_chapters_off">Não receberá notificações, mas novos capítulos serão destacados nas listas</string>
|
<string name="show_notification_new_chapters_off">Você não receberá notificações, mas novos capítulos serão destacados nas listas</string>
|
||||||
<string name="bookmark_add">Adicionar marcador</string>
|
<string name="bookmark_add">Adicionar marcador</string>
|
||||||
<string name="bookmark_remove">Remover marcador</string>
|
<string name="bookmark_remove">Remover marcador</string>
|
||||||
<string name="bookmarks">Marcadores</string>
|
<string name="bookmarks">Marcadores</string>
|
||||||
<string name="bookmark_removed">Marcador removido</string>
|
<string name="bookmark_removed">Marcador removido</string>
|
||||||
<string name="undo">Desfazer</string>
|
<string name="undo">Desfazer</string>
|
||||||
<string name="dns_over_https">DNS sobre HTTPS</string>
|
<string name="dns_over_https">DNS sobre HTTPS</string>
|
||||||
<string name="detect_reader_mode">Detecção automática do modo de leitura</string>
|
<string name="detect_reader_mode">Modo de leitor de detecção automática</string>
|
||||||
<string name="detect_reader_mode_summary">Detetar automaticamente se o mangá é webtoon</string>
|
<string name="detect_reader_mode_summary">Detectar automaticamente se o mangá é webtoon</string>
|
||||||
<string name="disable_battery_optimization">Desative a otimização da bateria</string>
|
<string name="disable_battery_optimization">Desativar otimização de bateria</string>
|
||||||
<string name="disable_battery_optimization_summary">Ajuda com verificações de atualizações em segundo plano</string>
|
<string name="disable_battery_optimization_summary">Ajuda com verificações de atualizações em segundo plano</string>
|
||||||
<string name="status_dropped">Desistido</string>
|
<string name="status_dropped">Dropado</string>
|
||||||
<string name="disable_all">Desativar tudo</string>
|
<string name="disable_all">Desativar tudo</string>
|
||||||
<string name="report">Reportar</string>
|
<string name="report">Relatório</string>
|
||||||
<string name="show_reading_indicators_summary">Mostrar percentual de leitura no histórico e nos favoritos</string>
|
<string name="show_reading_indicators_summary">Mostrar porcentagem lida no histórico e favoritos</string>
|
||||||
<string name="exclude_nsfw_from_history_summary">Mangás marcados como +18 nunca serão adicionados ao histórico e o seu progresso não sera gravado</string>
|
<string name="exclude_nsfw_from_history_summary">Mangás marcados como NSFW nunca serão adicionados ao seu histórico e seu progresso não será salvo</string>
|
||||||
<string name="history_cleared">Histórico apagado</string>
|
<string name="history_cleared">Histórico deletado</string>
|
||||||
<string name="manage">Gerir</string>
|
<string name="manage">Gerenciar</string>
|
||||||
<string name="no_bookmarks_yet">Sem páginas marcadas ainda</string>
|
<string name="no_bookmarks_yet">Ainda não há marcadores</string>
|
||||||
<string name="no_bookmarks_summary">Pode criar um marcador de página enquanto lé o mangá</string>
|
<string name="no_bookmarks_summary">Você pode criar marcadores enquanto lê o mangá</string>
|
||||||
<string name="bookmarks_removed">Marcadores de página removidos</string>
|
<string name="bookmarks_removed">Marcadores removidos</string>
|
||||||
<string name="no_manga_sources">Sem fontes de mangás</string>
|
<string name="no_manga_sources">Sem fontes de mangá</string>
|
||||||
<string name="no_manga_sources_text">Ative as fontes de mangá para ler online</string>
|
<string name="no_manga_sources_text">Habilitar fontes de mangá para ler o mangá online</string>
|
||||||
<string name="random">Aleatório</string>
|
<string name="random">Aleatório</string>
|
||||||
<string name="confirm_exit">Pressione Voltar novamente para sair</string>
|
<string name="confirm_exit">Pressione Voltar novamente para sair</string>
|
||||||
<string name="exit_confirmation_summary">Pressione Voltar duas vezes para sair do app</string>
|
<string name="exit_confirmation_summary">Pressione Voltar duas vezes para sair do aplicativo</string>
|
||||||
<string name="exit_confirmation">Confirmação de saída</string>
|
<string name="exit_confirmation">Confirmação de saída</string>
|
||||||
<string name="pages_cache">Cache de páginas</string>
|
<string name="pages_cache">Cache de páginas</string>
|
||||||
<string name="other_cache">Outro cache</string>
|
<string name="other_cache">Outros cache</string>
|
||||||
<string name="storage_usage">Uso de armazenamento</string>
|
<string name="storage_usage">Armazenamento usado</string>
|
||||||
<string name="available">Disponível</string>
|
<string name="available">Disponível</string>
|
||||||
<string name="memory_usage_pattern">%s - %s</string>
|
<string name="memory_usage_pattern">%s - %s</string>
|
||||||
<string name="removed_from_favourites">Removido dos favoritos</string>
|
<string name="removed_from_favourites">Removido dos favoritos</string>
|
||||||
<string name="options">Opções</string>
|
<string name="options">Opções</string>
|
||||||
<string name="not_found_404">Conteúdo não encontrado ou removido</string>
|
<string name="not_found_404">Conteúdo não encontrado ou removido</string>
|
||||||
<string name="incognito_mode">Modo anônimo</string>
|
<string name="incognito_mode">Modo de navegação anônima</string>
|
||||||
<string name="no_chapters">Sem capítulos</string>
|
<string name="no_chapters">Sem capítulos</string>
|
||||||
<string name="automatic_scroll">Rolagem automática</string>
|
<string name="automatic_scroll">Rolagem automática</string>
|
||||||
<string name="reader_info_pattern">Cap. %1$d/%2$d Pág. %3$d/%4$d</string>
|
<string name="reader_info_pattern">Cap. %1$d/%2$d Pág. %3$d/%4$d</string>
|
||||||
<string name="reader_info_bar">Mostrar barra de informações no leitor</string>
|
<string name="reader_info_bar">Mostrar barra de informações no leitor</string>
|
||||||
<string name="import_completed">Importação completa</string>
|
<string name="import_completed">Importação concluída</string>
|
||||||
<string name="import_completed_hint">Pode apagar o ficheiro original do aparelho para poupar espaço</string>
|
<string name="import_completed_hint">Você pode excluir o arquivo original do armazenamento para economizar espaço</string>
|
||||||
<string name="import_will_start_soon">A importação começará em breve</string>
|
<string name="import_will_start_soon">A importação começará em breve</string>
|
||||||
<string name="feed">Feed</string>
|
<string name="feed">Fluxo de conteúdo</string>
|
||||||
<string name="manga_error_description_pattern">Detalhes do erro:<br><tt>%1$s</tt><br><br>1. Tente <a href=%2$s>abrir o mangá num navegador de internet</a>para garantir que ele está disponível na fonte<br>2. Se estiver disponível, envie um relatório de erro para os programadores.</string>
|
<string name="manga_error_description_pattern">Detalhes do erro:<br><tt>%1$s</tt><br><br>1. Tente <a href=%2$s>abra a página do mangá em um navegador da web</a> para garantir que o mesmo esteja disponível em sua fonte<br>2. Se estiver disponível, envie um relatório de erro para os desenvolvedores.</string>
|
||||||
<string name="reader_control_ltr_summary">Tocar na borda direita ou pressionar a tecla direita sempre passa para a próxima página</string>
|
<string name="reader_control_ltr_summary">Tocar na borda direita ou pressionar a tecla direita sempre muda para a próxima página</string>
|
||||||
<string name="reader_control_ltr">Controle de leitura ergonômico</string>
|
<string name="reader_control_ltr">Controle ergonômico do leitor</string>
|
||||||
<string name="color_correction_hint">As configurações de cor escolhidas serão lembradas para esse mangá</string>
|
<string name="color_correction_hint">As configurações de cores escolhidas serão lembradas para este mangá</string>
|
||||||
<string name="discard">Descartar</string>
|
<string name="discard">Descartar</string>
|
||||||
<string name="language">Idioma</string>
|
<string name="language">Idioma</string>
|
||||||
<string name="theme_name_mamimi">Mamimi</string>
|
<string name="theme_name_mamimi">Mamimi</string>
|
||||||
@@ -366,4 +366,9 @@
|
|||||||
<string name="theme_name_asuka">Asuka</string>
|
<string name="theme_name_asuka">Asuka</string>
|
||||||
<string name="theme_name_mion">Mion</string>
|
<string name="theme_name_mion">Mion</string>
|
||||||
<string name="settings_apply_restart_required">Por favor, reinicie o app para aplicar essas mudanças</string>
|
<string name="settings_apply_restart_required">Por favor, reinicie o app para aplicar essas mudanças</string>
|
||||||
|
<string name="theme_name_kanade">Kanade</string>
|
||||||
|
<string name="scrobbling_empty_hint">Para acompanhar o progresso da leitura, selecione Menu → Vá até a tela de detalhes do mangá.</string>
|
||||||
|
<string name="details_button_tip">Pressione e segure o botão Ler para ver mais opções</string>
|
||||||
|
<string name="webtoon_zoom">Zoom Webtoon</string>
|
||||||
|
<string name="allow_unstable_updates_summary">Propor atualizações para versões beta do aplicativo</string>
|
||||||
</resources>
|
</resources>
|
||||||
2
app/src/main/res/values-th/plurals.xml
Normal file
2
app/src/main/res/values-th/plurals.xml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources></resources>
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
<string name="suggestions">Öneriler</string>
|
<string name="suggestions">Öneriler</string>
|
||||||
<string name="suggestions_enable">Önerileri etkinleştir</string>
|
<string name="suggestions_enable">Önerileri etkinleştir</string>
|
||||||
<string name="suggestions_summary">Tercihlerinize göre manga önerileri alın</string>
|
<string name="suggestions_summary">Tercihlerinize göre manga önerileri alın</string>
|
||||||
<string name="suggestions_info">Tüm veriler sadece bu cihaz üzerinde yerel olarak işlenir ve asla herhangi bir yere satılmaz.</string>
|
<string name="suggestions_info">Tüm veriler bu cihazda yalnızca yerel olarak analiz edilir ve asla hiçbir yere gönderilmez.</string>
|
||||||
<string name="text_suggestion_holder">Manga okumaya başladıktan sonra kişiselleştirilmiş öneriler alacaksınız</string>
|
<string name="text_suggestion_holder">Manga okumaya başladıktan sonra kişiselleştirilmiş öneriler alacaksınız</string>
|
||||||
<string name="exclude_nsfw_from_suggestions">Uygunsuz manga önerme</string>
|
<string name="exclude_nsfw_from_suggestions">Uygunsuz manga önerme</string>
|
||||||
<string name="enabled">Etkin</string>
|
<string name="enabled">Etkin</string>
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
<string name="suggestions_excluded_genres_summary">Önerilerde görmek istemediğiniz türleri belirtin</string>
|
<string name="suggestions_excluded_genres_summary">Önerilerde görmek istemediğiniz türleri belirtin</string>
|
||||||
<string name="text_delete_local_manga_batch">Seçilen ögeler aygıttan kalıcı olarak silinsin mi\?</string>
|
<string name="text_delete_local_manga_batch">Seçilen ögeler aygıttan kalıcı olarak silinsin mi\?</string>
|
||||||
<string name="removal_completed">Kaldırma tamamlandı</string>
|
<string name="removal_completed">Kaldırma tamamlandı</string>
|
||||||
<string name="chapters_will_removed_background">Bölümler arka planda kaldırılacak.</string>
|
<string name="chapters_will_removed_background">Bölümler arka planda kaldırılacak</string>
|
||||||
<string name="download_slowdown">İndirmeyi yavaşlat</string>
|
<string name="download_slowdown">İndirmeyi yavaşlat</string>
|
||||||
<string name="download_slowdown_summary">IP adresinizin engellenmesinden kaçınmanıza yardımcı olur</string>
|
<string name="download_slowdown_summary">IP adresinizin engellenmesinden kaçınmanıza yardımcı olur</string>
|
||||||
<string name="local_manga_processing">Kaydedilen manga işleme</string>
|
<string name="local_manga_processing">Kaydedilen manga işleme</string>
|
||||||
@@ -302,7 +302,7 @@
|
|||||||
<string name="removed_from_favourites">Favorilerden kaldırıldı</string>
|
<string name="removed_from_favourites">Favorilerden kaldırıldı</string>
|
||||||
<string name="exit_confirmation">Çıkış doğrulaması</string>
|
<string name="exit_confirmation">Çıkış doğrulaması</string>
|
||||||
<string name="comics_archive">Çizgi roman arşivi</string>
|
<string name="comics_archive">Çizgi roman arşivi</string>
|
||||||
<string name="manga_error_description_pattern">Hata ayrıntıları:<br><tt>%1$s</tt><br><br>1.Mangayı <a href=%2$s>kaynağında mevcut olduğuna emin olmak için</a> bir web tarayıcısında açın<br>2. <a href=kotatsu://about> Kotatsunun son sürümünü kullandığnızdan emin olun.</a>/br> 3. Mevcutsa, geliştiricilere bir hata reporu gönderin.</string>
|
<string name="manga_error_description_pattern">Hata ayrıntıları:<br><tt>%1$s</tt><br><br>1. Kaynağında bulunduğundan emin olmak için <a href=%2$s>mangayı bir web tarayıcısında açmayı</a> deneyin<br>2. <a href=kotatsu://about>Kotatsu\'nun en son sürümünü</a><br>3 kullandığınızdan emin olun. Varsa, geliştiricilere bir hata raporu gönderin.</string>
|
||||||
<string name="text_shelf_holder_secondary">«Keşfet» kısmında neler okuyacağınızı bulun</string>
|
<string name="text_shelf_holder_secondary">«Keşfet» kısmında neler okuyacağınızı bulun</string>
|
||||||
<string name="categories_delete_confirm">Seçilen favori kategorileri silmek istediğinizden emin misiniz\?
|
<string name="categories_delete_confirm">Seçilen favori kategorileri silmek istediğinizden emin misiniz\?
|
||||||
\nİçindeki tüm mangalar kaybolur ve bu işlem geri alınamaz.</string>
|
\nİçindeki tüm mangalar kaybolur ve bu işlem geri alınamaz.</string>
|
||||||
@@ -379,7 +379,7 @@
|
|||||||
<string name="clear_network_cache">İnternet geçmişini temizle</string>
|
<string name="clear_network_cache">İnternet geçmişini temizle</string>
|
||||||
<string name="sync_settings">Eşitleme seçenekleri</string>
|
<string name="sync_settings">Eşitleme seçenekleri</string>
|
||||||
<string name="server_address">Sunucu adresi</string>
|
<string name="server_address">Sunucu adresi</string>
|
||||||
<string name="sync_host_description">"Şirket içinde barındırılan bir eşitleme sunucusu veya varsayılan bir sunucu kullanabilirsiniz. Ne yaptığınızdan emin değilseniz bunu değiştirmeyin."</string>
|
<string name="sync_host_description">Şirket içinde barındırılan bir eşitleme sunucusu veya varsayılan bir sunucu kullanabilirsiniz. Ne yaptığınızdan emin değilseniz bunu değiştirmeyin.</string>
|
||||||
<string name="mirror_switching_summary">Yansıtmalar varsa, hatalarda uzak kaynaklar için etki alanlarını otomatik olarak değiştir</string>
|
<string name="mirror_switching_summary">Yansıtmalar varsa, hatalarda uzak kaynaklar için etki alanlarını otomatik olarak değiştir</string>
|
||||||
<string name="downloads_wifi_only_summary">Mobil ağa geçerken indirmeyi durdur</string>
|
<string name="downloads_wifi_only_summary">Mobil ağa geçerken indirmeyi durdur</string>
|
||||||
<string name="remove_completed">Bitirilenleri kaldır</string>
|
<string name="remove_completed">Bitirilenleri kaldır</string>
|
||||||
@@ -392,7 +392,7 @@
|
|||||||
<string name="speed">Hız</string>
|
<string name="speed">Hız</string>
|
||||||
<string name="restore_backup_description">Kullanıcı verilerinin önceden oluşturulmuş bir yedeğini içe aktarın</string>
|
<string name="restore_backup_description">Kullanıcı verilerinin önceden oluşturulmuş bir yedeğini içe aktarın</string>
|
||||||
<string name="show_on_shelf">Rafta Göster</string>
|
<string name="show_on_shelf">Rafta Göster</string>
|
||||||
<string name="sync_auth_hint">Mevcut bir hesapta oturum açabilir veya yeni bir hesap oluşturabilirsiniz.</string>
|
<string name="sync_auth_hint">Mevcut bir hesapta oturum açabilir veya yeni bir hesap oluşturabilirsiniz</string>
|
||||||
<string name="ignore_ssl_errors">SSL hatalarını görmezden gel</string>
|
<string name="ignore_ssl_errors">SSL hatalarını görmezden gel</string>
|
||||||
<string name="pause">Durdur</string>
|
<string name="pause">Durdur</string>
|
||||||
<string name="resume">Devam et</string>
|
<string name="resume">Devam et</string>
|
||||||
@@ -423,4 +423,12 @@
|
|||||||
<string name="downloaded">İndirildi</string>
|
<string name="downloaded">İndirildi</string>
|
||||||
<string name="images_procy_description">Trafik kullanımını azaltmak ve mümkünse resim yüklemeyi hızlandırmak için wsrv.nl hizmetini kullanın</string>
|
<string name="images_procy_description">Trafik kullanımını azaltmak ve mümkünse resim yüklemeyi hızlandırmak için wsrv.nl hizmetini kullanın</string>
|
||||||
<string name="username">Kullanıcı adı</string>
|
<string name="username">Kullanıcı adı</string>
|
||||||
|
<string name="network">Ağ</string>
|
||||||
|
<string name="data_and_privacy">Veri ve gizlilik</string>
|
||||||
|
<string name="restore_summary">Önceden oluşturulmuş yedeği geri yükle</string>
|
||||||
|
<string name="webtoon_zoom_summary">Webtoon modunda yakınlaştırma hareketine izin ver</string>
|
||||||
|
<string name="reader_info_bar_summary">Geçerli saati ve okuma ilerlemesini ekranın üst kısmında gösterin</string>
|
||||||
|
<string name="show_pages_numbers_summary">Sayfa numaralarını alt köşede göster</string>
|
||||||
|
<string name="pages_animation_summary">Sayfa Çevirme Animasyonu</string>
|
||||||
|
<string name="details_button_tip">Daha fazla seçenek görmek için Oku düğmesini basılı tutun</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<string name="detailed_list">Детальний список</string>
|
<string name="detailed_list">Детальний список</string>
|
||||||
<string name="list_mode">Режим списку</string>
|
<string name="list_mode">Режим списку</string>
|
||||||
<string name="settings">Налаштування</string>
|
<string name="settings">Налаштування</string>
|
||||||
<string name="remote_sources">Джерела манги</string>
|
<string name="remote_sources">Джерела манґи</string>
|
||||||
<string name="loading_">Завантаження…</string>
|
<string name="loading_">Завантаження…</string>
|
||||||
<string name="computing_">Обчислення…</string>
|
<string name="computing_">Обчислення…</string>
|
||||||
<string name="chapter_d_of_d">Розділ %1$d із %2$d</string>
|
<string name="chapter_d_of_d">Розділ %1$d із %2$d</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user