mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
Compare commits
12 Commits
cb06d149f7
...
5685d442ff
Author | SHA1 | Date | |
---|---|---|---|
|
5685d442ff | ||
|
94fb7564f1 | ||
|
11eb304fae | ||
|
33e9286a8e | ||
|
e57ad3a09e | ||
|
29a6b49d67 | ||
|
025dbcc3d4 | ||
|
10d2764c61 | ||
|
5b86fb8dd8 | ||
|
59d4bb6c8e | ||
|
85575111da | ||
|
f83a2bc357 |
@ -11,7 +11,6 @@ import io.legado.app.constant.PageAnim
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.help.DefaultData
|
||||
import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.ui.book.read.page.provider.ChapterProvider
|
||||
import io.legado.app.utils.BitmapUtils
|
||||
import io.legado.app.utils.FileUtils
|
||||
import io.legado.app.utils.GSON
|
||||
|
@ -133,7 +133,7 @@ public class QueryTTF {
|
||||
}
|
||||
|
||||
private static class GlyfLayout {
|
||||
public short numberOfContours; // 非负值为简单字型,负值为符合字型
|
||||
public short numberOfContours; // 非负值为简单字型,负值为复合字型
|
||||
public short xMin;
|
||||
public short yMin;
|
||||
public short xMax;
|
||||
|
@ -7,6 +7,7 @@ import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.os.PowerManager
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseService
|
||||
import io.legado.app.constant.AppConst
|
||||
@ -15,7 +16,16 @@ import io.legado.app.constant.IntentAction
|
||||
import io.legado.app.constant.NotificationId
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.receiver.NetworkChangedListener
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.NetworkUtils
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.getPrefInt
|
||||
import io.legado.app.utils.postEvent
|
||||
import io.legado.app.utils.printOnDebug
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.servicePendingIntent
|
||||
import io.legado.app.utils.startService
|
||||
import io.legado.app.utils.stopService
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.web.HttpServer
|
||||
import io.legado.app.web.WebSocketServer
|
||||
import splitties.init.appCtx
|
||||
@ -33,6 +43,11 @@ class WebService : BaseService() {
|
||||
context.startService<WebService>()
|
||||
}
|
||||
|
||||
fun startForeground(context: Context) {
|
||||
val intent = Intent(context, WebService::class.java)
|
||||
ContextCompat.startForegroundService(context, intent)
|
||||
}
|
||||
|
||||
fun stop(context: Context) {
|
||||
context.stopService<WebService>()
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
package io.legado.app.service
|
||||
|
||||
import android.app.Dialog
|
||||
import android.app.ForegroundServiceStartNotAllowedException
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import android.view.WindowManager.BadTokenException
|
||||
import androidx.annotation.RequiresApi
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.IntentAction
|
||||
import io.legado.app.utils.printOnDebug
|
||||
|
||||
@ -22,6 +26,7 @@ class WebTileService : TileService() {
|
||||
state = Tile.STATE_ACTIVE
|
||||
updateTile()
|
||||
}
|
||||
|
||||
IntentAction.stop -> qsTile?.run {
|
||||
state = Tile.STATE_INACTIVE
|
||||
updateTile()
|
||||
@ -49,7 +54,24 @@ class WebTileService : TileService() {
|
||||
if (WebService.isRun) {
|
||||
WebService.stop(this)
|
||||
} else {
|
||||
WebService.start(this)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
val dialog = Dialog(this, R.style.AppTheme_Transparent)
|
||||
dialog.setOnShowListener {
|
||||
try {
|
||||
WebService.startForeground(this)
|
||||
} catch (e: ForegroundServiceStartNotAllowedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
dialog.dismiss()
|
||||
}
|
||||
try {
|
||||
showDialog(dialog)
|
||||
} catch (e: BadTokenException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
WebService.start(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,6 @@ import io.legado.app.ui.replace.ReplaceRuleActivity
|
||||
import io.legado.app.ui.replace.edit.ReplaceEditActivity
|
||||
import io.legado.app.ui.widget.PopupAction
|
||||
import io.legado.app.ui.widget.dialog.PhotoDialog
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.utils.ACache
|
||||
import io.legado.app.utils.Debounce
|
||||
import io.legado.app.utils.LogUtils
|
||||
@ -114,6 +113,7 @@ import io.legado.app.utils.observeEvent
|
||||
import io.legado.app.utils.observeEventSticky
|
||||
import io.legado.app.utils.postEvent
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.sysScreenOffTime
|
||||
import io.legado.app.utils.throttle
|
||||
@ -553,7 +553,7 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
|
||||
R.id.menu_effective_replaces -> showDialogFragment<EffectiveReplacesDialog>()
|
||||
|
||||
R.id.menu_help -> showReadMenuHelp()
|
||||
R.id.menu_help -> showHelp()
|
||||
}
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
@ -1022,11 +1022,6 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun showReadMenuHelp() {
|
||||
val text = String(assets.open("web/help/md/readMenuHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示朗读菜单
|
||||
*/
|
||||
@ -1255,6 +1250,10 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun showHelp() {
|
||||
showHelp("readMenuHelp")
|
||||
}
|
||||
|
||||
/**
|
||||
* 长按图片
|
||||
*/
|
||||
|
@ -150,7 +150,7 @@ class ReadMenu @JvmOverloads constructor(
|
||||
}
|
||||
callBack.upSystemUiVisibility()
|
||||
if (!LocalConfig.readMenuHelpVersionIsLast) {
|
||||
callBack.showReadMenuHelp()
|
||||
callBack.showHelp()
|
||||
}
|
||||
}
|
||||
|
||||
@ -580,7 +580,7 @@ class ReadMenu @JvmOverloads constructor(
|
||||
fun showReadAloudDialog()
|
||||
fun upSystemUiVisibility()
|
||||
fun onClickReadAloud()
|
||||
fun showReadMenuHelp()
|
||||
fun showHelp()
|
||||
fun showLogin()
|
||||
fun payAction()
|
||||
fun disableSource()
|
||||
|
@ -17,8 +17,14 @@ import io.legado.app.ui.login.SourceLoginActivity
|
||||
import io.legado.app.ui.widget.code.addJsPattern
|
||||
import io.legado.app.ui.widget.code.addJsonPattern
|
||||
import io.legado.app.ui.widget.code.addLegadoPattern
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.GSON
|
||||
import io.legado.app.utils.applyTint
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setLayout
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
|
||||
class HttpTtsEditDialog() : BaseDialogFragment(R.layout.dialog_http_tts_edit, true),
|
||||
@ -111,7 +117,7 @@ class HttpTtsEditDialog() : BaseDialogFragment(R.layout.dialog_http_tts_edit, tr
|
||||
initView(it)
|
||||
}
|
||||
R.id.menu_log -> showDialogFragment<AppLogDialog>()
|
||||
R.id.menu_help -> help()
|
||||
R.id.menu_help -> showHelp("httpTTSHelp")
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -130,11 +136,4 @@ class HttpTtsEditDialog() : BaseDialogFragment(R.layout.dialog_http_tts_edit, tr
|
||||
)
|
||||
}
|
||||
|
||||
private fun help() {
|
||||
val helpStr = String(
|
||||
requireContext().assets.open("web/help/md/httpTTSHelp.md").readBytes()
|
||||
)
|
||||
showDialogFragment(TextDialog(getString(R.string.help), helpStr, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +1,15 @@
|
||||
package io.legado.app.ui.book.read.page
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Picture
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import androidx.core.graphics.withClip
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.config.ReadBookConfig
|
||||
import io.legado.app.lib.theme.ThemeStore
|
||||
import io.legado.app.ui.book.read.page.entities.PageDirection
|
||||
import io.legado.app.utils.screenshot
|
||||
import io.legado.app.utils.canvasrecorder.CanvasRecorderFactory
|
||||
import io.legado.app.utils.canvasrecorder.recordIfNeeded
|
||||
|
||||
/**
|
||||
* 自动翻页
|
||||
@ -24,13 +21,10 @@ class AutoPager(private val readView: ReadView) {
|
||||
private var scrollOffsetRemain = 0.0
|
||||
private var scrollOffset = 0
|
||||
private var lastTimeMillis = 0L
|
||||
private var bitmap: Bitmap? = null
|
||||
private var picture: Picture? = null
|
||||
private var pictureIsDirty = true
|
||||
private val atLeastApi23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
private val rect = Rect()
|
||||
private var canvasRecorder = CanvasRecorderFactory.create()
|
||||
private val paint by lazy { Paint() }
|
||||
|
||||
|
||||
fun start() {
|
||||
isRunning = true
|
||||
paint.color = ThemeStore.accentColor
|
||||
@ -48,7 +42,7 @@ class AutoPager(private val readView: ReadView) {
|
||||
readView.curPage.upSelectAble(AppConfig.textSelectAble)
|
||||
readView.invalidate()
|
||||
reset()
|
||||
picture = null
|
||||
canvasRecorder.recycle()
|
||||
}
|
||||
|
||||
fun pause() {
|
||||
@ -71,9 +65,12 @@ class AutoPager(private val readView: ReadView) {
|
||||
progress = 0
|
||||
scrollOffsetRemain = 0.0
|
||||
scrollOffset = 0
|
||||
bitmap?.recycle()
|
||||
bitmap = null
|
||||
pictureIsDirty = true
|
||||
canvasRecorder.invalidate()
|
||||
}
|
||||
|
||||
fun upRecorder() {
|
||||
canvasRecorder.recycle()
|
||||
canvasRecorder = CanvasRecorderFactory.create()
|
||||
}
|
||||
|
||||
fun onDraw(canvas: Canvas) {
|
||||
@ -86,24 +83,12 @@ class AutoPager(private val readView: ReadView) {
|
||||
} else {
|
||||
val bottom = progress
|
||||
val width = readView.width
|
||||
if (atLeastApi23) {
|
||||
if (picture == null) {
|
||||
picture = Picture()
|
||||
}
|
||||
if (pictureIsDirty) {
|
||||
pictureIsDirty = false
|
||||
readView.nextPage.screenshot(picture!!)
|
||||
}
|
||||
canvas.withClip(0, 0, width, bottom) {
|
||||
drawPicture(picture!!)
|
||||
}
|
||||
} else {
|
||||
if (bitmap == null) {
|
||||
bitmap = readView.nextPage.screenshot()
|
||||
}
|
||||
rect.set(0, 0, width, bottom)
|
||||
canvas.drawBitmap(bitmap!!, rect, rect, null)
|
||||
|
||||
canvasRecorder.recordIfNeeded(readView.nextPage)
|
||||
canvas.withClip(0, 0, width, bottom) {
|
||||
canvasRecorder.draw(this)
|
||||
}
|
||||
|
||||
canvas.drawRect(
|
||||
0f,
|
||||
bottom.toFloat() - 1,
|
||||
|
@ -514,6 +514,7 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
||||
(pageDelegate as? ScrollPageDelegate)?.noAnim = AppConfig.noAnimScrollPage
|
||||
if (upRecorder) {
|
||||
(pageDelegate as? HorizontalPageDelegate)?.upRecorder()
|
||||
autoPager.upRecorder()
|
||||
}
|
||||
pageDelegate?.setViewSize(width, height)
|
||||
if (isScroll) {
|
||||
|
@ -20,6 +20,7 @@ import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.utils.launch
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.launch
|
||||
@ -184,14 +185,9 @@ class BookSourceDebugActivity : VMBaseActivity<ActivitySourceDebugBinding, BookS
|
||||
R.id.menu_book_src -> showDialogFragment(TextDialog("html", viewModel.bookSrc))
|
||||
R.id.menu_toc_src -> showDialogFragment(TextDialog("html", viewModel.tocSrc))
|
||||
R.id.menu_content_src -> showDialogFragment(TextDialog("html", viewModel.contentSrc))
|
||||
R.id.menu_help -> showHelp()
|
||||
R.id.menu_help -> showHelp("debugHelp")
|
||||
}
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun showHelp() {
|
||||
val text = String(assets.open("web/help/md/debugHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
}
|
@ -43,7 +43,6 @@ import io.legado.app.ui.config.CheckSourceConfig
|
||||
import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.qrcode.QrCodeResult
|
||||
import io.legado.app.ui.widget.SelectActionBar
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
@ -59,6 +58,7 @@ import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.share
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.toastOnUi
|
||||
@ -134,7 +134,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
initSelectActionBar()
|
||||
resumeCheckSource()
|
||||
if (!LocalConfig.bookSourcesHelpVersionIsLast) {
|
||||
showHelp()
|
||||
showHelp("SourceMBookHelp")
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
searchView.setQuery(getString(R.string.disabled_explore), true)
|
||||
}
|
||||
|
||||
R.id.menu_help -> showHelp()
|
||||
R.id.menu_help -> showHelp("SourceMBookHelp")
|
||||
}
|
||||
if (item.groupId == R.id.source_group) {
|
||||
searchView.setQuery("group:${item.title}", true)
|
||||
@ -370,11 +370,6 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHelp() {
|
||||
val text = String(assets.open("web/help/md/SourceMBookHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
private fun initLiveDataGroup() {
|
||||
lifecycleScope.launch {
|
||||
appDb.bookSourceDao.flowGroups().conflate().collect {
|
||||
|
@ -22,7 +22,6 @@ import io.legado.app.ui.association.ImportTxtTocRuleDialog
|
||||
import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.qrcode.QrCodeResult
|
||||
import io.legado.app.ui.widget.SelectActionBar
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
@ -34,6 +33,7 @@ import io.legado.app.utils.readText
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
@ -140,7 +140,7 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
|
||||
R.id.menu_import_onLine -> showImportDialog()
|
||||
R.id.menu_import_qr -> qrCodeResult.launch()
|
||||
R.id.menu_import_default -> viewModel.importDefault()
|
||||
R.id.menu_help -> showTxtTocRuleHelp()
|
||||
R.id.menu_help -> showHelp("txtTocRuleHelp")
|
||||
|
||||
}
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
@ -244,11 +244,6 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
|
||||
}
|
||||
}
|
||||
|
||||
private fun showTxtTocRuleHelp() {
|
||||
val text = String(assets.open("web/help/md/txtTocRuleHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.menu_enable_selection -> viewModel.enableSelection(*adapter.selection.toTypedArray())
|
||||
|
@ -88,7 +88,7 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
|
||||
bundle.keySet().map {
|
||||
when (it) {
|
||||
"selected" -> cbSource.isChecked = selected.contains(item)
|
||||
"upNmae" -> cbSource.text = item.name
|
||||
"upName" -> cbSource.text = item.name
|
||||
"upExample" -> titleExample.text = item.example
|
||||
"enabled" -> swtEnabled.isChecked = item.enable
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.association.ImportTxtTocRuleDialog
|
||||
import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.qrcode.QrCodeResult
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
import io.legado.app.utils.ACache
|
||||
@ -38,6 +37,7 @@ import io.legado.app.utils.launch
|
||||
import io.legado.app.utils.readText
|
||||
import io.legado.app.utils.setLayout
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
@ -152,7 +152,7 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
|
||||
R.id.menu_import_onLine -> showImportDialog()
|
||||
R.id.menu_import_qr -> qrCodeResult.launch()
|
||||
R.id.menu_import_default -> viewModel.importDefault()
|
||||
R.id.menu_help -> showTxtTocRuleHelp()
|
||||
R.id.menu_help -> showHelp("txtTocRuleHelp")
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -197,11 +197,6 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
|
||||
}
|
||||
}
|
||||
|
||||
private fun showTxtTocRuleHelp() {
|
||||
val text = String(requireContext().assets.open("web/help/md/txtTocRuleHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
inner class TocRegexAdapter(context: Context) :
|
||||
RecyclerAdapter<TxtTocRule, ItemTocRegexBinding>(context),
|
||||
ItemTouchCallback.Callback {
|
||||
@ -264,7 +259,7 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
|
||||
} else {
|
||||
bundle.keySet().map {
|
||||
when (it) {
|
||||
"upNmae" -> rbRegexName.text = item.name
|
||||
"upName" -> rbRegexName.text = item.name
|
||||
"upExample" -> titleExample.text = item.example
|
||||
"enabled" -> swtEnabled.isChecked = item.enable
|
||||
"upSelect" -> rbRegexName.isChecked = item.name == selectedName
|
||||
|
@ -35,9 +35,17 @@ import io.legado.app.lib.prefs.fragment.PreferenceFragment
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.about.AppLogDialog
|
||||
import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.dialog.WaitDialog
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.applyTint
|
||||
import io.legado.app.utils.checkWrite
|
||||
import io.legado.app.utils.getPrefString
|
||||
import io.legado.app.utils.isContentScheme
|
||||
import io.legado.app.utils.launch
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.toEditable
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.Job
|
||||
@ -150,7 +158,7 @@ class BackupConfigFragment : PreferenceFragment(),
|
||||
listView.setEdgeEffectColor(primaryColor)
|
||||
activity?.addMenuProvider(this, viewLifecycleOwner)
|
||||
if (!LocalConfig.backupHelpVersionIsLast) {
|
||||
showHelp()
|
||||
showHelp("webDavHelp")
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +170,7 @@ class BackupConfigFragment : PreferenceFragment(),
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
when (menuItem.itemId) {
|
||||
R.id.menu_help -> {
|
||||
showHelp()
|
||||
showHelp("webDavHelp")
|
||||
return true
|
||||
}
|
||||
|
||||
@ -171,11 +179,6 @@ class BackupConfigFragment : PreferenceFragment(),
|
||||
return false
|
||||
}
|
||||
|
||||
private fun showHelp() {
|
||||
val text = String(requireContext().assets.open("web/help/md/webDavHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
preferenceManager.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
|
||||
|
@ -23,7 +23,6 @@ import io.legado.app.ui.association.ImportDictRuleDialog
|
||||
import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.qrcode.QrCodeResult
|
||||
import io.legado.app.ui.widget.SelectActionBar
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
@ -35,6 +34,7 @@ import io.legado.app.utils.readText
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
@ -143,7 +143,7 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
|
||||
R.id.menu_import_onLine -> showImportDialog()
|
||||
R.id.menu_import_qr -> qrCodeResult.launch()
|
||||
R.id.menu_import_default -> viewModel.importDefault()
|
||||
R.id.menu_help -> showDictRuleHelp()
|
||||
R.id.menu_help -> showHelp("dictRuleHelp")
|
||||
}
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
@ -235,9 +235,4 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDictRuleHelp() {
|
||||
val text = String(assets.open("web/help/md/dictRuleHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import android.view.View
|
||||
import androidx.core.view.isGone
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.flowWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
@ -29,6 +28,7 @@ import io.legado.app.ui.book.info.BookInfoActivity
|
||||
import io.legado.app.ui.book.read.ReadBookActivity
|
||||
import io.legado.app.ui.main.MainViewModel
|
||||
import io.legado.app.utils.cnCompare
|
||||
import io.legado.app.utils.flowWithLifecycleFirst
|
||||
import io.legado.app.utils.observeEvent
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.startActivity
|
||||
@ -175,7 +175,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
|
||||
|
||||
else -> list.sortedByDescending { it.durChapterTime }
|
||||
}
|
||||
}.flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.RESUMED).catch {
|
||||
}.flowWithLifecycleFirst(viewLifecycleOwner.lifecycle, Lifecycle.State.RESUMED).catch {
|
||||
AppLog.put("书架更新出错", it)
|
||||
}.conflate().flowOn(Dispatchers.Default).collect { list ->
|
||||
binding.tvEmptyMsg.isGone = list.isNotEmpty()
|
||||
|
@ -148,6 +148,11 @@ class BookshelfFragment2() : BaseBookshelfFragment(R.layout.fragment_bookshelf2)
|
||||
3 -> list.sortedBy {
|
||||
it.order
|
||||
}
|
||||
|
||||
4 -> list.sortedByDescending {
|
||||
max(it.latestChapterTime, it.durChapterTime)
|
||||
}
|
||||
|
||||
else -> list.sortedByDescending {
|
||||
it.durChapterTime
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import io.legado.app.ui.dict.rule.DictRuleActivity
|
||||
import io.legado.app.ui.file.FileManageActivity
|
||||
import io.legado.app.ui.main.MainFragmentInterface
|
||||
import io.legado.app.ui.replace.ReplaceRuleActivity
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.utils.LogUtils
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.observeEventSticky
|
||||
@ -37,7 +36,7 @@ import io.legado.app.utils.openUrl
|
||||
import io.legado.app.utils.putPrefBoolean
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
|
||||
@ -68,10 +67,7 @@ class MyFragment() : BaseFragment(R.layout.fragment_my_config), MainFragmentInte
|
||||
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem) {
|
||||
when (item.itemId) {
|
||||
R.id.menu_help -> {
|
||||
val text = String(requireContext().assets.open("web/help/md/appHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
R.id.menu_help -> showHelp("appHelp")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.qrcode.QrCodeResult
|
||||
import io.legado.app.ui.replace.edit.ReplaceEditActivity
|
||||
import io.legado.app.ui.widget.SelectActionBar
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
@ -47,6 +46,7 @@ import io.legado.app.utils.readText
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
@ -255,7 +255,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
|
||||
allowExtensions = arrayOf("txt", "json")
|
||||
}
|
||||
R.id.menu_import_qr -> qrCodeResult.launch()
|
||||
R.id.menu_help -> showHelp()
|
||||
R.id.menu_help -> showHelp("replaceRuleHelp")
|
||||
R.id.menu_group_null -> {
|
||||
searchView.setQuery(getString(R.string.no_group), true)
|
||||
}
|
||||
@ -324,11 +324,6 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHelp() {
|
||||
val text = String(assets.open("web/help/md/replaceRuleHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
observeReplaceRuleData(newText)
|
||||
return false
|
||||
|
@ -28,7 +28,6 @@ import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.qrcode.QrCodeResult
|
||||
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
||||
import io.legado.app.ui.widget.SelectActionBar
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
@ -44,6 +43,7 @@ import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.share
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.showHelp
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.toastOnUi
|
||||
@ -163,7 +163,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
|
||||
R.id.menu_group_null -> {
|
||||
searchView.setQuery(getString(R.string.no_group), true)
|
||||
}
|
||||
R.id.menu_help -> showHelp()
|
||||
R.id.menu_help -> showHelp("SourceMRssHelp")
|
||||
else -> if (item.groupId == R.id.source_group) {
|
||||
searchView.setQuery("group:${item.title}", true)
|
||||
}
|
||||
@ -354,11 +354,6 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHelp() {
|
||||
val text = String(assets.open("web/help/md/SourceMRssHelp.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
override fun upCountView() {
|
||||
binding.selectActionBar.upCountView(
|
||||
adapter.selection.size,
|
||||
|
@ -203,8 +203,10 @@ val Activity.navigationBarGravity: Int
|
||||
return gravity ?: Gravity.BOTTOM
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示目录help下的帮助文档
|
||||
*/
|
||||
fun AppCompatActivity.showHelp(fileName: String) {
|
||||
//显示目录help下的帮助文档
|
||||
val mdText = String(assets.open("web/help/md/${fileName}.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), mdText, TextDialog.Mode.MD))
|
||||
}
|
@ -32,14 +32,16 @@ object ChineseUtils {
|
||||
fun fixT2sDict() {
|
||||
val dict = DictionaryContainer.getInstance().getDictionary(TransType.TRADITIONAL_TO_SIMPLE)
|
||||
dict.run {
|
||||
remove("劈", "脊", "槃")
|
||||
remove("支援", "沈默", "類比", "模擬", "划槳", "列根", "先進", "雪梨", "雪糕")
|
||||
remove("零錢", "零钱", "離線", "碟片", "模組", "桌球", "案頭", "機車", "電漿")
|
||||
remove("鳳梨", "魔戒", "載入")
|
||||
remove("路易斯", "非同步", "出租车", "周杰倫", "马铃薯", "馬鈴薯", "機械人", "電單車")
|
||||
remove("電扶梯", "音效卡", "飆車族", "點陣圖", "個入球", "顆進球")
|
||||
remove("魔獸紀元", "高空彈跳", "铁达尼号")
|
||||
remove("魔鬼終結者", "純文字檔案")
|
||||
remove(
|
||||
"劈", "脊", "槃",
|
||||
"支援", "沈默", "類比", "模擬", "划槳", "列根", "先進", "雪梨", "雪糕",
|
||||
"零錢", "零钱", "離線", "碟片", "模組", "桌球", "案頭", "機車", "電漿",
|
||||
"鳳梨", "魔戒", "載入",
|
||||
"路易斯", "非同步", "出租车", "周杰倫", "马铃薯", "馬鈴薯", "機械人", "電單車",
|
||||
"電扶梯", "音效卡", "飆車族", "點陣圖", "個入球", "顆進球",
|
||||
"魔獸紀元", "高空彈跳", "铁达尼号",
|
||||
"魔鬼終結者", "純文字檔案"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.buffer
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flatMapMerge
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
@ -185,3 +189,18 @@ inline fun <T> Flow<T>.onEachAsyncIndexed(
|
||||
}.onEach { semaphore.release() }
|
||||
}.buffer(0)
|
||||
}
|
||||
|
||||
fun <T> Flow<T>.flowWithLifecycleFirst(
|
||||
lifecycle: Lifecycle,
|
||||
minActiveState: Lifecycle.State = Lifecycle.State.STARTED
|
||||
): Flow<T> = callbackFlow {
|
||||
if (!lifecycle.currentState.isAtLeast(minActiveState)) {
|
||||
send(first())
|
||||
}
|
||||
lifecycle.repeatOnLifecycle(minActiveState) {
|
||||
this@flowWithLifecycleFirst.collect {
|
||||
send(it)
|
||||
}
|
||||
}
|
||||
close()
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.edit
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import io.legado.app.R
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
|
||||
inline fun <reified T : DialogFragment> Fragment.showDialogFragment(
|
||||
arguments: Bundle.() -> Unit = {}
|
||||
@ -76,4 +78,9 @@ inline fun <reified T : Activity> Fragment.startActivity(
|
||||
configIntent: Intent.() -> Unit = {}
|
||||
) {
|
||||
startActivity(Intent(requireContext(), T::class.java).apply(configIntent))
|
||||
}
|
||||
|
||||
fun Fragment.showHelp(fileName: String) {
|
||||
val mdText = String(requireContext().assets.open("web/help/md/${fileName}.md").readBytes())
|
||||
showDialogFragment(TextDialog(getString(R.string.help), mdText, TextDialog.Mode.MD))
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package io.legado.app.utils.canvasrecorder
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.view.View
|
||||
import androidx.core.graphics.withSave
|
||||
|
||||
inline fun CanvasRecorder.recordIfNeeded(
|
||||
@ -13,6 +14,14 @@ inline fun CanvasRecorder.recordIfNeeded(
|
||||
return true
|
||||
}
|
||||
|
||||
fun CanvasRecorder.recordIfNeeded(view: View): Boolean {
|
||||
if (!needRecord()) return false
|
||||
record(view.width, view.height) {
|
||||
view.draw(this)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
inline fun CanvasRecorder.record(width: Int, height: Int, block: Canvas.() -> Unit) {
|
||||
try {
|
||||
val canvas = beginRecording(width, height)
|
||||
|
Loading…
Reference in New Issue
Block a user