- update translators list in ActAbout
- Android gradle plugin 4.2.0 - Gradle 6.9 - kotlin 1.5.0 - kotlinx.coroutines 1.4.3 - junit 4.13.2 - firebase-messaging:21.1.0 - androidx.annotation:1.2.0 - androidx.recyclerview:1.2.0 - exoplayer:2.13.3
This commit is contained in:
parent
5a3dcd8704
commit
e8222fa2d8
|
@ -3,6 +3,7 @@
|
|||
package jp.juggler.apng
|
||||
|
||||
import jp.juggler.apng.util.getUInt8
|
||||
import kotlin.math.min
|
||||
|
||||
class ApngPalette(
|
||||
src : ByteArray // repeat of R,G,B
|
||||
|
@ -35,7 +36,7 @@ class ApngPalette(
|
|||
// update alpha value from tRNS chunk data
|
||||
fun parseTRNS(ba : ByteArray) {
|
||||
hasAlpha = true
|
||||
for(i in 0 until Math.min(list.size, ba.size)) {
|
||||
for(i in 0 until min(list.size, ba.size)) {
|
||||
list[i] = (list[i] and 0xffffff) or (ba.getUInt8(i) shl 24)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package jp.juggler.apng
|
||||
|
||||
import java.io.InputStream
|
||||
import java.lang.StringBuilder
|
||||
import kotlin.math.min
|
||||
|
||||
// https://raw.githubusercontent.com/rtyley/animated-gif-lib-for-java/master/src/main/java/com/madgag/gif/fmsware/GifDecoder.java
|
||||
|
@ -44,9 +45,11 @@ class GifDecoder(val callback : GifDecoderCallback) {
|
|||
|
||||
// Reads specified bytes and compose it to ascii string
|
||||
fun string(n : Int) : String {
|
||||
val ba = ByteArray(n)
|
||||
array(ba)
|
||||
return ba.map { it.toChar() }.joinToString(separator = "")
|
||||
return StringBuilder(n).apply{
|
||||
ByteArray(n)
|
||||
.also{ array(it)}
|
||||
.forEach { append( Char( it.toInt() and 255)) }
|
||||
}.toString()
|
||||
}
|
||||
|
||||
// Reads next variable length block
|
||||
|
@ -478,11 +481,11 @@ class GifDecoder(val callback : GifDecoderCallback) {
|
|||
// application extension
|
||||
0xff -> {
|
||||
val block = reader.block()
|
||||
var app = ""
|
||||
val app = StringBuilder(12)
|
||||
for(i in 0 until 11) {
|
||||
app += block[i].toChar()
|
||||
app.append( Char( block[i].toInt() and 255 ))
|
||||
}
|
||||
if(app == "NETSCAPE2.0") {
|
||||
if(app.toString() == "NETSCAPE2.0") {
|
||||
readNetscapeExt(reader)
|
||||
} else {
|
||||
reader.skipBlock() // don't care
|
||||
|
|
|
@ -6,6 +6,8 @@ import jp.juggler.apng.util.*
|
|||
import java.io.InputStream
|
||||
import java.util.zip.CRC32
|
||||
import java.util.zip.Inflater
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
|
||||
internal class IdatDecoder(
|
||||
apng: Apng,
|
||||
|
@ -35,9 +37,9 @@ internal class IdatDecoder(
|
|||
// a = left, b = above, c = upper left
|
||||
private fun paeth(a: Int, b: Int, c: Int): Int {
|
||||
val p = a + b - c
|
||||
val pa = Math.abs(p - a)
|
||||
val pb = Math.abs(p - b)
|
||||
val pc = Math.abs(p - c)
|
||||
val pa = abs(p - a)
|
||||
val pb = abs(p - b)
|
||||
val pc = abs(p - c)
|
||||
return when {
|
||||
(pa <= pb && pa <= pc) -> a
|
||||
(pb <= pc) -> b
|
||||
|
@ -167,13 +169,13 @@ internal class IdatDecoder(
|
|||
transparentCheckerGrey = if (transparentColor != null) {
|
||||
{ v: Int -> if (transparentColor.match(v)) 0 else 255 }
|
||||
} else {
|
||||
{ _ : Int -> 255 }
|
||||
{ 255 }
|
||||
}
|
||||
|
||||
transparentCheckerRGB = if (transparentColor != null) {
|
||||
{ r : Int, g : Int, b : Int -> if(transparentColor.match(r, g, b)) 0 else 255 }
|
||||
{ r, g, b -> if (transparentColor.match(r, g, b)) 0 else 255 }
|
||||
} else {
|
||||
{ _ : Int, _ : Int, _ : Int -> 255 }
|
||||
{ _, _, _ -> 255 }
|
||||
}
|
||||
|
||||
renderScanLineFunc = selectRenderFunc()
|
||||
|
@ -402,11 +404,10 @@ internal class IdatDecoder(
|
|||
inflateBufferQueue.readBytes(baLine, 0, scanLineBytes)
|
||||
|
||||
val filterNum = baLine.getUInt8(0)
|
||||
val filterType = FilterType.values().first { it.num == filterNum }
|
||||
|
||||
// if( callback.canApngDebug() ) callback.onApngDebug("y=$passY/${passHeight},filterType=$filterType")
|
||||
|
||||
when(filterType) {
|
||||
when (FilterType.values().first { it.num == filterNum }) {
|
||||
FilterType.None -> {
|
||||
}
|
||||
|
||||
|
@ -505,7 +506,7 @@ internal class IdatDecoder(
|
|||
|
||||
// inBufferのサイズに合わせて読み込む
|
||||
var nRead = 0
|
||||
val nReadMax = Math.min(inBuffer.size, inRemain)
|
||||
val nReadMax = min(inBuffer.size, inRemain)
|
||||
while (true) {
|
||||
|
||||
val remain = nReadMax - nRead
|
||||
|
@ -538,9 +539,12 @@ internal class IdatDecoder(
|
|||
inflateBufferPool.recycle(buffer)
|
||||
} else {
|
||||
inflateBufferQueue.add(ByteSequence(buffer, 0, nInflated))
|
||||
|
||||
// キューに追加したデータをScanLine単位で消費する
|
||||
@Suppress("ControlFlowWithEmptyBody")
|
||||
while (!isCompleted && readScanLine()){
|
||||
}
|
||||
|
||||
if (isCompleted) {
|
||||
inflateBufferQueue.clear()
|
||||
break
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package jp.juggler.apng.util
|
||||
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
internal class ByteSequenceQueue(private val bufferRecycler : (ByteSequence) -> Unit) {
|
||||
|
||||
private val list = LinkedList<ByteSequence>()
|
||||
|
||||
val remain : Int
|
||||
get() = list.sumBy { it.length }
|
||||
get() = list.sumOf { it.length }
|
||||
|
||||
fun add(range : ByteSequence) =list.add(range)
|
||||
|
||||
|
@ -22,7 +23,7 @@ internal class ByteSequenceQueue(private val bufferRecycler : (ByteSequence) ->
|
|||
bufferRecycler(item)
|
||||
list.removeFirst()
|
||||
} else {
|
||||
val delta = Math.min(item.length, dstRemain)
|
||||
val delta = min(item.length, dstRemain)
|
||||
System.arraycopy(item.array, item.offset, dst, dstOffset, delta)
|
||||
dstOffset += delta
|
||||
dstRemain -= delta
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.util.Log
|
|||
import java.io.InputStream
|
||||
import java.util.ArrayList
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class ApngFrames private constructor(
|
||||
private val pixelSizeMax : Int = 0,
|
||||
|
@ -126,7 +127,16 @@ class ApngFrames private constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private val apngHeadKey = byteArrayOf(0x89.toByte(),0x50)
|
||||
private val gifHeadKey = "GIF".toByteArray(Charsets.UTF_8)
|
||||
|
||||
private fun matchBytes(ba1:ByteArray,ba2:ByteArray,length:Int=min(ba1.size,ba2.size)):Boolean{
|
||||
for( i in 0 until length){
|
||||
if( ba1[i] != ba2[i] ) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun parse(
|
||||
pixelSizeMax : Int,
|
||||
debug : Boolean = false,
|
||||
|
@ -136,18 +146,11 @@ class ApngFrames private constructor(
|
|||
val buf = ByteArray(8) { 0.toByte() }
|
||||
opener()?.use { it.read(buf, 0, buf.size) }
|
||||
|
||||
if(buf.size >= 8
|
||||
&& (buf[0].toInt() and 0xff) == 0x89
|
||||
&& (buf[1].toInt() and 0xff) == 0x50
|
||||
) {
|
||||
if(buf.size >= 8 && matchBytes(buf, apngHeadKey) ) {
|
||||
return opener()?.use { parseApng(it, pixelSizeMax, debug) }
|
||||
}
|
||||
|
||||
if(buf.size >= 6
|
||||
&& buf[0].toChar() == 'G'
|
||||
&& buf[1].toChar() == 'I'
|
||||
&& buf[2].toChar() == 'F'
|
||||
) {
|
||||
if(buf.size >= 6 && matchBytes(buf, gifHeadKey) ) {
|
||||
return opener()?.use { parseGif(it, pixelSizeMax, debug) }
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,9 @@ dependencies {
|
|||
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$appcompat_version"
|
||||
//noinspection KtxExtensionAvailable
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
|
||||
|
||||
|
||||
// DrawerLayout
|
||||
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
|
||||
|
@ -113,12 +116,12 @@ dependencies {
|
|||
implementation "androidx.browser:browser:1.3.0"
|
||||
|
||||
// Recyclerview
|
||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
||||
implementation "androidx.recyclerview:recyclerview:1.2.0"
|
||||
|
||||
kapt 'androidx.annotation:annotation:1.1.0'
|
||||
kapt 'androidx.annotation:annotation:1.2.0'
|
||||
|
||||
// https://firebase.google.com/support/release-notes/android
|
||||
implementation "com.google.firebase:firebase-messaging:21.0.1"
|
||||
implementation "com.google.firebase:firebase-messaging:21.1.0"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
|
@ -174,7 +177,7 @@ dependencies {
|
|||
|
||||
implementation 'com.astuetz:pagerslidingtabstrip:1.0.1'
|
||||
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.12.0'
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.13.3'
|
||||
/*
|
||||
WARNING: [Processor] Library '…\exoplayer-ui-2.12.0.aar' contains references to both AndroidX and old support library. This seems like the library is partially migrated. Jetifier will try to rewrite the library anyway.
|
||||
Example of androidX reference: 'androidx/core/app/NotificationCompat$Builder'
|
||||
|
|
|
@ -48,15 +48,15 @@ class WordTrieTreeTest {
|
|||
val tokenizer = CharacterGroup.Tokenizer().reset(strTest, 0, strTest.length)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals('A'.toInt(), id)
|
||||
assertEquals('A'.code, id)
|
||||
assertEquals((whitespace_len + 1), tokenizer.offset) // offset は Aの次の位置になる
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals('B'.toInt(), id)
|
||||
assertEquals('B'.code, id)
|
||||
assertEquals((whitespace_len + 2).toLong(), tokenizer.offset.toLong())
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals('C'.toInt(), id)
|
||||
assertEquals('C'.code, id)
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
//
|
||||
id = tokenizer.next()
|
||||
|
@ -71,15 +71,15 @@ class WordTrieTreeTest {
|
|||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 1).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('A'.toInt(), id)
|
||||
assertEquals('A'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 2).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('B'.toInt(), id)
|
||||
assertEquals('B'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('C'.toInt(), id)
|
||||
assertEquals('C'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
|
@ -93,15 +93,15 @@ class WordTrieTreeTest {
|
|||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 1).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('A'.toInt(), id)
|
||||
assertEquals('A'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 2).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('B'.toInt(), id)
|
||||
assertEquals('B'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('C'.toInt(), id)
|
||||
assertEquals('C'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
|
@ -115,15 +115,15 @@ class WordTrieTreeTest {
|
|||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 1).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('A'.toInt(), id)
|
||||
assertEquals('A'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 2).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('B'.toInt(), id)
|
||||
assertEquals('B'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
assertEquals('C'.toInt(), id)
|
||||
assertEquals('C'.code, id)
|
||||
//
|
||||
id = tokenizer.next()
|
||||
assertEquals((whitespace_len + 3).toLong(), tokenizer.offset.toLong())
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<!-- CAMERAパーミッションをつけるとPlayストアにプライバシーポリシーを記載する必要がある -->
|
||||
|
|
|
@ -35,22 +35,39 @@ class ActAbout : AppCompatActivity() {
|
|||
|
||||
// git log --pretty=format:"%an %s" |grep "Translated using Weblate"|sort|uniq
|
||||
val translators = arrayOf(
|
||||
Translators("Allan Nordhøy", null, "English & Norwegian Bokmål"),
|
||||
Translators("ButterflyOfFire", "@ButterflyOfFire@mstdn.fr", "Arabic & French"),
|
||||
Translators("Allan Nordhøy", null, "English, Norwegian Bokmål"),
|
||||
Translators("ayiniho", null, "French"),
|
||||
Translators("ButterflyOfFire", "@ButterflyOfFire@mstdn.fr", "Arabic, French, Kabyle"),
|
||||
Translators("Ch", null, "Korean"),
|
||||
Translators("chinnux", "@chinnux@neko.ci", "Chinese (Simplified)"),
|
||||
Translators("Dyxang", null, "Chinese (Simplified)"),
|
||||
Translators("Elizabeth Sherrock", null, "Chinese (Simplified)"),
|
||||
Translators("Gennady Archangorodsky", null, "Hebrew"),
|
||||
Translators("inqbs Siina", null, "Korean"),
|
||||
Translators("J. Lavoie", null, "French, German"),
|
||||
Translators("Jeong Arm", "@jarm@qdon.space", "Korean"),
|
||||
Translators("Joan Pujolar", "@jpujolar@mastodont.cat", "Catalan"),
|
||||
Translators("Kai Zhang", "@bearzk@mastodon.social", "Chinese (Simplified)"),
|
||||
Translators("koyu", null, "German"),
|
||||
Translators("Liaizon Wakest", null, "English"),
|
||||
Translators("lingcas", null, "Chinese (Traditional)"),
|
||||
Translators("Love Xu", null, "Chinese (Simplified)"),
|
||||
Translators("lptprjh", null, "Korean"),
|
||||
Translators("mv87", null, "German"),
|
||||
Translators("mynameismonkey", null, "Welsh"),
|
||||
Translators("Nathan", null, "French"),
|
||||
Translators("Niek Visser", null, "Dutch"),
|
||||
Translators("Owain Rhys Lewis", null, "Welsh"),
|
||||
Translators("Remi Rampin", null, "French"),
|
||||
Translators("Sachin", null, "Kannada"),
|
||||
Translators("Swann Martinet", null, "French"),
|
||||
Translators("takubunn", null, "Chinese (Simplified)"),
|
||||
Translators("배태길", null, "Korea")
|
||||
Translators("Whod", null, "Bulgarian"),
|
||||
Translators("yucj", null, "Chinese (Traditional)"),
|
||||
Translators("邓志诚", null, "Chinese (Simplified)"),
|
||||
Translators("배태길", null, "Korea"),
|
||||
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
spResizeImage = findViewById(R.id.spResizeImage)
|
||||
|
||||
imageResizeItems = SavedAccount.resizeConfigList.map {
|
||||
var caption = when (it.type) {
|
||||
val caption = when (it.type) {
|
||||
ResizeType.None -> getString(R.string.dont_resize)
|
||||
ResizeType.LongSide -> getString(R.string.long_side_pixel, it.size)
|
||||
ResizeType.SquarePixel -> if (it.extraStringId != 0) {
|
||||
|
@ -436,7 +436,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
btnNotificationStyleEditReply.setOnClickListener(this)
|
||||
|
||||
|
||||
spResizeImage.setOnItemSelectedListener(this)
|
||||
spResizeImage.onItemSelectedListener = this
|
||||
|
||||
|
||||
btnNotificationStyleEditReply.vg(Pref.bpSeparateReplyNotificationGroup(pref))
|
||||
|
|
|
@ -1125,7 +1125,7 @@ class ActPost : AsyncActivity(),
|
|||
}
|
||||
} else {
|
||||
if (editable.isNotEmpty()
|
||||
&& !CharacterGroup.isWhitespace(editable[editable.length - 1].toInt())
|
||||
&& !CharacterGroup.isWhitespace(editable[editable.length - 1].code)
|
||||
) {
|
||||
editable.append(' ')
|
||||
}
|
||||
|
@ -2571,7 +2571,7 @@ class ActPost : AsyncActivity(),
|
|||
val e = etContent.editableText
|
||||
val len = e.length
|
||||
val last_char = if (len <= 0) ' ' else e[len - 1]
|
||||
if (!CharacterGroup.isWhitespace(last_char.toInt())) {
|
||||
if (!CharacterGroup.isWhitespace(last_char.code)) {
|
||||
e.append(" ").append(a.text_url)
|
||||
} else {
|
||||
e.append(a.text_url)
|
||||
|
|
|
@ -3,7 +3,6 @@ package jp.juggler.subwaytooter.action
|
|||
import android.app.AlertDialog
|
||||
import jp.juggler.subwaytooter.ActColumnList
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.TootApplication
|
||||
import jp.juggler.subwaytooter.table.MutedApp
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package jp.juggler.subwaytooter.action
|
||||
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.api.TootApiResult
|
||||
|
|
|
@ -2,7 +2,6 @@ package jp.juggler.subwaytooter.action
|
|||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.ColumnType
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
|
|
|
@ -2,7 +2,6 @@ package jp.juggler.subwaytooter.action
|
|||
|
||||
import android.app.AlertDialog
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
|
|
|
@ -47,7 +47,7 @@ class Host private constructor(
|
|||
val cached = hostSet[srcArg]
|
||||
if(cached != null) return cached
|
||||
val src = srcArg.removeUrlSchema()
|
||||
val ascii = IDN.toASCII(src, IDN.ALLOW_UNASSIGNED).toLowerCase(Locale.JAPAN)
|
||||
val ascii = IDN.toASCII(src, IDN.ALLOW_UNASSIGNED).lowercase()
|
||||
val pretty = IDN.toUnicode(src, IDN.ALLOW_UNASSIGNED)
|
||||
val host = if(ascii == pretty) Host(ascii) else Host(ascii, pretty)
|
||||
hostSet[src] = host
|
||||
|
|
|
@ -427,7 +427,7 @@ class TootInstance(parser: TootParser, src: JsonObject) {
|
|||
|
||||
private fun Host.getCacheEntry(): CacheEntry =
|
||||
synchronized(_hostCache) {
|
||||
val hostLower = ascii.toLowerCase(Locale.JAPAN)
|
||||
val hostLower = ascii.lowercase()
|
||||
var item = _hostCache[hostLower]
|
||||
if (item == null) {
|
||||
item = CacheEntry()
|
||||
|
|
|
@ -240,7 +240,7 @@ class TootPolls (
|
|||
TootStatus.parseTime(src.string("endTime")).notZero() ?: Long.MAX_VALUE
|
||||
this.expired = expired_at >= System.currentTimeMillis()
|
||||
this.multiple = src.containsKey("anyOf")
|
||||
this.votes_count = items?.sumBy{ it.votes?: 0 }?.notZero()
|
||||
this.votes_count = items?.sumOf{ it.votes ?: 0 }?.notZero()
|
||||
|
||||
this.ownVoted = false
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ open class TootTag constructor(
|
|||
|
||||
init {
|
||||
countDaily = history?.first()?.uses ?: 0
|
||||
countWeekly = history?.sumBy { it.uses } ?: 0
|
||||
countWeekly = history?.sumOf{ it.uses } ?: 0
|
||||
|
||||
accountDaily = history?.first()?.accounts ?: 0
|
||||
accountWeekly = history?.map { it.accounts }?.maxOrNull() ?: accountDaily
|
||||
|
|
|
@ -38,33 +38,31 @@ object AccountPicker {
|
|||
extra_callback: (LinearLayout, Int, Int) -> Unit = { _, _, _ -> },
|
||||
callback: SavedAccountCallback
|
||||
) {
|
||||
var removeMastodon = 0
|
||||
var removedMisskey = 0
|
||||
var removedPseudo = 0
|
||||
var removeMastodon = 0
|
||||
val account_list : MutableList<SavedAccount> = accountListArg ?: {
|
||||
val l = SavedAccount.loadAccountList(activity).filter { a ->
|
||||
var bOk = true
|
||||
|
||||
if(! bAllowMastodon && ! a.isMisskey) {
|
||||
++ removeMastodon
|
||||
bOk = false
|
||||
fun SavedAccount.checkMastodon() = when {
|
||||
!bAllowMastodon && !isMisskey -> ++removeMastodon
|
||||
else -> 0
|
||||
}
|
||||
|
||||
if(! bAllowMisskey && a.isMisskey) {
|
||||
++ removedMisskey
|
||||
bOk = false
|
||||
fun SavedAccount.checkMisskey() = when {
|
||||
!bAllowMisskey && isMisskey -> ++removedMisskey
|
||||
else -> 0
|
||||
}
|
||||
|
||||
if(! bAllowPseudo && a.isPseudo) {
|
||||
++ removedPseudo
|
||||
bOk = false
|
||||
fun SavedAccount.checkPseudo() = when {
|
||||
!bAllowPseudo && isPseudo -> ++removedPseudo
|
||||
else -> 0
|
||||
}
|
||||
|
||||
bOk
|
||||
}.toMutableList()
|
||||
SavedAccount.sort(l)
|
||||
l
|
||||
}()
|
||||
|
||||
val account_list: MutableList<SavedAccount> = accountListArg
|
||||
?: SavedAccount.loadAccountList(activity)
|
||||
.filter { 0 == it.checkMastodon() + it.checkMisskey() + it.checkPseudo() }
|
||||
.toMutableList()
|
||||
.also { SavedAccount.sort(it) }
|
||||
|
||||
if (account_list.isEmpty()) {
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ class EmojiPicker(
|
|||
val entries = newList.entries
|
||||
custom_list.clear()
|
||||
custom_categories.clear()
|
||||
custom_list.ensureCapacity(entries.sumBy { it.value.size })
|
||||
custom_list.ensureCapacity(entries.sumOf { it.value.size })
|
||||
custom_categories.ensureCapacity(entries.size)
|
||||
entries.forEach {
|
||||
val rangeStart = custom_list.size
|
||||
|
|
|
@ -131,7 +131,7 @@ object LoginForm {
|
|||
val br = BufferedReader(InputStreamReader(inStream, "UTF-8"))
|
||||
while(true) {
|
||||
val s : String =
|
||||
br.readLine()?.trim { it <= ' ' }?.toLowerCase(Locale.JAPAN) ?: break
|
||||
br.readLine()?.trim { it <= ' ' }?.lowercase() ?: break
|
||||
if(s.isEmpty()) continue
|
||||
add(s)
|
||||
add(IDN.toASCII(s, IDN.ALLOW_UNASSIGNED))
|
||||
|
@ -155,7 +155,7 @@ object LoginForm {
|
|||
override fun performFiltering(constraint : CharSequence?) : FilterResults =
|
||||
FilterResults().also { result ->
|
||||
if(constraint?.isNotEmpty() == true) {
|
||||
val key = constraint.toString().toLowerCase(Locale.JAPAN)
|
||||
val key = constraint.toString().lowercase()
|
||||
// suggestions リストは毎回生成する必要がある。publishResultsと同時にアクセスされる場合がある
|
||||
val suggestions = StringArray()
|
||||
for(s in instance_list) {
|
||||
|
|
|
@ -59,7 +59,7 @@ class PollingForegrounder : IntentService("PollingForegrounder") {
|
|||
intent_click.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
val pi_click = PendingIntent.getActivity(
|
||||
context, 2, intent_click,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or (if(Build.VERSION.SDK_INT>=23) PendingIntent.FLAG_IMMUTABLE else 0)
|
||||
)
|
||||
|
||||
val builder = if (Build.VERSION.SDK_INT >= 26) {
|
||||
|
|
|
@ -692,7 +692,7 @@ class TaskRunner(
|
|||
// FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY を付与してはいけない
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
},
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or (if(Build.VERSION.SDK_INT>=23) PendingIntent.FLAG_IMMUTABLE else 0)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -705,7 +705,7 @@ class TaskRunner(
|
|||
data =
|
||||
"subwaytooter://notification_delete/?$params".toUri()
|
||||
},
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or (if(Build.VERSION.SDK_INT>=23) PendingIntent.FLAG_IMMUTABLE else 0)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -748,7 +748,7 @@ class TaskRunner(
|
|||
context,
|
||||
3,
|
||||
intent_click,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or (if(Build.VERSION.SDK_INT>=23) PendingIntent.FLAG_IMMUTABLE else 0)
|
||||
)
|
||||
|
||||
val builder = if (Build.VERSION.SDK_INT >= 26) {
|
||||
|
|
|
@ -50,7 +50,7 @@ class AcctColor {
|
|||
|
||||
fun save(now : Long) {
|
||||
|
||||
val key = acctAscii.toLowerCase(Locale.ENGLISH)
|
||||
val key = acctAscii.lowercase()
|
||||
|
||||
try {
|
||||
val cv = ContentValues()
|
||||
|
@ -137,7 +137,7 @@ class AcctColor {
|
|||
fun load(acct:Acct) =load(acct.ascii,acct.pretty)
|
||||
|
||||
fun load(acctAscii: String,acctPretty : String) : AcctColor {
|
||||
val key = acctAscii.toLowerCase(Locale.ENGLISH)
|
||||
val key = acctAscii.lowercase()
|
||||
val cached : AcctColor? = mMemoryCache.get(key)
|
||||
if(cached != null) return cached
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package jp.juggler.subwaytooter.table
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.provider.BaseColumns
|
||||
import jp.juggler.subwaytooter.App1
|
||||
|
|
|
@ -28,9 +28,9 @@ object EmojiDecoder {
|
|||
|
||||
// private val log = LogCategory("EmojiDecoder")
|
||||
|
||||
private const val cpColon = ':'.toInt()
|
||||
private const val cpColon = ':'.code
|
||||
|
||||
private const val cpZwsp = '\u200B'.toInt()
|
||||
private const val cpZwsp = '\u200B'.code
|
||||
|
||||
var handleUnicodeEmoji = true
|
||||
|
||||
|
@ -223,7 +223,7 @@ object EmojiDecoder {
|
|||
continue
|
||||
}
|
||||
|
||||
val nextChar = if (result.endPos >= end) null else s[result.endPos].toInt()
|
||||
val nextChar = if (result.endPos >= end) null else s[result.endPos].code
|
||||
|
||||
// 絵文字バリエーション・シーケンス(EVS)のU+FE0E(VS-15)が直後にある場合
|
||||
// その文字を絵文字化しない
|
||||
|
@ -232,7 +232,7 @@ object EmojiDecoder {
|
|||
continue
|
||||
}
|
||||
|
||||
val emoji = if (nextChar == 0xFE0F && s[result.endPos - 1].toInt() != 0xFE0F) {
|
||||
val emoji = if (nextChar == 0xFE0F && s[result.endPos - 1].code != 0xFE0F) {
|
||||
// 絵文字の最後が 0xFE0F でない
|
||||
// 直後にU+0xFE0F (絵文字バリエーション・シーケンスEVSのVS-16)がある
|
||||
// 直後のそれまで含めて絵文字として表示する
|
||||
|
@ -246,16 +246,16 @@ object EmojiDecoder {
|
|||
}
|
||||
}
|
||||
|
||||
private const val codepointColon = ':'.toInt()
|
||||
private const val codepointColon = ':'.code
|
||||
// private const val codepointAtmark = '@'.toInt()
|
||||
|
||||
private val shortCodeCharacterSet =
|
||||
SparseBooleanArray().apply {
|
||||
for (c in 'A'..'Z') put(c.toInt(), true)
|
||||
for (c in 'a'..'z') put(c.toInt(), true)
|
||||
for (c in '0'..'9') put(c.toInt(), true)
|
||||
for (c in "+-_@:") put(c.toInt(), true)
|
||||
for (c in ".") put(c.toInt(), true)
|
||||
for (c in 'A'..'Z') put(c.code, true)
|
||||
for (c in 'a'..'z') put(c.code, true)
|
||||
for (c in '0'..'9') put(c.code, true)
|
||||
for (c in "+-_@:") put(c.code, true)
|
||||
for (c in ".") put(c.code, true)
|
||||
}
|
||||
|
||||
private interface ShortCodeSplitterCallback {
|
||||
|
@ -392,7 +392,7 @@ object EmojiDecoder {
|
|||
else -> {
|
||||
// EmojiOneのショートコード
|
||||
val emoji = if (useEmojioneShortcode) {
|
||||
EmojiMap.shortNameMap[name.toLowerCase(Locale.JAPAN).replace('-', '_')]
|
||||
EmojiMap.shortNameMap[name.lowercase().replace('-', '_')]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ object EmojiDecoder {
|
|||
|
||||
// カスタム絵文字ではなく通常の絵文字のショートコードなら絵文字に変換する
|
||||
val emoji = if (decodeEmojioneShortcode) {
|
||||
EmojiMap.shortNameMap[name.toLowerCase(Locale.JAPAN).replace('-', '_')]
|
||||
EmojiMap.shortNameMap[name.lowercase().replace('-', '_')]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ object HTMLDecoder {
|
|||
val m = reTag.matcher(text)
|
||||
if (m.find()) {
|
||||
val is_close = m.groupEx(1)!!.isNotEmpty()
|
||||
tag = m.groupEx(2)!!.toLowerCase(Locale.JAPAN)
|
||||
tag = m.groupEx(2)!!.lowercase()
|
||||
|
||||
val m2 = reTagEnd.matcher(text)
|
||||
val is_openclose = when {
|
||||
|
@ -369,15 +369,15 @@ object HTMLDecoder {
|
|||
ArrayList<SpannableStringBuilder>().also { dst ->
|
||||
// 入力の末尾のtrim
|
||||
var end = this.length
|
||||
while (end > 0 && CharacterGroup.isWhitespace(this[end - 1].toInt())) --end
|
||||
while (end > 0 && CharacterGroup.isWhitespace(this[end - 1].code)) --end
|
||||
|
||||
// 入力の最初の非空白文字の位置を調べておく
|
||||
var firstNonSpace = 0
|
||||
while (firstNonSpace <end && CharacterGroup.isWhitespace(this[firstNonSpace].toInt())) ++firstNonSpace
|
||||
while (firstNonSpace <end && CharacterGroup.isWhitespace(this[firstNonSpace].code)) ++firstNonSpace
|
||||
|
||||
var i = 0
|
||||
while (i < end) {
|
||||
var lineStart = i
|
||||
val lineStart = i
|
||||
while (i < end && this[i] != '\n') ++i
|
||||
val lineEnd = if (i >= end) end else i + 1
|
||||
++i
|
||||
|
@ -758,7 +758,7 @@ object HTMLDecoder {
|
|||
val dst = HashMap<String, String>()
|
||||
val m = reAttribute.matcher(text)
|
||||
while (m.find()) {
|
||||
val name = m.groupEx(1)!!.toLowerCase(Locale.JAPAN)
|
||||
val name = m.groupEx(1)!!.lowercase()
|
||||
val value = decodeEntity(m.groupEx(3))
|
||||
dst[name] = value
|
||||
}
|
||||
|
|
|
@ -367,10 +367,10 @@ object MisskeySyntaxHighlighter {
|
|||
addAll(_keywords)
|
||||
|
||||
// UPPER
|
||||
addAll(_keywords.map { k -> k.toUpperCase(Locale.JAPAN) })
|
||||
addAll(_keywords.map { it.uppercase() })
|
||||
|
||||
// Snake
|
||||
addAll(_keywords.map { k -> k[0].toUpperCase() + k.substring(1) })
|
||||
addAll(_keywords.map { k -> k[0].uppercase() + k.substring(1) })
|
||||
|
||||
add("NaN")
|
||||
|
||||
|
@ -378,12 +378,12 @@ object MisskeySyntaxHighlighter {
|
|||
}
|
||||
|
||||
private val symbolMap = SparseBooleanArray().apply {
|
||||
"=+-*/%~^&|><!?".forEach { put(it.toInt(), true) }
|
||||
"=+-*/%~^&|><!?".forEach { put(it.code, true) }
|
||||
}
|
||||
|
||||
// 文字列リテラルの開始文字のマップ
|
||||
private val stringStart = SparseBooleanArray().apply {
|
||||
"\"'`".forEach { put(it.toInt(), true) }
|
||||
"\"'`".forEach { put(it.code, true) }
|
||||
}
|
||||
|
||||
private class Token(
|
||||
|
@ -536,7 +536,7 @@ object MisskeySyntaxHighlighter {
|
|||
// string
|
||||
{
|
||||
val beginChar = source[pos]
|
||||
if (!stringStart[beginChar.toInt()]) return@arrayOf null
|
||||
if (!stringStart[beginChar.code]) return@arrayOf null
|
||||
var i = pos + 1
|
||||
while (i < end) {
|
||||
val char = source[i++]
|
||||
|
@ -653,7 +653,7 @@ object MisskeySyntaxHighlighter {
|
|||
{
|
||||
val c = source[pos]
|
||||
when {
|
||||
symbolMap.get(c.toInt(), false) ->
|
||||
symbolMap.get(c.code, false) ->
|
||||
Token(length = 1, color = 0x42b983)
|
||||
c == '-' ->
|
||||
Token(length = 1, color = 0x42b983)
|
||||
|
@ -1348,7 +1348,7 @@ object MisskeyMarkdownDecoder {
|
|||
var i = lastEnd //スキャン中の位置
|
||||
while (i < end) {
|
||||
// 注目位置の文字に関連するパーサー
|
||||
val lastParsers = nodeParserMap[text[i].toInt()]
|
||||
val lastParsers = nodeParserMap[text[i].code]
|
||||
if (lastParsers == null) {
|
||||
++i
|
||||
continue
|
||||
|
@ -1538,8 +1538,11 @@ object MisskeyMarkdownDecoder {
|
|||
}
|
||||
|
||||
// \} \]はムダなエスケープに見えるが、androidでは必要なので削ってはいけない
|
||||
@Suppress("RegExpRedundantEscape")
|
||||
private val reLatexRemove = """\\(?:quad|Huge|atop|sf|scriptsize|bf|small|tiny|underline|large|(?:color)\{[^}]*\})""".toRegex()
|
||||
@Suppress("RegExpRedundantEscape")
|
||||
private val reLatex1 = """\\(?:(?:url)|(?:textcolor|colorbox)\{[^}]*\}|(?:fcolorbox|raisebox)\{[^}]*\}\{[^}]*\}|includegraphics\[[^]]*\])\{([^}]*)\}""".toRegex()
|
||||
@Suppress("RegExpRedundantEscape")
|
||||
private val reLatex2reversed = """\\(?:overset|href)\{([^}]+)\}\{([^}]+)\}""".toRegex()
|
||||
|
||||
private fun String.removeLatex(): String {
|
||||
|
@ -1586,7 +1589,7 @@ object MisskeyMarkdownDecoder {
|
|||
vararg nodeParsers: NodeParseEnv.() -> NodeDetected?
|
||||
) {
|
||||
for (s in firstChars) {
|
||||
put(s.toInt(), nodeParsers)
|
||||
put(s.code, nodeParsers)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1808,15 +1811,15 @@ object MisskeyMarkdownDecoder {
|
|||
// メールアドレスの@の手前に使える文字なら真
|
||||
val mailChars = SparseBooleanArray().apply {
|
||||
for (it in '0'..'9') {
|
||||
put(it.toInt(), true)
|
||||
put(it.code, true)
|
||||
}
|
||||
for (it in 'A'..'Z') {
|
||||
put(it.toInt(), true)
|
||||
put(it.code, true)
|
||||
}
|
||||
for (it in 'a'..'z') {
|
||||
put(it.toInt(), true)
|
||||
put(it.code, true)
|
||||
}
|
||||
"""${'$'}!#%&'`"*+-/=?^_{|}~""".forEach { put(it.toInt(), true) }
|
||||
"""${'$'}!#%&'`"*+-/=?^_{|}~""".forEach { put(it.code, true) }
|
||||
}
|
||||
|
||||
addParser("@", {
|
||||
|
|
|
@ -760,7 +760,7 @@ class PostHelper(
|
|||
val cp = src.codePointBefore(i)
|
||||
i -= Character.charCount(cp)
|
||||
|
||||
if (cp == '@'.toInt()) {
|
||||
if (cp == '@'.code) {
|
||||
start = i
|
||||
if (++count_atMark >= 2) break else continue
|
||||
} else if (count_atMark == 1) {
|
||||
|
@ -865,7 +865,7 @@ class PostHelper(
|
|||
val remain = limit - code_list.size
|
||||
if (remain > 0) {
|
||||
val s =
|
||||
src.substring(last_colon + 1, end).toLowerCase(Locale.JAPAN).replace('-', '_')
|
||||
src.substring(last_colon + 1, end).lowercase().replace('-', '_')
|
||||
val matches = EmojiDecoder.searchShortCode(activity, s, remain)
|
||||
log.d("checkEmoji: search for %s, result=%d", s, matches.size)
|
||||
code_list.addAll(matches)
|
||||
|
|
|
@ -18,7 +18,7 @@ class Blurhash(blurhash : String, punch : Float = 1f) {
|
|||
private val base83Map = SparseIntArray().apply {
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"
|
||||
.forEachIndexed { index, c ->
|
||||
put(c.toInt(), index)
|
||||
put(c.code, index)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,9 @@ class Blurhash(blurhash : String, punch : Float = 1f) {
|
|||
private fun String.decodeBase83(start : Int, length : Int) : Int {
|
||||
var v = 0
|
||||
for(i in start until start + length) {
|
||||
val ci = this[i].toInt()
|
||||
val ci = this[i].code
|
||||
val idx = base83Map.get(ci, - 1)
|
||||
if(idx == - 1) {
|
||||
error("decodeBase83: incorrect char code $ci")
|
||||
}
|
||||
if(idx == - 1) error("decodeBase83: incorrect char code $ci")
|
||||
v = v * 83 + idx
|
||||
}
|
||||
return v
|
||||
|
|
|
@ -109,7 +109,7 @@ object CharacterGroup {
|
|||
var id = Integer.MAX_VALUE
|
||||
for(s in list) {
|
||||
if(s.length == 1) {
|
||||
val c = s[0].toInt()
|
||||
val c = s[0].code
|
||||
if(c < id) id = c
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ object CharacterGroup {
|
|||
// ユニコード文字を正規化する。
|
||||
// 簡易版なので全ての文字には対応していない
|
||||
fun getUnifiedCharacter(c : Char) : Char {
|
||||
val v1 = map1[c.toInt()]
|
||||
val v1 = map1[c.code]
|
||||
return if(v1 != 0) v1.toChar() else c
|
||||
}
|
||||
|
||||
|
@ -145,13 +145,13 @@ object CharacterGroup {
|
|||
val map : SparseIntArray
|
||||
val key : Int
|
||||
|
||||
val v1 = s[0].toInt()
|
||||
val v1 = s[0].code
|
||||
if(s.length == 1) {
|
||||
map = map1
|
||||
key = v1
|
||||
} else {
|
||||
map = map2
|
||||
val v2 = s[1].toInt()
|
||||
val v2 = s[1].code
|
||||
key = v1 or (v2 shl 16)
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ object CharacterGroup {
|
|||
var pos = offset
|
||||
|
||||
// 空白を読み飛ばす
|
||||
while(pos < end && isWhitespace(text[pos].toInt())) ++ pos
|
||||
while(pos < end && isWhitespace(text[pos].code)) ++ pos
|
||||
|
||||
// 終端までの文字数
|
||||
val remain = end - pos
|
||||
|
@ -193,7 +193,7 @@ object CharacterGroup {
|
|||
return END
|
||||
}
|
||||
|
||||
val v1 = text[pos].toInt()
|
||||
val v1 = text[pos].code
|
||||
|
||||
// グループに登録された文字を長い順にチェック
|
||||
var check_len = if(remain > 2) 2 else remain
|
||||
|
@ -201,7 +201,7 @@ object CharacterGroup {
|
|||
val group_id = if(check_len == 1)
|
||||
map1.get(v1)
|
||||
else
|
||||
map2.get(v1 or (text[pos + 1].toInt() shl 16))
|
||||
map2.get(v1 or (text[pos + 1].code shl 16))
|
||||
if(group_id != 0) {
|
||||
this.offset = pos + check_len
|
||||
return group_id
|
||||
|
|
|
@ -853,7 +853,7 @@ private fun Writer.writeQuote(string: String): Writer {
|
|||
in '\u0080' until '\u00a0',
|
||||
in '\u2000' until '\u2100' -> {
|
||||
write("\\u")
|
||||
val hexCode: String = Integer.toHexString(c.toInt())
|
||||
val hexCode: String = Integer.toHexString(c.code)
|
||||
write("0000", 0, 4 - hexCode.length)
|
||||
write(hexCode)
|
||||
}
|
||||
|
@ -1046,7 +1046,7 @@ fun Writer.writeJsonValue(
|
|||
}
|
||||
}
|
||||
|
||||
value is Char -> writeJsonValue(indentFactor, indent, value.toInt(), sort = sort)
|
||||
value is Char -> writeJsonValue(indentFactor, indent, value.code, sort = sort)
|
||||
|
||||
value is String -> writeQuote(value)
|
||||
value is Enum<*> -> writeQuote(value.name)
|
||||
|
|
|
@ -182,7 +182,7 @@ private val mimeTypeExMap : HashMap<String, String> by lazy {
|
|||
fun getMimeType(log : LogCategory?, src : String) : String {
|
||||
var ext = MimeTypeMap.getFileExtensionFromUrl(src)
|
||||
if(ext != null && ext.isNotEmpty()) {
|
||||
ext = ext.toLowerCase(Locale.US)
|
||||
ext = ext.lowercase()
|
||||
|
||||
//
|
||||
var mime_type : String? = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext)
|
||||
|
|
|
@ -81,7 +81,7 @@ fun IntArray.toByteArray(): ByteArray {
|
|||
fun CharArray.toLowerByteArray(): ByteArray {
|
||||
val dst = ByteArray(this.size)
|
||||
for (i in this.indices) {
|
||||
dst[i] = this[i].toByte()
|
||||
dst[i] = this[i].code.toByte()
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ fun CharSequence.codePointBefore(index: Int): Int {
|
|||
val c1 = this[index - 2]
|
||||
if (Character.isHighSurrogate(c1)) return Character.toCodePoint(c1, c2)
|
||||
}
|
||||
return c2.toInt()
|
||||
return c2.code
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ class WordTrieTree {
|
|||
val t = CharacterGroup.Tokenizer()
|
||||
|
||||
for(i in start until end) {
|
||||
if(! CharacterGroup.isWhitespace(src[i].toInt())) {
|
||||
if(! CharacterGroup.isWhitespace(src[i].code)) {
|
||||
val item = match(true, t.reset(src, i, end))
|
||||
if(item != null) return item
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ class WordTrieTree {
|
|||
|
||||
var i = start
|
||||
while(i < end) {
|
||||
if(! CharacterGroup.isWhitespace(src[i].toInt())) {
|
||||
if(! CharacterGroup.isWhitespace(src[i].code)) {
|
||||
val item = match(false, t.reset(src, i, end))
|
||||
if(item != null) {
|
||||
if(dst == null) dst = ArrayList()
|
||||
|
|
|
@ -131,11 +131,9 @@ class TestKotlinFeature {
|
|||
// 型が分からないようにするとビルドできるが、intの10とlongの10は異なると判断される
|
||||
// Int.equals も同じ結果
|
||||
assertEquals(false, int10 as Any == long10 as Any)
|
||||
assertEquals(false, int10.equals(long10))
|
||||
|
||||
// Long.equals でも同じ結果
|
||||
assertEquals(false, long10 as Any == int10 as Any)
|
||||
assertEquals(false, long10.equals(int10))
|
||||
|
||||
// 同じ型に変換すると数値が同じだと判定できる
|
||||
assertEquals(true, int10.toLong() == long10)
|
||||
|
|
11
build.gradle
11
build.gradle
|
@ -3,13 +3,15 @@ buildscript {
|
|||
ext.min_sdk_version = 21
|
||||
ext.target_sdk_version = 30
|
||||
ext.compile_sdk_version = 30
|
||||
ext.appcompat_version='1.2.0'
|
||||
|
||||
ext.kotlin_version = '1.4.32'
|
||||
ext.kotlinx_coroutines_version = '1.4.2'
|
||||
ext.appcompat_version='1.2.0'
|
||||
ext.lifecycle_version='2.3.1'
|
||||
|
||||
ext.kotlin_version = '1.5.0'
|
||||
ext.kotlinx_coroutines_version = '1.4.3'
|
||||
ext.anko_version='0.10.8'
|
||||
|
||||
ext.junit_version='4.13.1'
|
||||
ext.junit_version='4.13.2'
|
||||
|
||||
repositories {
|
||||
google()
|
||||
|
@ -20,6 +22,7 @@ buildscript {
|
|||
classpath 'com.android.tools.build:gradle:4.2.0'
|
||||
classpath 'com.google.gms:google-services:4.3.5'
|
||||
|
||||
//noinspection DifferentKotlinGradleVersion
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
classpath "com.github.bjoernq:unmockplugin:0.7.6"
|
||||
|
|
|
@ -34,7 +34,7 @@ object EmojiMap {
|
|||
|
||||
// 素の数字とcopyright,registered, trademark は絵文字にしない
|
||||
fun isIgnored(code: String): Boolean {
|
||||
val c = code[0].toInt()
|
||||
val c = code[0].code
|
||||
return code.length == 1 && c <= 0xae
|
||||
}
|
||||
|
||||
|
|
|
@ -15,17 +15,17 @@ class EmojiTrie<T> {
|
|||
this.data = data
|
||||
return
|
||||
}
|
||||
val c = src[offset].toInt()
|
||||
val c = src[offset].code
|
||||
val next = map[c] ?: EmojiTrie<T>().also { map.put(c, it) }
|
||||
next.append(src, offset + 1, data)
|
||||
}
|
||||
|
||||
fun hasNext(c: Char) = map.containsKey(c.toInt())
|
||||
fun hasNext(c: Char) = map.containsKey(c.code)
|
||||
|
||||
fun get(src: String, offset: Int, end: Int): Result<T>? {
|
||||
// 長い方を優先するので、先に子を調べる
|
||||
if (offset < end)
|
||||
map[src[offset].toInt()]?.get(src, offset + 1, end)
|
||||
map[src[offset].code]?.get(src, offset + 1, end)
|
||||
?.let { return it }
|
||||
return this.data?.let { Result(it, offset) }
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#Wed May 05 20:20:56 JST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
@ -40,6 +40,9 @@ dependencies {
|
|||
implementation project(':apng_android')
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$appcompat_version"
|
||||
//noinspection KtxExtensionAvailable
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
|
|
@ -5,9 +5,6 @@ import android.content.pm.PackageManager
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -15,6 +12,9 @@ import android.widget.AdapterView
|
|||
import android.widget.BaseAdapter
|
||||
import android.widget.ListView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import jp.juggler.apng.ApngFrames
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
@ -55,7 +55,8 @@ class ActList : AppCompatActivity(), CoroutineScope {
|
|||
if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)) {
|
||||
)
|
||||
) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||
|
@ -95,7 +96,7 @@ class ActList : AppCompatActivity(), CoroutineScope {
|
|||
}
|
||||
|
||||
private fun load() = launch {
|
||||
val list = async(Dispatchers.IO) {
|
||||
val list = withContext(Dispatchers.IO) {
|
||||
// RawリソースのIDと名前の一覧
|
||||
R.raw::class.java.fields
|
||||
.mapNotNull { it.get(null) as? Int }
|
||||
|
@ -108,8 +109,7 @@ class ActList : AppCompatActivity(), CoroutineScope {
|
|||
}
|
||||
.toMutableList()
|
||||
.apply { sortBy { it.caption } }
|
||||
|
||||
}.await()
|
||||
}
|
||||
|
||||
listAdapter.list.addAll(list)
|
||||
listAdapter.notifyDataSetChanged()
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.os.SystemClock
|
|||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import jp.juggler.apng.ApngFrames
|
||||
import kotlin.math.max
|
||||
|
||||
class ApngView : View{
|
||||
|
||||
|
@ -64,8 +65,8 @@ class ApngView : View{
|
|||
override fun onSizeChanged(w : Int, h : Int, oldw : Int, oldh : Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
|
||||
wView = Math.max(1, w).toFloat()
|
||||
hView = Math.max(1, h).toFloat()
|
||||
wView = max(1, w).toFloat()
|
||||
hView = max(1, h).toFloat()
|
||||
aspectView = wView / hView
|
||||
|
||||
initializeScale()
|
||||
|
@ -74,8 +75,8 @@ class ApngView : View{
|
|||
private fun initializeScale(){
|
||||
val apngFrames = this.apngFrames
|
||||
if( apngFrames != null) {
|
||||
wImage =Math.max(1, apngFrames.width).toFloat()
|
||||
hImage =Math.max(1, apngFrames.height).toFloat()
|
||||
wImage = max(1, apngFrames.width).toFloat()
|
||||
hImage = max(1, apngFrames.height).toFloat()
|
||||
aspectImage = wImage / hImage
|
||||
|
||||
currentScale = if(aspectView > aspectImage) {
|
||||
|
@ -118,7 +119,7 @@ class ApngView : View{
|
|||
canvas.drawBitmap(bitmap, drawMatrix, paint)
|
||||
|
||||
if( delay != Long.MAX_VALUE){
|
||||
postInvalidateDelayed(Math.max(1L,delay))
|
||||
postInvalidateDelayed(max(1L,delay))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
android:layout_height="match_parent"
|
||||
>
|
||||
<ListView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/listView"
|
||||
|
|
Loading…
Reference in New Issue