Merge branch 'master' into devel

remotes/weblate/devel
Koitharu 5 years ago
commit d41a813e41

@ -13,8 +13,9 @@ android {
applicationId 'org.koitharu.kotatsu' applicationId 'org.koitharu.kotatsu'
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode 365 versionCode 367
versionName '1.1' versionName '1.1.2'
generatedDensities = []
kapt { kapt {
arguments { arguments {
@ -93,7 +94,7 @@ dependencies {
implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl:4.3.0' implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl:4.3.0'
implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:4.3.0' implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:4.3.0'
implementation 'io.insert-koin:koin-android:3.1.1' implementation 'io.insert-koin:koin-android:3.1.2'
implementation 'io.coil-kt:coil-base:1.2.2' implementation 'io.coil-kt:coil-base:1.2.2'
implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0' implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
implementation 'com.github.solkin:disk-lru-cache:1.2' implementation 'com.github.solkin:disk-lru-cache:1.2'
@ -102,5 +103,5 @@ dependencies {
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20210307' testImplementation 'org.json:json:20210307'
testImplementation 'io.insert-koin:koin-test-junit4:3.1.1' testImplementation 'io.insert-koin:koin-test-junit4:3.1.2'
} }

@ -56,16 +56,18 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindo
protected fun setContentView(binding: B) { protected fun setContentView(binding: B) {
this.binding = binding this.binding = binding
super.setContentView(binding.root) super.setContentView(binding.root)
(binding.root.findViewById<View>(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) val toolbar = (binding.root.findViewById<View>(R.id.toolbar) as? Toolbar)
val toolbarParams = (binding.root.findViewById<View>(R.id.toolbar) as? Toolbar)?.layoutParams as? AppBarLayout.LayoutParams toolbar?.let(this::setSupportActionBar)
val persistentToolbarParams = (binding.root.findViewById<View>(R.id.toolbar_card))?.layoutParams as? AppBarLayout.LayoutParams
ViewCompat.setOnApplyWindowInsetsListener(binding.root, this) ViewCompat.setOnApplyWindowInsetsListener(binding.root, this)
if (get<AppSettings>().isToolbarHideWhenScrolling) {
toolbarParams?.scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS val toolbarParams = (toolbar ?: binding.root.findViewById<View>(R.id.toolbar_card))
persistentToolbarParams?.scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS ?.layoutParams as? AppBarLayout.LayoutParams
} else { if (toolbarParams != null) {
toolbarParams?.scrollFlags = SCROLL_FLAG_NO_SCROLL if (get<AppSettings>().isToolbarHideWhenScrolling) {
persistentToolbarParams?.scrollFlags = SCROLL_FLAG_NO_SCROLL toolbarParams.scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS
} else {
toolbarParams.scrollFlags = SCROLL_FLAG_NO_SCROLL
}
} }
} }

@ -166,6 +166,7 @@ class AppSettings private constructor(private val prefs: SharedPreferences) :
const val KEY_LOCAL_STORAGE = "local_storage" const val KEY_LOCAL_STORAGE = "local_storage"
const val KEY_READER_SWITCHERS = "reader_switchers" const val KEY_READER_SWITCHERS = "reader_switchers"
const val KEY_TRACK_SOURCES = "track_sources" const val KEY_TRACK_SOURCES = "track_sources"
const val KEY_TRACK_WARNING = "track_warning"
const val KEY_APP_UPDATE = "app_update" const val KEY_APP_UPDATE = "app_update"
const val KEY_APP_UPDATE_AUTO = "app_update_auto" const val KEY_APP_UPDATE_AUTO = "app_update_auto"
const val KEY_TRACKER_NOTIFICATIONS = "tracker_notifications" const val KEY_TRACKER_NOTIFICATIONS = "tracker_notifications"

@ -220,7 +220,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
} }
override fun onGridTouch(area: Int) { override fun onGridTouch(area: Int) {
controlDelegate.onGridTouch(area) controlDelegate.onGridTouch(area, binding.container)
} }
override fun onProcessTouch(rawX: Int, rawY: Int): Boolean { override fun onProcessTouch(rawX: Int, rawY: Int): Boolean {

@ -1,6 +1,8 @@
package org.koitharu.kotatsu.reader.ui package org.koitharu.kotatsu.reader.ui
import android.view.KeyEvent import android.view.KeyEvent
import android.view.SoundEffectConstants
import android.view.View
import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LifecycleCoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
@ -30,18 +32,27 @@ class ReaderControlDelegate(
}.launchIn(scope) }.launchIn(scope)
} }
fun onGridTouch(area: Int) { fun onGridTouch(area: Int, view: View) {
when (area) { when (area) {
GridTouchHelper.AREA_CENTER -> { GridTouchHelper.AREA_CENTER -> {
listener.toggleUiVisibility() listener.toggleUiVisibility()
view.playSoundEffect(SoundEffectConstants.CLICK)
}
GridTouchHelper.AREA_TOP -> if (isTapSwitchEnabled) {
listener.switchPageBy(-1)
view.playSoundEffect(SoundEffectConstants.NAVIGATION_UP)
} }
GridTouchHelper.AREA_TOP,
GridTouchHelper.AREA_LEFT -> if (isTapSwitchEnabled) { GridTouchHelper.AREA_LEFT -> if (isTapSwitchEnabled) {
listener.switchPageBy(-1) listener.switchPageBy(-1)
view.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT)
}
GridTouchHelper.AREA_BOTTOM -> if (isTapSwitchEnabled) {
listener.switchPageBy(1)
view.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN)
} }
GridTouchHelper.AREA_BOTTOM,
GridTouchHelper.AREA_RIGHT -> if (isTapSwitchEnabled) { GridTouchHelper.AREA_RIGHT -> if (isTapSwitchEnabled) {
listener.switchPageBy(1) listener.switchPageBy(1)
view.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT)
} }
} }
} }

