mirror of
https://github.com/gedoor/legado.git
synced 2024-07-04 23:36:56 +08:00
Compare commits
9 Commits
2badb499a6
...
a24fe81f37
Author | SHA1 | Date | |
---|---|---|---|
|
a24fe81f37 | ||
|
27571f5b06 | ||
|
0d63180dd0 | ||
|
9e5cefc47c | ||
|
5336adc035 | ||
|
72ad27ea84 | ||
|
5eaf2f034f | ||
|
2aed021e08 | ||
|
d4afcbe8fd |
2
.github/workflows/web.yml
vendored
2
.github/workflows/web.yml
vendored
|
@ -27,7 +27,7 @@ jobs:
|
|||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v3
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
|
|
|
@ -71,6 +71,8 @@ open class WebDav(
|
|||
<resourcetype />
|
||||
</prop>
|
||||
</propfind>"""
|
||||
|
||||
private const val DEFAULT_CONTENT_TYPE = "application/octet-stream"
|
||||
}
|
||||
|
||||
|
||||
|
@ -304,18 +306,12 @@ open class WebDav(
|
|||
* 上传文件
|
||||
*/
|
||||
@Throws(WebDavException::class)
|
||||
suspend fun upload(
|
||||
localPath: String,
|
||||
contentType: String = "application/octet-stream"
|
||||
) {
|
||||
suspend fun upload(localPath: String, contentType: String = DEFAULT_CONTENT_TYPE) {
|
||||
upload(File(localPath), contentType)
|
||||
}
|
||||
|
||||
@Throws(WebDavException::class)
|
||||
suspend fun upload(
|
||||
file: File,
|
||||
contentType: String = "application/octet-stream"
|
||||
) {
|
||||
suspend fun upload(file: File, contentType: String = DEFAULT_CONTENT_TYPE) {
|
||||
kotlin.runCatching {
|
||||
withContext(IO) {
|
||||
if (!file.exists()) throw WebDavException("文件不存在")
|
||||
|
@ -336,7 +332,7 @@ open class WebDav(
|
|||
}
|
||||
|
||||
@Throws(WebDavException::class)
|
||||
suspend fun upload(byteArray: ByteArray, contentType: String) {
|
||||
suspend fun upload(byteArray: ByteArray, contentType: String = DEFAULT_CONTENT_TYPE) {
|
||||
// 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
|
||||
kotlin.runCatching {
|
||||
withContext(IO) {
|
||||
|
@ -356,7 +352,7 @@ open class WebDav(
|
|||
}
|
||||
|
||||
@Throws(WebDavException::class)
|
||||
suspend fun upload(uri: Uri, contentType: String) {
|
||||
suspend fun upload(uri: Uri, contentType: String = DEFAULT_CONTENT_TYPE) {
|
||||
// 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
|
||||
kotlin.runCatching {
|
||||
withContext(IO) {
|
||||
|
|
|
@ -93,7 +93,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
|||
readRecord.readTime = appDb.readRecordDao.getReadTime(book.name) ?: 0
|
||||
chapterSize = appDb.bookChapterDao.getChapterCount(book.bookUrl)
|
||||
contentProcessor = ContentProcessor.get(book)
|
||||
durChapterIndex = min(book.durChapterIndex, chapterSize - 1).coerceAtLeast(0)
|
||||
durChapterIndex = book.durChapterIndex
|
||||
durChapterPos = book.durChapterPos
|
||||
isLocalBook = book.isLocal
|
||||
clearTextChapter()
|
||||
|
|
|
@ -14,10 +14,7 @@ import io.legado.app.model.analyzeRule.CustomUrl
|
|||
import io.legado.app.model.localBook.LocalBook
|
||||
import io.legado.app.utils.NetworkUtils
|
||||
import io.legado.app.utils.isContentScheme
|
||||
import io.legado.app.utils.readBytes
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
|
||||
class RemoteBookWebDav(
|
||||
val rootBookUrl: String,
|
||||
|
@ -71,20 +68,17 @@ class RemoteBookWebDav(
|
|||
override suspend fun upload(book: Book) {
|
||||
if (!NetworkUtils.isAvailable()) throw NoStackTraceException("网络不可用")
|
||||
val localBookUri = Uri.parse(book.bookUrl)
|
||||
val putUrl = "$rootBookUrl${File.separator}${book.originName}"
|
||||
val putUrl = "$rootBookUrl${book.originName}"
|
||||
val webDav = WebDav(putUrl, authorization)
|
||||
if (localBookUri.isContentScheme()) {
|
||||
webDav.upload(
|
||||
byteArray = localBookUri.readBytes(appCtx),
|
||||
contentType = "application/octet-stream"
|
||||
)
|
||||
webDav.upload(localBookUri)
|
||||
} else {
|
||||
webDav.upload(localBookUri.path!!)
|
||||
}
|
||||
book.origin = BookType.webDavTag + CustomUrl(putUrl)
|
||||
.putAttribute("serverID", serverID)
|
||||
.toString()
|
||||
book.save()
|
||||
book.update()
|
||||
}
|
||||
|
||||
override suspend fun delete(remoteBookUrl: String) {
|
||||
|
|
|
@ -96,12 +96,11 @@ class WebService : BaseService() {
|
|||
if (addressList.any()) {
|
||||
notificationList.addAll(addressList.map { address -> getString(R.string.http_ip, address.hostAddress, getPort()) })
|
||||
hostAddress = notificationList.first()
|
||||
startForegroundNotification()
|
||||
} else {
|
||||
hostAddress = getString(R.string.network_connection_unavailable)
|
||||
notificationList.add(hostAddress)
|
||||
startForegroundNotification()
|
||||
}
|
||||
startForegroundNotification()
|
||||
postEvent(EventBus.WEB_SERVICE, hostAddress)
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +183,7 @@ class WebService : BaseService() {
|
|||
*/
|
||||
override fun startForegroundNotification() {
|
||||
val builder = NotificationCompat.Builder(this, AppConst.channelIdWeb)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setSmallIcon(R.drawable.ic_web_service_noti)
|
||||
.setOngoing(true)
|
||||
.setContentTitle(getString(R.string.web_service))
|
||||
|
@ -196,7 +196,6 @@ class WebService : BaseService() {
|
|||
getString(R.string.cancel),
|
||||
servicePendingIntent<WebService>(IntentAction.stop)
|
||||
)
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
val notification = builder.build()
|
||||
startForeground(NotificationId.WebService, notification)
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import kotlinx.coroutines.channels.awaitClose
|
|||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.util.*
|
||||
import java.util.Collections
|
||||
|
||||
class RemoteBookViewModel(application: Application) : BaseViewModel(application) {
|
||||
var sortKey = RemoteBookSort.Default
|
||||
|
@ -78,6 +78,7 @@ class RemoteBookViewModel(application: Application) : BaseViewModel(application)
|
|||
}
|
||||
return@sortedWith compare
|
||||
}
|
||||
|
||||
else -> list.sortedWith { o1, o2 ->
|
||||
val compare = -compareValues(o1.isDir, o2.isDir)
|
||||
if (compare == 0) {
|
||||
|
@ -132,10 +133,8 @@ class RemoteBookViewModel(application: Application) : BaseViewModel(application)
|
|||
val downloadBookUri = bookWebDav.downloadRemoteBook(remoteBook)
|
||||
LocalBook.importFiles(downloadBookUri).forEach { book ->
|
||||
book.origin = BookType.webDavTag + CustomUrl(remoteBook.path)
|
||||
.putAttribute(
|
||||
"serverID",
|
||||
bookWebDav.serverID
|
||||
).toString()
|
||||
.putAttribute("serverID", bookWebDav.serverID)
|
||||
.toString()
|
||||
book.save()
|
||||
}
|
||||
remoteBook.isOnBookShelf = true
|
||||
|
@ -152,7 +151,7 @@ class RemoteBookViewModel(application: Application) : BaseViewModel(application)
|
|||
}
|
||||
|
||||
fun updateCallBackFlow(filterKey: String?) {
|
||||
dataCallback?.screen(filterKey)
|
||||
dataCallback?.screen(filterKey)
|
||||
}
|
||||
|
||||
interface DataCallback {
|
||||
|
|
|
@ -116,6 +116,9 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
|
|||
ReadBook.loadOrUpContent()
|
||||
checkLocalBookFileExist(book)
|
||||
} else {
|
||||
if (ReadBook.durChapterIndex > ReadBook.chapterSize - 1) {
|
||||
ReadBook.durChapterIndex = ReadBook.chapterSize - 1
|
||||
}
|
||||
ReadBook.loadContent(resetPageOffset = false)
|
||||
checkLocalBookFileExist(book)
|
||||
}
|
||||
|
|
|
@ -278,17 +278,18 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
if (textPos.compare(selectEnd) <= 0) {
|
||||
selectStart.upData(pos = textPos)
|
||||
upSelectedStart(
|
||||
if (textPos.isTouch) textColumn.start else textColumn.end,
|
||||
if (textPos.columnIndex < textLine.columns.lastIndex) textColumn.start else textColumn.end,
|
||||
textLine.lineBottom + relativeOffset,
|
||||
textLine.lineTop + relativeOffset
|
||||
)
|
||||
} else {
|
||||
reverseStartCursor = true
|
||||
reverseEndCursor = false
|
||||
selectEnd.columnIndex++
|
||||
selectStartMoveIndex(selectEnd)
|
||||
selectEnd.upData(textPos)
|
||||
upSelectedEnd(
|
||||
if (selectEnd.isTouch || selectEnd.isLast) textColumn.end else textColumn.start,
|
||||
if (textPos.columnIndex > -1) textColumn.end else textColumn.start,
|
||||
textLine.lineBottom + relativeOffset
|
||||
)
|
||||
}
|
||||
|
@ -307,16 +308,17 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
if (textPos.compare(selectStart) >= 0) {
|
||||
selectEnd.upData(textPos)
|
||||
upSelectedEnd(
|
||||
if (selectEnd.isTouch || selectEnd.isLast) textColumn.end else textColumn.start,
|
||||
if (textPos.columnIndex > -1) textColumn.end else textColumn.start,
|
||||
textLine.lineBottom + relativeOffset
|
||||
)
|
||||
} else {
|
||||
reverseEndCursor = true
|
||||
reverseStartCursor = false
|
||||
selectStart.columnIndex--
|
||||
selectEndMoveIndex(selectStart)
|
||||
selectStart.upData(textPos)
|
||||
upSelectedStart(
|
||||
if (textPos.isTouch) textColumn.start else textColumn.end,
|
||||
if (textPos.columnIndex < textLine.columns.lastIndex) textColumn.start else textColumn.end,
|
||||
textLine.lineBottom + relativeOffset,
|
||||
textLine.lineTop + relativeOffset
|
||||
)
|
||||
|
@ -418,11 +420,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
}
|
||||
}
|
||||
val isLast = columns.first().start < x
|
||||
val charIndex = if (isLast) columns.lastIndex else 0
|
||||
val charIndex = if (isLast) columns.lastIndex + 1 else -1
|
||||
val textColumn = if (isLast) columns.last() else columns.first()
|
||||
touched.invoke(
|
||||
relativeOffset,
|
||||
TextPos(relativePos, lineIndex, charIndex, false, isLast),
|
||||
TextPos(relativePos, lineIndex, charIndex),
|
||||
textPage, textLine, textColumn
|
||||
)
|
||||
return
|
||||
|
@ -489,18 +491,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
relativePagePos: Int,
|
||||
lineIndex: Int,
|
||||
charIndex: Int,
|
||||
isTouch: Boolean,
|
||||
isLast: Boolean = false
|
||||
) {
|
||||
selectStart.relativePagePos = relativePagePos
|
||||
selectStart.lineIndex = lineIndex
|
||||
selectStart.columnIndex = charIndex
|
||||
selectStart.isTouch = isTouch
|
||||
selectStart.isLast = isLast
|
||||
val textLine = relativePage(relativePagePos).getLine(lineIndex)
|
||||
val textColumn = textLine.getColumn(charIndex)
|
||||
upSelectedStart(
|
||||
textColumn.start,
|
||||
if (charIndex < textLine.columns.lastIndex) textColumn.start else textColumn.end,
|
||||
textLine.lineBottom + relativeOffset(relativePagePos),
|
||||
textLine.lineTop + relativeOffset(relativePagePos)
|
||||
)
|
||||
|
@ -508,7 +506,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
}
|
||||
|
||||
fun selectStartMoveIndex(textPos: TextPos) = textPos.run {
|
||||
selectStartMoveIndex(relativePagePos, lineIndex, columnIndex, isTouch, isLast)
|
||||
selectStartMoveIndex(relativePagePos, lineIndex, columnIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -518,22 +516,21 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
relativePage: Int,
|
||||
lineIndex: Int,
|
||||
charIndex: Int,
|
||||
isTouch: Boolean,
|
||||
isLast: Boolean = false
|
||||
) {
|
||||
selectEnd.relativePagePos = relativePage
|
||||
selectEnd.lineIndex = lineIndex
|
||||
selectEnd.columnIndex = charIndex
|
||||
selectEnd.isTouch = isTouch
|
||||
selectEnd.isLast = isLast
|
||||
val textLine = relativePage(relativePage).getLine(lineIndex)
|
||||
val textColumn = textLine.getColumn(charIndex)
|
||||
upSelectedEnd(textColumn.end, textLine.lineBottom + relativeOffset(relativePage))
|
||||
upSelectedEnd(
|
||||
if (charIndex > -1) textColumn.end else textColumn.start,
|
||||
textLine.lineBottom + relativeOffset(relativePage)
|
||||
)
|
||||
upSelectChars()
|
||||
}
|
||||
|
||||
fun selectEndMoveIndex(textPos: TextPos) = textPos.run {
|
||||
selectEndMoveIndex(relativePagePos, lineIndex, columnIndex, isTouch, isLast)
|
||||
selectEndMoveIndex(relativePagePos, lineIndex, columnIndex)
|
||||
}
|
||||
|
||||
private fun upSelectChars() {
|
||||
|
@ -553,8 +550,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
val compareStart = textPos.compare(selectStart)
|
||||
val compareEnd = textPos.compare(selectEnd)
|
||||
column.selected = when {
|
||||
compareStart == 0 -> selectStart.isTouch
|
||||
compareEnd == 0 -> selectEnd.isTouch || selectEnd.isLast
|
||||
compareStart == 0 -> true
|
||||
compareEnd == 0 -> true
|
||||
compareStart > 0 && compareEnd < 0 -> true
|
||||
else -> false
|
||||
}
|
||||
|
@ -624,19 +621,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
if (column is TextColumn) {
|
||||
when {
|
||||
compareStart == 0 -> {
|
||||
if (selectStart.isTouch) {
|
||||
if (textPos.columnIndex < textLine.columns.lastIndex) {
|
||||
builder.append(column.charData)
|
||||
}
|
||||
if (
|
||||
textLine.isParagraphEnd
|
||||
&& charIndex == textLine.charSize - 1
|
||||
&& charIndex == textLine.columns.lastIndex
|
||||
&& compareEnd != 0
|
||||
) {
|
||||
builder.append("\n")
|
||||
}
|
||||
}
|
||||
|
||||
compareEnd == 0 -> if (selectEnd.isTouch || selectEnd.isLast) {
|
||||
compareEnd == 0 -> if (textPos.columnIndex > -1) {
|
||||
builder.append(column.charData)
|
||||
}
|
||||
|
||||
|
@ -644,7 +641,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||
builder.append(column.charData)
|
||||
if (
|
||||
textLine.isParagraphEnd
|
||||
&& charIndex == textLine.charSize - 1
|
||||
&& charIndex == textLine.columns.lastIndex
|
||||
) {
|
||||
builder.append("\n")
|
||||
}
|
||||
|
|
|
@ -404,17 +404,9 @@ class PageView(context: Context) : FrameLayout(context) {
|
|||
fun selectStartMoveIndex(
|
||||
relativePagePos: Int,
|
||||
lineIndex: Int,
|
||||
charIndex: Int,
|
||||
isTouch: Boolean = true,
|
||||
isLast: Boolean = false
|
||||
charIndex: Int
|
||||
) {
|
||||
binding.contentTextView.selectStartMoveIndex(
|
||||
relativePagePos,
|
||||
lineIndex,
|
||||
charIndex,
|
||||
isTouch,
|
||||
isLast
|
||||
)
|
||||
binding.contentTextView.selectStartMoveIndex(relativePagePos, lineIndex, charIndex)
|
||||
}
|
||||
|
||||
fun selectStartMoveIndex(textPos: TextPos) {
|
||||
|
@ -428,17 +420,9 @@ class PageView(context: Context) : FrameLayout(context) {
|
|||
fun selectEndMoveIndex(
|
||||
relativePagePos: Int,
|
||||
lineIndex: Int,
|
||||
charIndex: Int,
|
||||
isTouch: Boolean = true,
|
||||
isLast: Boolean = false
|
||||
charIndex: Int
|
||||
) {
|
||||
binding.contentTextView.selectEndMoveIndex(
|
||||
relativePagePos,
|
||||
lineIndex,
|
||||
charIndex,
|
||||
isTouch,
|
||||
isLast
|
||||
)
|
||||
binding.contentTextView.selectEndMoveIndex(relativePagePos, lineIndex, charIndex)
|
||||
}
|
||||
|
||||
fun selectEndMoveIndex(textPos: TextPos) {
|
||||
|
|
|
@ -443,9 +443,13 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|||
curPage.selectText(x, y) { textPos ->
|
||||
val compare = initialTextPos.compare(textPos)
|
||||
when {
|
||||
compare >= 0 -> {
|
||||
compare > 0 -> {
|
||||
curPage.selectStartMoveIndex(textPos)
|
||||
curPage.selectEndMoveIndex(initialTextPos)
|
||||
curPage.selectEndMoveIndex(
|
||||
initialTextPos.relativePagePos,
|
||||
initialTextPos.lineIndex,
|
||||
initialTextPos.columnIndex - 1
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
|
|
@ -11,30 +11,22 @@ data class TextPos(
|
|||
var relativePagePos: Int,
|
||||
var lineIndex: Int,
|
||||
var columnIndex: Int,
|
||||
var isTouch: Boolean = true,
|
||||
var isLast: Boolean = false
|
||||
) {
|
||||
|
||||
fun upData(
|
||||
relativePos: Int,
|
||||
lineIndex: Int,
|
||||
charIndex: Int,
|
||||
isTouch: Boolean,
|
||||
isLast: Boolean
|
||||
) {
|
||||
this.relativePagePos = relativePos
|
||||
this.lineIndex = lineIndex
|
||||
this.columnIndex = charIndex
|
||||
this.isTouch = isTouch
|
||||
this.isLast = isLast
|
||||
}
|
||||
|
||||
fun upData(pos: TextPos) {
|
||||
relativePagePos = pos.relativePagePos
|
||||
lineIndex = pos.lineIndex
|
||||
columnIndex = pos.columnIndex
|
||||
isTouch = pos.isTouch
|
||||
isLast = pos.isLast
|
||||
}
|
||||
|
||||
fun compare(pos: TextPos): Int {
|
||||
|
@ -65,8 +57,6 @@ data class TextPos(
|
|||
relativePagePos = 0
|
||||
lineIndex = -1
|
||||
columnIndex = -1
|
||||
isTouch = true
|
||||
isLast = false
|
||||
}
|
||||
|
||||
fun isSelected(): Boolean {
|
||||
|
|
|
@ -6,10 +6,8 @@ import android.graphics.Canvas
|
|||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Typeface
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.os.Build
|
||||
import android.text.StaticLayout
|
||||
import android.text.style.LineHeightSpan
|
||||
import android.util.AttributeSet
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
|
@ -29,13 +27,6 @@ class BatteryView @JvmOverloads constructor(
|
|||
private val outFrame = Rect()
|
||||
private val polar = Rect()
|
||||
private val canvasRecorder = CanvasRecorderFactory.create()
|
||||
private val batterySpan = LineHeightSpan { _, _, _, _, _, fm ->
|
||||
fm.top = -22
|
||||
fm.ascent = -28
|
||||
fm.descent = 7
|
||||
fm.bottom = 1
|
||||
fm.leading = 0
|
||||
}
|
||||
var isBattery = false
|
||||
set(value) {
|
||||
field = value
|
||||
|
@ -48,6 +39,9 @@ class BatteryView @JvmOverloads constructor(
|
|||
|
||||
init {
|
||||
setPadding(4.dpToPx(), 3.dpToPx(), 6.dpToPx(), 3.dpToPx())
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
isFallbackLineSpacing = false
|
||||
}
|
||||
batteryPaint.strokeWidth = 1f.dpToPx()
|
||||
batteryPaint.isAntiAlias = true
|
||||
batteryPaint.color = paint.color
|
||||
|
@ -69,9 +63,9 @@ class BatteryView @JvmOverloads constructor(
|
|||
fun setBattery(battery: Int, text: String? = null) {
|
||||
this.battery = battery
|
||||
if (text.isNullOrEmpty()) {
|
||||
setText(getBatteryText(battery.toString()))
|
||||
setText(battery.toString())
|
||||
} else {
|
||||
setText(getBatteryText("$text $battery"))
|
||||
setText("$text $battery")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,17 +78,16 @@ class BatteryView @JvmOverloads constructor(
|
|||
if (AppConfig.optimizeRender) {
|
||||
canvasRecorder.recordIfNeededThenDraw(canvas, width, height) {
|
||||
super.onDraw(this)
|
||||
if (!isBattery) return@recordIfNeededThenDraw
|
||||
drawBattery(this)
|
||||
}
|
||||
} else {
|
||||
super.onDraw(canvas)
|
||||
if (!isBattery) return
|
||||
drawBattery(canvas)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawBattery(canvas: Canvas) {
|
||||
if (!isBattery) return
|
||||
layout.getLineBounds(0, outFrame)
|
||||
val batteryStart = layout
|
||||
.getPrimaryHorizontal(text.length - battery.toString().length)
|
||||
|
@ -120,22 +113,10 @@ class BatteryView @JvmOverloads constructor(
|
|||
canvas.drawRect(polar, batteryPaint)
|
||||
}
|
||||
|
||||
private fun getBatteryText(text: CharSequence?): SpannableStringBuilder? {
|
||||
if (text == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return SpannableStringBuilder(text).apply {
|
||||
setSpan(batterySpan, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Suppress("UNNECESSARY_SAFE_CALL")
|
||||
override fun invalidate() {
|
||||
super.invalidate()
|
||||
kotlin.runCatching {
|
||||
canvasRecorder.invalidate()
|
||||
}
|
||||
canvasRecorder?.invalidate()
|
||||
}
|
||||
|
||||
}
|
|
@ -194,10 +194,10 @@ object NetworkUtils {
|
|||
enumeration = NetworkInterface.getNetworkInterfaces()
|
||||
} catch (e: SocketException) {
|
||||
e.printOnDebug()
|
||||
return mutableListOf()
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
var fallbackAddress: MutableList<InetAddress> = mutableListOf()
|
||||
val addressList = mutableListOf<InetAddress>()
|
||||
|
||||
while (enumeration.hasMoreElements()) {
|
||||
val nif = enumeration.nextElement()
|
||||
|
@ -205,13 +205,11 @@ object NetworkUtils {
|
|||
while (addresses.hasMoreElements()) {
|
||||
val address = addresses.nextElement()
|
||||
if (!address.isLoopbackAddress && isIPv4Address(address.hostAddress)) {
|
||||
if (nif.name?.startsWith("wlan") == true) {
|
||||
fallbackAddress.add(address)
|
||||
}
|
||||
addressList.add(address)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallbackAddress
|
||||
return addressList
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,17 +4,14 @@ package io.legado.app.utils
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.fragment.app.Fragment
|
||||
import io.legado.app.BuildConfig
|
||||
import io.legado.app.R
|
||||
import io.legado.app.databinding.ViewToastBinding
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.lib.theme.bottomBackground
|
||||
import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
import splitties.views.inflate
|
||||
import splitties.systemservices.layoutInflater
|
||||
|
||||
private var toast: Toast? = null
|
||||
|
||||
|
@ -31,14 +28,13 @@ fun Context.toastOnUi(message: CharSequence?, duration: Int = Toast.LENGTH_SHORT
|
|||
kotlin.runCatching {
|
||||
toast?.cancel()
|
||||
toast = Toast(this)
|
||||
val toastView: View = inflate(R.layout.view_toast)
|
||||
toast?.view = toastView
|
||||
val cardView = toastView.findViewById<CardView>(R.id.cv_content)
|
||||
cardView.setCardBackgroundColor(bottomBackground)
|
||||
val isLight = ColorUtils.isColorLight(bottomBackground)
|
||||
val textView = toastView.findViewById<TextView>(R.id.tv_text)
|
||||
textView.setTextColor(getPrimaryTextColor(isLight))
|
||||
textView.text = message
|
||||
ViewToastBinding.inflate(layoutInflater).run {
|
||||
toast?.view = root
|
||||
cvToast.setCardBackgroundColor(bottomBackground)
|
||||
tvText.setTextColor(getPrimaryTextColor(isLight))
|
||||
tvText.text = message
|
||||
}
|
||||
toast?.duration = duration
|
||||
toast?.show()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cv_content"
|
||||
android:id="@+id/cv_toast"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="10dp"
|
||||
|
|
|
@ -161,7 +161,7 @@ android-application = { id = "com.android.application", version.ref = "agp" }
|
|||
android-library = { id = "com.android.library", version.ref = "agp" }
|
||||
android-test = { id = "com.android.test", version.ref = "agp" }
|
||||
|
||||
androidx-benchmark = { id = "androidx.benchmark", version = "1.2.3" }
|
||||
androidx-benchmark = { id = "androidx.benchmark", version = "1.2.4" }
|
||||
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||
|
|
Loading…
Reference in New Issue
Block a user