更新界面
增加首次进入引导界面
This commit is contained in:
@@ -133,10 +133,12 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.welcome.WelcomeActivity"
|
||||
android:exported="false" />
|
||||
<!-- 阅读界面 -->
|
||||
<activity
|
||||
android:name=".ui.book.read.ReadBookActivity"
|
||||
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# 免责声明(Disclaimer)
|
||||
|
||||
* 阅读是一款解析指定规则并获取内容的工具,为广大网络文学爱好者提供一种方便、快捷舒适的试读体验。
|
||||
* 当您搜索一本书的时,阅读会您所使用的规则将该书的书名以关键词的形式提交到各个第三方网络文学网站。
|
||||
各第三方网站返回的内容与阅读无关,阅读对其概不负责,亦不承担任何法律责任。
|
||||
|
||||
@@ -204,7 +204,7 @@ object PreferKey {
|
||||
const val mangaClickActionBL = "mangaClickActionBottomLeft"
|
||||
const val mangaClickActionBC = "mangaClickActionBottomCenter"
|
||||
const val mangaClickActionBR = "mangaClickActionBottomRight"
|
||||
|
||||
const val isFirstLaunch = "isFirstLaunch"
|
||||
const val permissionChecked = "permissionChecked"
|
||||
const val notificationsPost = "notificationsPost"
|
||||
const val ignoreBatteryPermission = "ignoreBatteryPermission"
|
||||
|
||||
@@ -149,6 +149,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
var isFirstLaunch: Boolean
|
||||
get() = appCtx.getPrefBoolean(PreferKey.isFirstLaunch, true)
|
||||
set(value) {
|
||||
appCtx.putPrefBoolean(PreferKey.isFirstLaunch, value)
|
||||
}
|
||||
|
||||
var showUnread: Boolean
|
||||
get() = appCtx.getPrefBoolean(PreferKey.showUnread, true)
|
||||
set(value) {
|
||||
|
||||
@@ -24,7 +24,7 @@ class ThemeCardPreference(context: Context, attrs: AttributeSet) : Preference(co
|
||||
private var entries: Array<CharSequence> = context.resources.getTextArray(R.array.themes_item)
|
||||
private var entryValues: Array<CharSequence> = context.resources.getTextArray(R.array.themes_value).takeIf { it.isNotEmpty() }
|
||||
?: arrayOf("0")
|
||||
private var currentValue: String? = null
|
||||
private var currentValue = "0"
|
||||
|
||||
init {
|
||||
layoutResource = R.layout.preference_theme_card
|
||||
|
||||
@@ -2,9 +2,6 @@ package io.legato.kazusa.lib.prefs
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||
import io.legato.kazusa.R
|
||||
@@ -13,7 +10,7 @@ import io.legato.kazusa.help.config.ThemeConfig
|
||||
|
||||
class ThemeModePreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) {
|
||||
|
||||
private var currentValue: String? = null
|
||||
private var currentValue: String = "0"
|
||||
|
||||
init {
|
||||
layoutResource = R.layout.view_pref
|
||||
@@ -23,17 +20,21 @@ class ThemeModePreference(context: Context, attrs: AttributeSet) : Preference(co
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
super.onBindViewHolder(holder)
|
||||
|
||||
val toggleGroup = holder.itemView.findViewById<View>(R.id.theme_toggle_group)
|
||||
if (toggleGroup == null) {
|
||||
val rootView = holder.itemView as ViewGroup
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val themeToggleView = inflater.inflate(R.layout.view_theme_mode, rootView, false)
|
||||
rootView.addView(themeToggleView)
|
||||
val toggleGroup =
|
||||
holder.itemView.findViewById<MaterialButtonToggleGroup>(R.id.theme_toggle_group)
|
||||
?: return
|
||||
|
||||
setupToggleGroup(themeToggleView.findViewById(R.id.theme_toggle_group))
|
||||
// 根据 currentValue 设置选中
|
||||
when (currentValue) {
|
||||
"0" -> toggleGroup.check(R.id.btn_system)
|
||||
"1" -> toggleGroup.check(R.id.btn_light)
|
||||
"2" -> toggleGroup.check(R.id.btn_dark)
|
||||
}
|
||||
|
||||
setupToggleGroup(toggleGroup)
|
||||
}
|
||||
|
||||
|
||||
private fun setupToggleGroup(toggleGroup: MaterialButtonToggleGroup) {
|
||||
|
||||
when (currentValue) {
|
||||
@@ -65,8 +66,4 @@ class ThemeModePreference(context: Context, attrs: AttributeSet) : Preference(co
|
||||
currentValue = getPersistedString(defaultValue as? String ?: "0")
|
||||
}
|
||||
|
||||
override fun shouldDisableDependents(): Boolean {
|
||||
return currentValue == null || super.shouldDisableDependents()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +1,21 @@
|
||||
package io.legato.kazusa.ui.book.read.config
|
||||
|
||||
//import io.legado.app.lib.theme.bottomBackground
|
||||
//import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
//import io.legado.app.lib.theme.getSecondaryTextColor
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.widget.TooltipCompat
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.google.android.material.slider.Slider
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.BaseBottomSheetDialogFragment
|
||||
import io.legato.kazusa.base.BaseDialogFragment
|
||||
import io.legato.kazusa.constant.AppLog
|
||||
import io.legato.kazusa.constant.EventBus
|
||||
import io.legato.kazusa.databinding.DialogEditTextBinding
|
||||
@@ -29,9 +28,6 @@ import io.legato.kazusa.help.http.okHttpClient
|
||||
import io.legato.kazusa.lib.dialogs.SelectItem
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
import io.legato.kazusa.lib.dialogs.selector
|
||||
//import io.legado.app.lib.theme.bottomBackground
|
||||
//import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
//import io.legado.app.lib.theme.getSecondaryTextColor
|
||||
import io.legato.kazusa.ui.book.read.ReadBookActivity
|
||||
import io.legato.kazusa.ui.file.HandleFileContract
|
||||
import io.legato.kazusa.utils.FileUtils
|
||||
@@ -116,22 +112,6 @@ class BgTextConfigDialog : BaseBottomSheetDialogFragment(R.layout.dialog_read_bg
|
||||
}
|
||||
|
||||
private fun initView() = binding.run {
|
||||
// val bg = requireContext().bottomBackground
|
||||
// val isLight = ColorUtils.isColorLight(bg)
|
||||
// primaryTextColor = requireContext().getPrimaryTextColor(isLight)
|
||||
// secondaryTextColor = requireContext().getSecondaryTextColor(isLight)
|
||||
// rootView.setBackgroundColor(bg)
|
||||
// tvNameTitle.setTextColor(primaryTextColor)
|
||||
// tvName.setTextColor(secondaryTextColor)
|
||||
// ivEdit.setColorFilter(secondaryTextColor, PorterDuff.Mode.SRC_IN)
|
||||
// tvRestore.setTextColor(primaryTextColor)
|
||||
// swDarkStatusIcon.setTextColor(primaryTextColor)
|
||||
// swUnderline.setTextColor(primaryTextColor)
|
||||
// ivImport.setColorFilter(primaryTextColor, PorterDuff.Mode.SRC_IN)
|
||||
// ivExport.setColorFilter(primaryTextColor, PorterDuff.Mode.SRC_IN)
|
||||
// ivDelete.setColorFilter(primaryTextColor, PorterDuff.Mode.SRC_IN)
|
||||
// tvBgAlpha.setTextColor(primaryTextColor)
|
||||
// tvBgImage.setTextColor(primaryTextColor)
|
||||
recyclerView.adapter = adapter
|
||||
adapter.addHeaderView {
|
||||
ItemBgImageBinding.inflate(layoutInflater, it, false).apply {
|
||||
|
||||
@@ -230,14 +230,14 @@ class ReadStyleDialog : BaseBottomSheetDialogFragment(R.layout.dialog_read_book_
|
||||
llStyle.gravity = Gravity.TOP
|
||||
cdStyle.cardElevation = 1f.dpToPx()
|
||||
cdStyle.radius = 16f.dpToPx()
|
||||
cdStyle.strokeWidth = 2
|
||||
cdStyle.strokeColor = item.curTextColor()
|
||||
cdStyle.strokeWidth = 1.dpToPx()
|
||||
//cdStyle.strokeColor = item.curTextColor()
|
||||
//tvStyle.setTextBold(true)
|
||||
} else {
|
||||
cdStyle.cardElevation = 2f.dpToPx()
|
||||
cdStyle.radius = 32f.dpToPx()
|
||||
cdStyle.strokeWidth = 0
|
||||
cdStyle.strokeColor = item.curTextColor()
|
||||
//cdStyle.strokeColor = item.curTextColor()
|
||||
//tvStyle.setTextBold(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package io.legato.kazusa.ui.config
|
||||
|
||||
//import io.legado.app.lib.theme.primaryColor
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.SeekBar
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import io.legato.kazusa.R
|
||||
@@ -23,10 +21,8 @@ import io.legato.kazusa.help.config.ThemeConfig
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
import io.legato.kazusa.lib.dialogs.selector
|
||||
import io.legato.kazusa.lib.prefs.ColorPreference
|
||||
import io.legato.kazusa.lib.prefs.NameListPreference
|
||||
import io.legato.kazusa.lib.prefs.ThemeCardPreference
|
||||
import io.legato.kazusa.lib.prefs.ThemeModePreference
|
||||
//import io.legado.app.lib.theme.primaryColor
|
||||
import io.legato.kazusa.ui.widget.number.NumberPickerDialog
|
||||
import io.legato.kazusa.ui.widget.seekbar.SeekBarChangeListener
|
||||
import io.legato.kazusa.utils.ColorUtils
|
||||
@@ -72,9 +68,6 @@ class ThemeConfigFragment : PreferenceFragmentCompat(),
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_config_theme)
|
||||
if (Build.VERSION.SDK_INT < 26) {
|
||||
preferenceScreen.removePreferenceRecursively(PreferKey.launcherIcon)
|
||||
}
|
||||
|
||||
upPreferenceSummary(PreferKey.bgImage, getPrefString(PreferKey.bgImage))
|
||||
upPreferenceSummary(PreferKey.bgImageN, getPrefString(PreferKey.bgImageN))
|
||||
|
||||
@@ -26,7 +26,6 @@ import io.legato.kazusa.constant.AppConst.appInfo
|
||||
import io.legato.kazusa.constant.EventBus
|
||||
import io.legato.kazusa.constant.PreferKey
|
||||
import io.legato.kazusa.databinding.ActivityMainBinding
|
||||
import io.legato.kazusa.databinding.DialogEditTextBinding
|
||||
import io.legato.kazusa.help.AppWebDav
|
||||
import io.legato.kazusa.help.book.BookHelp
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
@@ -43,6 +42,7 @@ import io.legato.kazusa.ui.main.bookshelf.books.BookshelfFragment3
|
||||
import io.legato.kazusa.ui.main.explore.ExploreFragment
|
||||
import io.legato.kazusa.ui.main.my.MyFragment
|
||||
import io.legato.kazusa.ui.main.rss.RssFragment
|
||||
import io.legato.kazusa.ui.welcome.WelcomeActivity
|
||||
import io.legato.kazusa.ui.widget.dialog.TextDialog
|
||||
import io.legato.kazusa.utils.gone
|
||||
import io.legato.kazusa.utils.hideSoftInput
|
||||
@@ -51,6 +51,7 @@ import io.legato.kazusa.utils.observeEvent
|
||||
import io.legato.kazusa.utils.setNavigationBarColorAuto
|
||||
import io.legato.kazusa.utils.shouldHideSoftInput
|
||||
import io.legato.kazusa.utils.showDialogFragment
|
||||
import io.legato.kazusa.utils.startActivity
|
||||
import io.legato.kazusa.utils.themeColor
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
@@ -100,6 +101,12 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (AppConfig.isFirstLaunch) {
|
||||
startActivity<WelcomeActivity>()
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
if (pagePosition != 0) {
|
||||
binding.viewPagerMain.currentItem = 0
|
||||
@@ -145,12 +152,9 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
||||
super.onPostCreate(savedInstanceState)
|
||||
lifecycleScope.launch {
|
||||
//隐私协议
|
||||
if (!privacyPolicy()) return@launch
|
||||
//版本更新
|
||||
upVersion()
|
||||
//设置本地密码
|
||||
setLocalPassword()
|
||||
notifyAppCrash()
|
||||
//备份同步
|
||||
backupSync()
|
||||
@@ -217,27 +221,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
||||
window.setNavigationBarColorAuto(themeColor(com.google.android.material.R.attr.colorSurfaceContainer))
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户隐私与协议
|
||||
*/
|
||||
private suspend fun privacyPolicy(): Boolean = suspendCoroutine { block ->
|
||||
if (LocalConfig.privacyPolicyOk) {
|
||||
block.resume(true)
|
||||
return@suspendCoroutine
|
||||
}
|
||||
val privacyPolicy = String(assets.open("privacyPolicy.md").readBytes())
|
||||
alert(getString(R.string.privacy_policy), privacyPolicy) {
|
||||
positiveButton(R.string.agree) {
|
||||
LocalConfig.privacyPolicyOk = true
|
||||
block.resume(true)
|
||||
}
|
||||
negativeButton(R.string.refuse) {
|
||||
finish()
|
||||
block.resume(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本更新日志
|
||||
*/
|
||||
@@ -269,29 +252,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
||||
/**
|
||||
* 设置本地密码
|
||||
*/
|
||||
private suspend fun setLocalPassword() = suspendCoroutine { block ->
|
||||
if (LocalConfig.password != null) {
|
||||
block.resume(null)
|
||||
return@suspendCoroutine
|
||||
}
|
||||
alert(R.string.set_local_password, R.string.set_local_password_summary) {
|
||||
val editTextBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
|
||||
editView.hint = "password"
|
||||
}
|
||||
customView {
|
||||
editTextBinding.root
|
||||
}
|
||||
onDismiss {
|
||||
block.resume(null)
|
||||
}
|
||||
okButton {
|
||||
LocalConfig.password = editTextBinding.editView.text.toString()
|
||||
}
|
||||
cancelButton {
|
||||
LocalConfig.password = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyAppCrash() {
|
||||
if (!LocalConfig.appCrash || BuildConfig.DEBUG) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.legato.kazusa.ui.welcome
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.BaseFragment
|
||||
import io.legato.kazusa.databinding.FragmentPrivacyBinding
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
|
||||
class PrivacyFragment : BaseFragment(R.layout.fragment_privacy) {
|
||||
|
||||
private val binding by viewBinding(FragmentPrivacyBinding::bind)
|
||||
|
||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
||||
binding.tvPrivacy.text =
|
||||
String(requireContext().assets.open("privacyPolicy.md").readBytes())
|
||||
binding.tvDisclaimer.text =
|
||||
String(requireContext().assets.open("disclaimer.md").readBytes())
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.legato.kazusa.ui.welcome
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.constant.PreferKey
|
||||
import io.legato.kazusa.lib.prefs.ThemeCardPreference
|
||||
import io.legato.kazusa.lib.prefs.ThemeModePreference
|
||||
|
||||
class ThemeFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.pref_strat_theme, rootKey)
|
||||
|
||||
findPreference<ThemeModePreference>(PreferKey.themeMode)?.let {
|
||||
it.setOnPreferenceChangeListener { _, _ ->
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
findPreference<ThemeCardPreference>(PreferKey.themePref)?.let {
|
||||
it.setOnPreferenceChangeListener { _, _ ->
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package io.legato.kazusa.ui.welcome
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.BaseFragment
|
||||
import io.legato.kazusa.constant.AppLog
|
||||
import io.legato.kazusa.constant.PreferKey
|
||||
import io.legato.kazusa.databinding.FragmentWebdavAuthBinding
|
||||
import io.legato.kazusa.exception.NoStackTraceException
|
||||
import io.legato.kazusa.help.AppWebDav
|
||||
import io.legato.kazusa.help.AppWebDav.testWebDav
|
||||
import io.legato.kazusa.help.config.LocalConfig
|
||||
import io.legato.kazusa.help.coroutine.Coroutine
|
||||
import io.legato.kazusa.help.storage.Restore
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
import io.legato.kazusa.lib.dialogs.selector
|
||||
import io.legato.kazusa.ui.file.HandleFileContract
|
||||
import io.legato.kazusa.ui.widget.dialog.WaitDialog
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import splitties.init.appCtx
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
class WebDavFragment : BaseFragment(R.layout.fragment_webdav_auth) {
|
||||
|
||||
private var _binding: FragmentWebdavAuthBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var restoreJob: Job? = null
|
||||
private val waitDialog by lazy { WaitDialog(requireContext()) }
|
||||
|
||||
private val restoreDoc = registerForActivityResult(HandleFileContract()) {
|
||||
it.uri?.let { uri ->
|
||||
waitDialog.setText("恢复中…")
|
||||
waitDialog.show()
|
||||
val task = Coroutine.async {
|
||||
Restore.restore(appCtx, uri)
|
||||
}.onFinally {
|
||||
waitDialog.dismiss()
|
||||
}
|
||||
waitDialog.setOnCancelListener {
|
||||
task.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentWebdavAuthBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
|
||||
val urls = listOf(
|
||||
"https://dav.jianguoyun.com/dav/",
|
||||
"https://webdav.aliyundrive.com/",
|
||||
"https://dav.example.com/"
|
||||
)
|
||||
|
||||
val adapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
urls
|
||||
)
|
||||
|
||||
binding.editUrl.setAdapter(adapter)
|
||||
|
||||
binding.editAccount.setText(prefs.getString(PreferKey.webDavAccount, ""))
|
||||
binding.editPassword.setText(prefs.getString(PreferKey.webDavPassword, ""))
|
||||
binding.editPassword.inputType =
|
||||
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|
||||
binding.etPassword.setText(LocalConfig.password ?: "")
|
||||
|
||||
binding.etPassword.doAfterTextChanged {
|
||||
LocalConfig.password = it.toString()
|
||||
}
|
||||
|
||||
binding.btnCheck.setOnClickListener {
|
||||
saveWebDavConfig()
|
||||
|
||||
lifecycleScope.launch {
|
||||
testWebDav()
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnRestore.setOnClickListener {
|
||||
restore()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun saveWebDavConfig(onSaved: (() -> Unit)? = null) {
|
||||
val url = binding.editUrl.text.toString()
|
||||
val account = binding.editAccount.text.toString()
|
||||
val password = binding.editPassword.text.toString()
|
||||
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
||||
putString(PreferKey.webDavUrl, url)
|
||||
putString(PreferKey.webDavAccount, account)
|
||||
putString(PreferKey.webDavPassword, password)
|
||||
}
|
||||
|
||||
onSaved?.invoke()
|
||||
}
|
||||
|
||||
fun restore() {
|
||||
waitDialog.setText(R.string.loading)
|
||||
waitDialog.setOnCancelListener {
|
||||
restoreJob?.cancel()
|
||||
}
|
||||
waitDialog.show()
|
||||
Coroutine.async {
|
||||
restoreJob = coroutineContext[Job]
|
||||
showRestoreDialog(requireContext())
|
||||
}.onError {
|
||||
AppLog.put("恢复备份出错WebDavError\n${it.localizedMessage}", it)
|
||||
if (context == null) {
|
||||
return@onError
|
||||
}
|
||||
alert {
|
||||
setTitle(R.string.restore)
|
||||
setMessage("WebDavError\n${it.localizedMessage}\n将从本地备份恢复。")
|
||||
okButton {
|
||||
restoreFromLocal()
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}.onFinally {
|
||||
waitDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun showRestoreDialog(context: Context) {
|
||||
val names = withContext(IO) { AppWebDav.getBackupNames() }
|
||||
if (AppWebDav.isJianGuoYun && names.size > 700) {
|
||||
context.toastOnUi("由于坚果云限制列出文件数量,部分备份可能未显示,请及时清理旧备份")
|
||||
}
|
||||
if (names.isNotEmpty()) {
|
||||
coroutineContext.ensureActive()
|
||||
withContext(Main) {
|
||||
context.selector(
|
||||
title = context.getString(R.string.select_restore_file),
|
||||
items = names
|
||||
) { _, index ->
|
||||
if (index in names.indices) {
|
||||
restoreWebDav(names[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw NoStackTraceException("Web dav no back up file")
|
||||
}
|
||||
}
|
||||
|
||||
private fun restoreWebDav(name: String) {
|
||||
waitDialog.setText("恢复中…")
|
||||
waitDialog.show()
|
||||
val task = Coroutine.async {
|
||||
AppWebDav.restoreWebDav(name)
|
||||
}.onError {
|
||||
AppLog.put("WebDav恢复出错\n${it.localizedMessage}", it)
|
||||
appCtx.toastOnUi("WebDav恢复出错\n${it.localizedMessage}")
|
||||
}.onFinally {
|
||||
waitDialog.dismiss()
|
||||
}
|
||||
waitDialog.setOnCancelListener {
|
||||
task.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private fun restoreFromLocal() {
|
||||
restoreDoc.launch {
|
||||
title = getString(R.string.select_restore_file)
|
||||
mode = HandleFileContract.FILE
|
||||
allowExtensions = arrayOf("zip")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -1,86 +1,101 @@
|
||||
package io.legato.kazusa.ui.welcome
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.core.view.postDelayed
|
||||
import androidx.activity.addCallback
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import io.legato.kazusa.base.BaseActivity
|
||||
import io.legato.kazusa.constant.PreferKey
|
||||
import io.legato.kazusa.constant.Theme
|
||||
import io.legato.kazusa.databinding.ActivityWelcomeBinding
|
||||
import io.legato.kazusa.help.config.ThemeConfig
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
//import io.legado.app.lib.theme.backgroundColor
|
||||
import io.legato.kazusa.ui.book.read.ReadBookActivity
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
import io.legato.kazusa.help.config.LocalConfig
|
||||
import io.legato.kazusa.ui.main.MainActivity
|
||||
import io.legato.kazusa.utils.*
|
||||
import io.legato.kazusa.utils.startActivity
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
|
||||
open class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
||||
class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
||||
|
||||
override val binding by viewBinding(ActivityWelcomeBinding::inflate)
|
||||
|
||||
private val pages = listOf(
|
||||
PrivacyFragment(),
|
||||
WebDavFragment(),
|
||||
ThemeFragment()
|
||||
)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// binding.ivBook.setColorFilter(accentColor)
|
||||
// binding.vwTitleLine.setBackgroundColor(accentColor)
|
||||
// 避免从桌面启动程序后,会重新实例化入口类的activity
|
||||
if (intent.flags and Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT != 0) {
|
||||
finish()
|
||||
} else {
|
||||
binding.root.postDelayed(100) { startMainActivity() }
|
||||
}
|
||||
}
|
||||
|
||||
// override fun setupSystemBar() {
|
||||
// fullScreen()
|
||||
// //setStatusBarColorAuto(backgroundColor, true, fullScreen)
|
||||
// upNavigationBarColor()
|
||||
// }
|
||||
|
||||
override fun upBackgroundImage() {
|
||||
if (getPrefBoolean(PreferKey.customWelcome)) {
|
||||
kotlin.runCatching {
|
||||
when (ThemeConfig.getTheme()) {
|
||||
Theme.Dark -> getPrefString(PreferKey.welcomeImageDark)?.let { path ->
|
||||
val size = windowManager.windowSize
|
||||
BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let {
|
||||
binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowTextDark))
|
||||
binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIconDark))
|
||||
binding.tvGzh.visible(getPrefBoolean(PreferKey.welcomeShowTextDark))
|
||||
window.decorView.background = BitmapDrawable(resources, it)
|
||||
return
|
||||
}
|
||||
}
|
||||
else -> getPrefString(PreferKey.welcomeImage)?.let { path ->
|
||||
val size = windowManager.windowSize
|
||||
BitmapUtils.decodeBitmap(path, size.widthPixels, size.heightPixels).let {
|
||||
binding.tvLegado.visible(getPrefBoolean(PreferKey.welcomeShowText))
|
||||
binding.ivBook.visible(getPrefBoolean(PreferKey.welcomeShowIcon))
|
||||
binding.tvGzh.visible(getPrefBoolean(PreferKey.welcomeShowText))
|
||||
window.decorView.background = BitmapDrawable(resources, it)
|
||||
return
|
||||
}
|
||||
}
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
val current = binding.viewPager.currentItem
|
||||
if (current > 0) {
|
||||
binding.viewPager.currentItem = current - 1
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress(0)
|
||||
|
||||
binding.viewPager.adapter = object : FragmentStateAdapter(this) {
|
||||
override fun getItemCount() = pages.size
|
||||
override fun createFragment(position: Int) = pages[position]
|
||||
}
|
||||
|
||||
binding.viewPager.isUserInputEnabled = false
|
||||
|
||||
binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
binding.btnNext.text = when (position) {
|
||||
0 -> "阅读并同意" // PrivacyFragment
|
||||
pages.lastIndex -> "完成"
|
||||
else -> "下一步"
|
||||
}
|
||||
binding.tvTitle.text = when (position) {
|
||||
0 -> "欢迎!" // PrivacyFragment
|
||||
1 -> "备份与恢复"
|
||||
else -> "主题样式"
|
||||
}
|
||||
binding.tvSummary.text = when (position) {
|
||||
0 -> "请先阅读应用的服务条款与用户协议。"
|
||||
1 -> "此处可设置云同步与恢复应用备份。"
|
||||
else -> "在这里设置您喜爱的样式。"
|
||||
}
|
||||
updateProgress(position)
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化按钮文字
|
||||
binding.btnNext.text = "阅读并同意"
|
||||
|
||||
binding.btnNext.setOnClickListener {
|
||||
val current = binding.viewPager.currentItem
|
||||
when (current) {
|
||||
0 -> {
|
||||
LocalConfig.privacyPolicyOk = true
|
||||
binding.viewPager.currentItem = 1
|
||||
}
|
||||
|
||||
pages.lastIndex -> {
|
||||
updateProgress(2)
|
||||
finishSetup()
|
||||
}
|
||||
|
||||
else -> binding.viewPager.currentItem = current + 1
|
||||
}
|
||||
}
|
||||
super.upBackgroundImage()
|
||||
}
|
||||
|
||||
private fun startMainActivity() {
|
||||
private fun updateProgress(position: Int) {
|
||||
val progressMax = pages.size
|
||||
val progress = (position * 100 / progressMax)
|
||||
binding.progressBar.setProgress(progress, true)
|
||||
}
|
||||
|
||||
private fun finishSetup() {
|
||||
AppConfig.isFirstLaunch = false
|
||||
startActivity<MainActivity>()
|
||||
if (getPrefBoolean(PreferKey.defaultToRead)) {
|
||||
startActivity<ReadBookActivity>()
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Launcher1 : WelcomeActivity()
|
||||
class Launcher2 : WelcomeActivity()
|
||||
class Launcher3 : WelcomeActivity()
|
||||
class Launcher4 : WelcomeActivity()
|
||||
class Launcher5 : WelcomeActivity()
|
||||
class Launcher6 : WelcomeActivity()
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?attr/colorPrimaryContainer" android:state_checked="true" />
|
||||
<item android:color="?attr/colorSurfaceContainerLow" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?attr/colorPrimaryContainer" android:state_checked="true" />
|
||||
<item android:color="?attr/colorOutlineVariant" />
|
||||
</selector>
|
||||
@@ -33,6 +33,8 @@
|
||||
android:id="@+id/refresh_progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:waveAmplitude="8dp"
|
||||
app:wavelength="80dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone">
|
||||
|
||||
|
||||
@@ -1,82 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal">
|
||||
android:animateLayoutChanges="true"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/tv_legado"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintVertical_bias="0.4"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iv_book">
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<View
|
||||
android:id="@+id/vw_title_line"
|
||||
android:layout_width="6dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@color/md_theme_primary"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_title"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
<ImageView
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="48dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_launcher_foreground" />
|
||||
|
||||
<io.legato.kazusa.ui.widget.text.AccentTextView
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:ems="1"
|
||||
android:text="阅读"
|
||||
android:textSize="49sp"
|
||||
app:layout_constraintRight_toLeftOf="@+id/tv_sub_title"
|
||||
app:layout_constraintLeft_toRightOf="@+id/vw_title_line"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="HardcodedText,RtlHardcoded" />
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:text="欢迎!"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<io.legato.kazusa.ui.widget.text.AccentTextView
|
||||
android:id="@+id/tv_sub_title"
|
||||
android:layout_width="wrap_content"
|
||||
<TextView
|
||||
android:id="@+id/tv_summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="60dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:ems="1"
|
||||
android:text="享受美好时光"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_title"
|
||||
app:layout_constraintLeft_toRightOf="@id/tv_title"
|
||||
tools:ignore="HardcodedText,RtlHardcoded" />
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="请先阅读应用的服务条款与用户协议。"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:indicatorColor="?attr/colorSecondary"
|
||||
app:waveAmplitude="4dp"
|
||||
app:waveSpeed="32dp"
|
||||
app:wavelength="80dp" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_weight="1"
|
||||
app:layout_constraintBottom_toTopOf="@id/btnNext"
|
||||
app:layout_constraintTop_toBottomOf="@id/ll_info" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_book"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:src="@drawable/icon_read_book"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="@string/welcome"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tv_gzh"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<io.legato.kazusa.ui.widget.text.AccentTextView
|
||||
android:id="@+id/tv_gzh"
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/btnNext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="关注公众号[开源阅读]\n看文章点广告支持作者"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_gravity="end"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/text"
|
||||
app:icon="@drawable/ic_arrow_right"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
tools:ignore="HardcodedText" />
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -50,66 +50,70 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_name_title"
|
||||
tools:text="文字" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_edit"
|
||||
style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
|
||||
<com.google.android.material.button.MaterialButtonGroup
|
||||
android:id="@+id/mbg_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:contentDescription="@string/edit"
|
||||
app:iconGravity="textStart"
|
||||
app:icon="@drawable/ic_edit"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tv_name"
|
||||
app:layout_constraintEnd_toStartOf="@id/iv_delete"
|
||||
app:layout_constraintTop_toTopOf="@id/tv_name" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_delete"
|
||||
style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/delete"
|
||||
app:icon="@drawable/ic_clear_all"
|
||||
app:layout_constraintBottom_toBottomOf="@id/iv_edit"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_edit"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
app:layout_constraintTop_toTopOf="@id/tv_name">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/tv_restore"
|
||||
android:layout_width="wrap_content"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/restore"
|
||||
app:icon="@drawable/ic_restore"
|
||||
app:layout_constraintEnd_toStartOf="@id/iv_import"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_edit" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_edit"
|
||||
style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/edit"
|
||||
app:icon="@drawable/ic_edit"
|
||||
app:iconGravity="textStart" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_import"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_delete"
|
||||
style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/delete"
|
||||
app:icon="@drawable/ic_clear_all"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
</com.google.android.material.button.MaterialButtonGroup>
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButtonGroup
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/import_str"
|
||||
android:text="@string/import_str"
|
||||
app:icon="@drawable/ic_import"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tv_restore"
|
||||
app:layout_constraintEnd_toStartOf="@id/iv_export"
|
||||
app:layout_constraintTop_toTopOf="@id/tv_restore" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_export"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/import_str"
|
||||
android:text="@string/export_str"
|
||||
app:icon="@drawable/ic_export"
|
||||
app:layout_constraintBottom_toBottomOf="@id/iv_import"
|
||||
android:layout_marginEnd="2dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_import" />
|
||||
app:layout_constraintTop_toBottomOf="@id/mbg_1">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/tv_restore"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/restore"
|
||||
app:icon="@drawable/ic_restore" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_import"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/import_str"
|
||||
android:text="@string/import_str"
|
||||
app:icon="@drawable/ic_import" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/iv_export"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/import_str"
|
||||
android:text="@string/export_str"
|
||||
app:icon="@drawable/ic_export" />
|
||||
|
||||
</com.google.android.material.button.MaterialButtonGroup>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -129,7 +133,7 @@
|
||||
android:text="@string/text_underline"
|
||||
tools:ignore="TouchTargetSizeCheck" />
|
||||
|
||||
<LinearLayout
|
||||
<com.google.android.material.button.MaterialButtonGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
@@ -141,7 +145,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_weight="1"
|
||||
app:icon="@drawable/ic_palette"
|
||||
android:text="@string/text_color"
|
||||
@@ -159,7 +163,7 @@
|
||||
android:text="@string/bg_color"
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.button.MaterialButtonGroup>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_bg_alpha"
|
||||
@@ -189,7 +193,7 @@
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingVertical="8dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_bg_image" />
|
||||
|
||||
@@ -272,45 +272,37 @@
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/rb_anim0"
|
||||
style="@style/Widget.Material3.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkable="true"
|
||||
android:text="@string/page_anim_cover" />
|
||||
|
||||
<!-- 滑动动画 Chip -->
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/rb_anim1"
|
||||
style="@style/Widget.Material3.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:checkable="true"
|
||||
android:text="@string/page_anim_slide" />
|
||||
|
||||
<!-- 仿真翻页 Chip -->
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/rb_simulation_anim"
|
||||
style="@style/Widget.Material3.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:checkable="true"
|
||||
android:text="@string/page_anim_simulation" />
|
||||
|
||||
<!-- 滚动动画 Chip -->
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/rb_scroll_anim"
|
||||
style="@style/Widget.Material3.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:checkable="true"
|
||||
android:text="@string/page_anim_scroll" />
|
||||
|
||||
<!-- 无动画 Chip -->
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/rb_no_anim"
|
||||
style="@style/Widget.Material3.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:checkable="true"
|
||||
android:text="@string/page_anim_none" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/privacy_policy"
|
||||
android:textColor="?attr/colorSecondary"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPrivacy"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/text" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/disclaimer"
|
||||
android:textColor="?attr/colorSecondary"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDisclaimer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/text" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:hint="@string/web_dav_url">
|
||||
|
||||
<com.google.android.material.textfield.MaterialAutoCompleteTextView
|
||||
android:id="@+id/editUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:completionThreshold="1"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textUri" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:hint="@string/web_dav_account">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/editAccount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_local_password" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:hint="@string/web_dav_pw"
|
||||
app:endIconMode="password_toggle">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/editPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_local_password" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnRestore"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_weight="2"
|
||||
android:text="获取备份" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnCheck"
|
||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/action_save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/set_local_password_summary"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/set_local_password">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/etPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -7,6 +7,7 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cd_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
@@ -104,6 +104,8 @@
|
||||
style="@style/Widget.Material3.LinearProgressIndicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:waveAmplitude="8dp"
|
||||
app:wavelength="80dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_download" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/ll_style"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -9,6 +10,8 @@
|
||||
android:id="@+id/cd_style"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
app:strokeColor="?attr/colorOutlineVariant"
|
||||
app:strokeWidth="2dp"
|
||||
android:layout_margin="4dp"
|
||||
android:foreground="?android:attr/selectableItemBackground">
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
android:id="@+id/theme_toggle_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:spacing="2dp"
|
||||
app:innerCornerSize="8dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:gravity="center"
|
||||
app:singleSelection="true"
|
||||
app:selectionRequired="true">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_system"
|
||||
style="@style/Widget.Material3Expressive.Button"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
android:checkable="true"
|
||||
android:layout_width="0dp"
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_light"
|
||||
style="@style/Widget.Material3Expressive.Button"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
android:checkable="true"
|
||||
android:layout_width="0dp"
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_dark"
|
||||
style="@style/Widget.Material3Expressive.Button"
|
||||
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
android:checkable="true"
|
||||
android:layout_width="0dp"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
<item name="tabStyle">@style/Widget.App.TabLayout</item>
|
||||
<item name="chipStyle">@style/Widget.MyApp.Chip.Assist</item>
|
||||
<item name="popupMenuBackground">@drawable/popup_background</item>
|
||||
<item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
|
||||
</style>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<dimen name="fastscroll_bubble_padding">16dp</dimen>
|
||||
|
||||
<dimen name="fastscroll_handle_height">48dp</dimen>
|
||||
<dimen name="fastscroll_handle_width">16dp</dimen>
|
||||
<dimen name="fastscroll_handle_width">12dp</dimen>
|
||||
<dimen name="fastscroll_handle_radius">8dp</dimen>
|
||||
|
||||
<dimen name="fastscroll_track_width">8dp</dimen>
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
<item name="android:layout" tools:ignore="PrivateResource">@layout/m3_alert_dialog</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MyApp.Chip.Assist" parent="Widget.Material3.Chip.Assist">
|
||||
<item name="chipBackgroundColor">@color/chip_background_selector</item>
|
||||
<item name="chipStrokeColor">@color/chip_stroke_selector</item>
|
||||
</style>
|
||||
|
||||
<style name="TextActionMenuAnimation">
|
||||
<item name="android:windowEnterAnimation">@anim/popup_enter</item>
|
||||
<item name="android:windowExitAnimation">@anim/popup_exit</item>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
<item name="tabStyle">@style/Widget.App.TabLayout</item>
|
||||
<item name="chipStyle">@style/Widget.MyApp.Chip.Assist</item>
|
||||
<item name="popupMenuBackground">@drawable/popup_background</item>
|
||||
<item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<io.legato.kazusa.lib.prefs.ThemeModePreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/theme_mode"
|
||||
android:entryValues="@array/theme_mode_v"
|
||||
android:key="themeMode" />
|
||||
|
||||
<io.legato.kazusa.lib.prefs.ThemeCardPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/themes_item"
|
||||
android:entryValues="@array/themes_value"
|
||||
android:key="app_theme" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
@@ -1,17 +1,17 @@
|
||||
[versions]
|
||||
|
||||
datastorePreferences = "1.1.7"
|
||||
kotlin = "2.1.21"
|
||||
kotlin = "2.2.10"
|
||||
ksp = "2.1.21-2.0.1"
|
||||
agp = "8.12.0"
|
||||
agp = "8.12.1"
|
||||
appcompat = "1.7.1"
|
||||
colorpicker = "1.1.0"
|
||||
commonsText = "1.13.1"
|
||||
commonsText = "1.14.0"
|
||||
constraintlayout = "2.2.1"
|
||||
core = "1.16.0"
|
||||
firebaseBom = "34.0.0"
|
||||
core = "1.17.0"
|
||||
firebaseBom = "34.1.0"
|
||||
flexbox = "3.0.0"
|
||||
fragment = "1.8.8"
|
||||
fragment = "1.8.9"
|
||||
|
||||
#不要更新版本
|
||||
hutool = "5.8.22"
|
||||
@@ -28,7 +28,7 @@ jsoupxpath = "2.5.3"
|
||||
coroutines = "1.10.2"
|
||||
liveeventbus = "1.8.14"
|
||||
markwon = "4.6.2"
|
||||
material = "1.14.0-alpha03"
|
||||
material = "1.14.0-alpha04"
|
||||
media = "1.7.0"
|
||||
media3 = "1.7.1"
|
||||
nanoHttpd = "2.3.1"
|
||||
@@ -52,7 +52,7 @@ viewpager2 = "1.0.0"
|
||||
webkit = "1.14.0"
|
||||
collection = "1.5.0"
|
||||
|
||||
zxingLite = "3.2.0"
|
||||
zxingLite = "3.3.0"
|
||||
|
||||
|
||||
[libraries]
|
||||
|
||||
Reference in New Issue
Block a user