@ -4,6 +4,9 @@ import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.text.style.URLSpan
import androidx.core.text.buildSpannedString
import androidx.core.text.inSpans
import androidx.preference.MultiSelectListPreference import androidx.preference.MultiSelectListPreference
import androidx.preference.Preference import androidx.preference.Preference
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@ -19,6 +22,17 @@ class TrackerSettingsFragment : BasePreferenceFragment(R.string.new_chapters_che
findPreference<MultiSelectListPreference>(AppSettings.KEY_TRACK_SOURCES) findPreference<MultiSelectListPreference>(AppSettings.KEY_TRACK_SOURCES)
?.summaryProvider = MultiSummaryProvider(R.string.dont_check) ?.summaryProvider = MultiSummaryProvider(R.string.dont_check)
val warningPreference = findPreference<Preference>(AppSettings.KEY_TRACK_WARNING)
if (warningPreference != null) {
warningPreference.summary = buildSpannedString {
append(getString(R.string.tracker_warning))
append(" ")
inSpans(URLSpan("https://dontkillmyapp.com/")) {
append(getString(R.string.read_more))
}
}
warningPreference
}
} }
override fun onPreferenceTreeClick(preference: Preference?): Boolean { override fun onPreferenceTreeClick(preference: Preference?): Boolean {

@ -1,27 +1,41 @@
package org.koitharu.kotatsu.settings.backup package org.koitharu.kotatsu.settings.backup
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible import androidx.core.view.isVisible
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.base.ui.AlertDialogFragment
import org.koitharu.kotatsu.databinding.DialogProgressBinding import org.koitharu.kotatsu.databinding.DialogProgressBinding
import org.koitharu.kotatsu.utils.ShareHelper
import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.progress.Progress import org.koitharu.kotatsu.utils.progress.Progress
import java.io.File import java.io.File
import java.io.FileOutputStream
class BackupDialogFragment : AlertDialogFragment<DialogProgressBinding>() { class BackupDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
private val viewModel by viewModel<BackupViewModel>(mode = LazyThreadSafetyMode.NONE) private val viewModel by viewModel<BackupViewModel>(mode = LazyThreadSafetyMode.NONE)
private var backup: File? = null
private val saveFileContract =
registerForActivityResult(ActivityResultContracts.CreateDocument()) { uri ->
val file = backup
if (uri != null && file != null) {
saveBackup(file, uri)
} else {
dismiss()
}
}
override fun onInflateView( override fun onInflateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup? container: ViewGroup?,
) = DialogProgressBinding.inflate(inflater, container, false) ) = DialogProgressBinding.inflate(inflater, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -60,8 +74,22 @@ class BackupDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
} }
private fun onBackupDone(file: File) { private fun onBackupDone(file: File) {
ShareHelper(context ?: return).shareBackup(file) this.backup = file
dismiss() saveFileContract.launch(file.name)
}
private fun saveBackup(file: File, output: Uri) {
try {
requireContext().contentResolver.openFileDescriptor(output, "w")?.use { fd ->
FileOutputStream(fd.fileDescriptor).use {
it.write(file.readBytes())
}
}
Toast.makeText(requireContext(), R.string.backup_saved, Toast.LENGTH_LONG).show()
dismiss()
} catch (e: Exception) {
onError(e)
}
} }
companion object { companion object {

@ -0,0 +1,23 @@
package org.koitharu.kotatsu.settings.utils
import android.content.Context
import android.text.method.LinkMovementMethod
import android.util.AttributeSet
import android.widget.TextView
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
class LinksPreference @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = androidx.preference.R.attr.preferenceStyle,
defStyleRes: Int = 0,
) : Preference(context, attrs, defStyleAttr, defStyleRes) {
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val summaryView = holder.findViewById(android.R.id.summary) as TextView
summaryView.movementMethod = LinkMovementMethod.getInstance()
}
}

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeightSmall"
android:background="?selectableItemBackground"
android:drawablePadding="20dp"
android:gravity="center_vertical"
android:paddingStart="?listPreferredItemPaddingStart"
android:paddingEnd="?listPreferredItemPaddingEnd"
android:textAppearance="?textAppearanceListItemSmall"
android:textColor="?android:textColorPrimary"
android:theme="@style/ThemeOverlay.Kotatsu"
app:drawableStartCompat="@drawable/ic_history"
tools:text="@tools:sample/full_names" />

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/ic_denied_large,@drawable/ic_alert_outline,@drawable/ic_error_large" />

@ -214,4 +214,7 @@
<string name="languages">Языки</string> <string name="languages">Языки</string>
<string name="welcome">Добро пожаловать</string> <string name="welcome">Добро пожаловать</string>
<string name="text_clear_search_history_prompt">Вы действительно хотите удалить все недавние поисковые запросы? Это действие не может быть отменено.</string> <string name="text_clear_search_history_prompt">Вы действительно хотите удалить все недавние поисковые запросы? Это действие не может быть отменено.</string>
<string name="backup_saved">Резервная копия успешно сохранена</string>
<string name="tracker_warning">Некоторые производители могут изменять поведение системы, нарушая работу фоновых задач.</string>
<string name="read_more">Подробнее</string>
</resources> </resources>

@ -217,4 +217,7 @@
<string name="languages">Languages</string> <string name="languages">Languages</string>
<string name="welcome">Welcome</string> <string name="welcome">Welcome</string>
<string name="description">Description</string> <string name="description">Description</string>
<string name="backup_saved">Backup saved successfully</string>
<string name="tracker_warning">Some manufacturers can change the system behavior, which may breaks background tasks.</string>
<string name="read_more">Read more</string>
</resources> </resources>

@ -16,7 +16,7 @@
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<Preference <Preference
android:icon="@drawable/ic_info_outilne" android:icon="@drawable/ic_info_outline"
android:persistent="false" android:persistent="false"
android:selectable="false" android:selectable="false"
android:summary="@string/backup_information" android:summary="@string/backup_information"

@ -24,4 +24,12 @@
android:title="@string/notifications_settings" android:title="@string/notifications_settings"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<org.koitharu.kotatsu.settings.utils.LinksPreference
android:key="track_warning"
android:icon="@drawable/ic_info_outline"
android:persistent="false"
android:selectable="false"
android:summary="@string/tracker_warning"
app:allowDividerAbove="true" />
</PreferenceScreen> </PreferenceScreen>

@ -5,7 +5,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.3' classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

@ -1,7 +1,7 @@
#Mon Mar 29 19:25:53 EEST 2021 #Sat Jul 03 12:50:59 EEST 2021
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
distributionSha256Sum=7faa7198769f872826c8ef4f1450f839ec27f0b4d5d1e51bade63667cbccd205 distributionSha256Sum=765442b8069c6bee2ea70713861c027587591c6b1df2c857a23361512560894e

Loading…
Cancel
Save