This commit is contained in:
tateisu 2021-06-13 20:48:48 +09:00
parent c08a5dfd8e
commit 5f7f486471
37 changed files with 3140 additions and 3186 deletions

View File

@ -840,7 +840,7 @@ class ActAppSetting : AppCompatActivity(), ColorPickerDialogListener, View.OnCli
private fun importAppData2(bConfirm: Boolean, uri: Uri) {
val type = contentResolver.getType(uri)
log.d("importAppData type=%s", type)
log.d("importAppData type=$type")
if (!bConfirm) {
AlertDialog.Builder(this)

View File

@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import jp.juggler.util.LogCategory
import jp.juggler.util.digestSHA256Hex
import okhttp3.internal.toHexString
import org.apache.commons.io.IOUtils
import java.io.File
import java.io.FileOutputStream
@ -32,7 +33,7 @@ class ActCallback : AppCompatActivity() {
}
override fun onCreate(savedInstanceState : Bundle?) {
log.d("onCreate flags=%x", intent.flags)
log.d("onCreate flags=0x${intent.flags.toHexString()}")
super.onCreate(savedInstanceState)
var intent : Intent? = intent

View File

@ -141,7 +141,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
}
override fun onRepeatModeChanged(repeatMode: Int) {
log.d("exoPlayer onRepeatModeChanged %d", repeatMode)
log.d("exoPlayer onRepeatModeChanged $repeatMode", )
}
override fun onPlayerError(error: ExoPlaybackException) {

View File

@ -135,14 +135,14 @@ object AppDataExporter {
Cursor.FIELD_TYPE_FLOAT -> {
val d = cursor.getDouble(i)
if(d.isNaN() || d.isInfinite()) {
log.w("column %s is nan or infinite value.", names[i])
log.w("column ${names[i]} is nan or infinite value.")
} else {
writer.name(names[i])
writer.value(d)
}
}
Cursor.FIELD_TYPE_BLOB -> log.w("column %s is blob.", names[i])
Cursor.FIELD_TYPE_BLOB -> log.w("column ${names[i]} is blob." )
}
}

View File

@ -20,8 +20,6 @@ import jp.juggler.subwaytooter.table.SavedAccount
import jp.juggler.subwaytooter.util.NetworkStateTracker
import jp.juggler.subwaytooter.util.PostAttachment
import jp.juggler.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.apache.commons.io.IOUtils
import java.io.ByteArrayOutputStream
import java.io.File
@ -140,7 +138,7 @@ class AppState(
synchronized(_columnList) { _columnList.elementAtOrNull(i) }
fun columnIndex(column: Column?) =
synchronized(_columnList) { _columnList.indexOf(column).takeIf{ it != -1 } }
synchronized(_columnList) { _columnList.indexOf(column).takeIf { it != -1 } }
fun editColumnList(save: Boolean = true, block: (ArrayList<Column>) -> Unit) {
synchronized(_columnList) {
@ -230,9 +228,9 @@ class AppState(
restartTTS()
} else {
log.d(
"proc_flushSpeechQueue: tts is speaking. queue_count=%d, expire_remain=%.3f",
queue_count,
expire_remain / 1000f
"proc_flushSpeechQueue: tts is speaking. queue_count=${queue_count}, expire_remain=${
String.format("%.3f",expire_remain / 1000f)
}"
)
handler.postDelayed(this, expire_remain)
return
@ -241,7 +239,7 @@ class AppState(
}
val sv = tts_queue.removeFirst()
log.d("proc_flushSpeechQueue: speak %s", sv)
log.d("proc_flushSpeechQueue: speak ${sv}")
val voice_count = voice_list.size
if (voice_count > 0) {
@ -277,7 +275,7 @@ class AppState(
columnList.mapIndexedNotNull { index, column ->
try {
val dst = JsonObject()
ColumnEncoder.encode(column,dst, index)
ColumnEncoder.encode(column, dst, index)
dst
} catch (ex: JsonException) {
log.trace(ex)
@ -381,7 +379,7 @@ class AppState(
context.showToast(false, R.string.text_to_speech_initializing)
log.d("initializing TextToSpeech…")
launchIO{
launchIO {
var tmp_tts: TextToSpeech? = null
@ -395,7 +393,7 @@ class AppState(
R.string.text_to_speech_initialize_failed,
status
)
log.d("speech initialize failed. status=%s", status)
log.d("speech initialize failed. status=${status}" )
return@OnInitListener
}
@ -423,15 +421,8 @@ class AppState(
} else {
val lang = defaultLocale(context).toLanguageTag()
for (v in voice_set) {
log.d(
"Voice %s %s %s",
v.name,
v.locale.toLanguageTag(),
lang
)
if (lang != v.locale.toLanguageTag()) {
continue
}
log.d( "Voice ${ v.name} ${ v.locale.toLanguageTag()} ${lang}" )
if (lang != v.locale.toLanguageTag()) continue
voice_list.add(v)
}
}
@ -603,7 +594,8 @@ class AppState(
}
if (item.sound_type == HighlightWord.SOUND_TYPE_CUSTOM && item.sound_uri.mayUri()
.tryRingtone()) return
.tryRingtone()
) return
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION).tryRingtone()
}

View File

@ -329,7 +329,7 @@ fun Column.isFiltered(item: TootNotification): Boolean {
TootNotification.TYPE_FOLLOW_REQUEST_ACCEPTED_MISSKEY -> {
val who = item.account
if (who != null && favMuteSet?.contains(access_info.getFullAcct(who)) == true) {
Column.log.d("%s is in favMuteSet.", access_info.getFullAcct(who))
Column.log.d("${access_info.getFullAcct(who)} is in favMuteSet.")
return true
}
}
@ -404,21 +404,21 @@ fun Column.checkFiltersForListData(trees: FilterTrees?) {
}
fun reloadFilter(context: Context, access_info: SavedAccount) {
launchMain{
launchMain {
var resultList: ArrayList<TootFilter>? = null
context.runApiTask(
access_info,
progressStyle = ApiTask.PROGRESS_NONE
){client->
client.request(ApiPath.PATH_FILTERS)?.also{ result->
result.jsonArray?.let{
) { client ->
client.request(ApiPath.PATH_FILTERS)?.also { result ->
result.jsonArray?.let {
resultList = TootFilter.parseList(it)
}
}
}
resultList?.let{
resultList?.let {
Column.log.d("update filters for ${access_info.acct.pretty}")
for (column in App1.getAppState(context).columnList) {
if (column.access_info == access_info) {

View File

@ -258,6 +258,7 @@ class ColumnTask_Loading(
column.saveRange(bBottom = true, bTop = true, result = result, list = src)
} else {
column.saveRangeTop(result, src)
true
}
return when {
@ -416,6 +417,7 @@ class ColumnTask_Loading(
column.saveRange(bBottom = true, bTop = true, result = result, list = src)
} else {
column.saveRangeTop(result, src)
true
}
return when {
@ -998,7 +1000,7 @@ class ColumnTask_Loading(
target_status.conversation_main = true
// 祖先
val list_asc = java.util.ArrayList<TootStatus>()
val list_asc = ArrayList<TootStatus>()
while (true) {
if (client.isApiCancelled) return null
queryParams["offset"] = list_asc.size
@ -1012,7 +1014,7 @@ class ColumnTask_Loading(
}
// 直接の子リプライ。(子孫をたどることまではしない)
val list_desc = java.util.ArrayList<TootStatus>()
val list_desc = ArrayList<TootStatus>()
val idSet = HashSet<EntityId>()
var untilId: EntityId? = null
@ -1048,7 +1050,7 @@ class ColumnTask_Loading(
}
// 一つのリストにまとめる
this.list_tmp = java.util.ArrayList<TimelineItem>(
this.list_tmp = ArrayList<TimelineItem>(
list_asc.size + list_desc.size + 2
).apply {
addAll(list_asc.sortedBy { it.time_created_at })
@ -1084,7 +1086,7 @@ class ColumnTask_Loading(
target_status.conversation_main = true
if (conversation_context != null) {
this.list_tmp = java.util.ArrayList(
this.list_tmp = ArrayList(
1
+ (conversation_context.ancestors?.size ?: 0)
+ (conversation_context.descendants?.size ?: 0)

View File

@ -103,8 +103,6 @@ class ColumnTask_Refresh(
sp = holder.scrollPosition
}
if (bBottom) {
val changeList = listOf(
AdapterChange(

View File

@ -237,21 +237,17 @@ class ColumnViewHolder(
val column = this@ColumnViewHolder.column
if (column == null) {
log.d("restoreScrollPosition [%d], column==null", page_idx)
log.d("restoreScrollPosition [${page_idx}], column==null")
return
}
if (column.is_dispose.get()) {
log.d("restoreScrollPosition [%d], column is disposed", page_idx)
log.d("restoreScrollPosition [${page_idx}], column is disposed")
return
}
if (column.hasMultipleViewHolder()) {
log.d(
"restoreScrollPosition [%d] %s , column has multiple view holder. retry later.",
page_idx,
column.getColumnName(true)
)
log.d("restoreScrollPosition [${page_idx}] ${column.getColumnName(true)}, column has multiple view holder. retry later.")
// タブレットモードでカラムを追加/削除した際に発生する。
// このタイミングでスクロール位置を復元してもうまくいかないので延期する
@ -277,30 +273,16 @@ class ColumnViewHolder(
// }
// }
log.d(
"restoreScrollPosition [$page_idx] %s , column has no saved scroll position.",
column.getColumnName(true)
)
log.d("restoreScrollPosition [$page_idx] ${column.getColumnName(true)} , column has no saved scroll position.")
return
}
column.scroll_save = null
if (listView.visibility != View.VISIBLE) {
log.d(
"restoreScrollPosition [$page_idx] %s , listView is not visible. saved position %s,%s is dropped.",
column.getColumnName(true),
sp.adapterIndex,
sp.offset
)
log.d("restoreScrollPosition [$page_idx] ${column.getColumnName(true)} , listView is not visible. saved position ${sp.adapterIndex},${sp.offset} is dropped.")
} else {
log.d(
"restoreScrollPosition [%d] %s , listView is visible. resume %s,%s",
page_idx,
column.getColumnName(true),
sp.adapterIndex,
sp.offset
)
log.d("restoreScrollPosition [${page_idx}] ${column.getColumnName(true)} , listView is visible. resume ${sp.adapterIndex},${sp.offset}")
sp.restore(this@ColumnViewHolder)
}

View File

@ -53,7 +53,7 @@ fun ColumnViewHolder.loadBackgroundImage(iv: ImageView, url: String?) {
val screen_h = iv.resources.displayMetrics.heightPixels
// 非同期処理を開始
last_image_task = launchMain{
last_image_task = launchMain {
val bitmap = try {
withContext(Dispatchers.IO) {
try {
@ -93,7 +93,7 @@ fun ColumnViewHolder.onPageDestroy(page_idx: Int) {
// タブレットモードの場合、onPageCreateより前に呼ばれる
val column = this.column
if (column != null) {
ColumnViewHolder.log.d("onPageDestroy [%d] %s", page_idx, tvColumnName.text)
ColumnViewHolder.log.d("onPageDestroy [${page_idx}] ${tvColumnName.text}")
saveScrollPosition()
listView.adapter = null
column.removeColumnViewHolder(this)
@ -111,7 +111,7 @@ fun ColumnViewHolder.onPageCreate(column: Column, page_idx: Int, page_count: Int
this.column = column
this.page_idx = page_idx
ColumnViewHolder.log.d("onPageCreate [%d] %s", page_idx, column.getColumnName(true))
ColumnViewHolder.log.d("onPageCreate [${page_idx}] ${column.getColumnName(true)}")
val bSimpleList =
column.type != ColumnType.CONVERSATION && Pref.bpSimpleList(activity.pref)

View File

@ -209,22 +209,17 @@ fun ColumnViewHolder.scrollToTop2() {
fun ColumnViewHolder.saveScrollPosition(): Boolean {
val column = this.column
when {
column == null -> ColumnViewHolder.log.d("saveScrollPosition [%d] , column==null", page_idx)
column == null ->
ColumnViewHolder.log.d("saveScrollPosition [${page_idx}] , column==null")
column.is_dispose.get() -> ColumnViewHolder.log.d(
"saveScrollPosition [%d] , column is disposed",
page_idx
)
column.is_dispose.get() ->
ColumnViewHolder.log.d("saveScrollPosition [${page_idx}] , column is disposed")
listView.visibility != View.VISIBLE -> {
val scroll_save = ScrollPosition()
column.scroll_save = scroll_save
ColumnViewHolder.log.d(
"saveScrollPosition [%d] %s , listView is not visible, save %s,%s",
page_idx,
column.getColumnName(true),
scroll_save.adapterIndex,
scroll_save.offset
"saveScrollPosition [${page_idx}] ${column.getColumnName(true)} , listView is not visible, save ${scroll_save.adapterIndex},${scroll_save.offset}"
)
return true
}
@ -233,11 +228,7 @@ fun ColumnViewHolder.saveScrollPosition(): Boolean {
val scroll_save = ScrollPosition(this)
column.scroll_save = scroll_save
ColumnViewHolder.log.d(
"saveScrollPosition [%d] %s , listView is visible, save %s,%s",
page_idx,
column.getColumnName(true),
scroll_save.adapterIndex,
scroll_save.offset
"saveScrollPosition [${page_idx}] ${column.getColumnName(true)} , listView is visible, save ${scroll_save.adapterIndex},${scroll_save.offset}"
)
return true
}
@ -262,7 +253,7 @@ fun ColumnViewHolder.setScrollPosition(sp: ScrollPosition, deltaDp: Float = 0f)
listLayoutManager.scrollVerticallyBy(dy, recycler, state)
} catch (ex: Throwable) {
ColumnViewHolder.log.trace(ex)
ColumnViewHolder.log.e("can't access field in class %s", RecyclerView::class.java.simpleName)
ColumnViewHolder.log.e("can't access field in class ${RecyclerView::class.java.simpleName}")
}
}, 20L)
}

View File

@ -26,7 +26,7 @@ class EventReceiver : BroadcastReceiver() {
ACTION_NOTIFICATION_DELETE ->
PollingWorker.queueNotificationDeleted( context,intent.data)
else -> log.e("onReceive: unsupported action %s", action)
else -> log.e("onReceive: unsupported action ${action}")
}
}
}

View File

@ -16,38 +16,38 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
internal val log = LogCategory("MyFirebaseMessagingService")
}
override fun onMessageReceived(remoteMessage : RemoteMessage) {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
var tag : String? = null
var tag: String? = null
val data = remoteMessage.data
for((key, value) in data) {
log.d("onMessageReceived: %s=%s", key, value)
when(key){
for ((key, value) in data) {
log.d("onMessageReceived: ${key}=${value}")
when (key) {
"notification_tag" -> tag = value
"acct" -> tag= "acct<>$value"
"acct" -> tag = "acct<>$value"
}
}
val context = applicationContext
val intent = Intent(context, PollingForegrounder::class.java)
if(tag != null) intent.putExtra(PollingWorker.EXTRA_TAG, tag)
if(Build.VERSION.SDK_INT >= 26) {
if (tag != null) intent.putExtra(PollingWorker.EXTRA_TAG, tag)
if (Build.VERSION.SDK_INT >= 26) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}
}
override fun onNewToken(token : String) {
override fun onNewToken(token: String) {
try {
log.d("onTokenRefresh: token=%s", token)
log.d("onTokenRefresh: token=${token}")
PrefDevice.prefDevice(this).edit().putString(PrefDevice.KEY_DEVICE_TOKEN, token).apply()
PollingWorker.queueFCMTokenUpdated(this)
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
}

View File

@ -5,19 +5,19 @@ import androidx.recyclerview.widget.RecyclerView
import jp.juggler.util.LogCategory
internal class TabletColumnViewHolder(
activity : ActMain,
activity: ActMain,
parent: ViewGroup,
val columnViewHolder : ColumnViewHolder = ColumnViewHolder(activity,parent)
val columnViewHolder: ColumnViewHolder = ColumnViewHolder(activity, parent)
) : RecyclerView.ViewHolder(columnViewHolder.viewRoot) {
companion object {
val log = LogCategory("TabletColumnViewHolder")
}
private var pageIndex = - 1
private var pageIndex = -1
fun bind(column : Column, pageIndex : Int, column_count : Int) {
log.d("bind. %d => %d ", this.pageIndex, pageIndex)
fun bind(column: Column, pageIndex: Int, column_count: Int) {
log.d("bind. ${this.pageIndex} => ${pageIndex}")
columnViewHolder.onPageDestroy(this.pageIndex)
@ -25,13 +25,13 @@ internal class TabletColumnViewHolder(
columnViewHolder.onPageCreate(column, pageIndex, column_count)
if(! column.bFirstInitialized) {
if (!column.bFirstInitialized) {
column.startLoading()
}
}
fun onViewRecycled() {
log.d("onViewRecycled %d", pageIndex)
log.d("onViewRecycled ${pageIndex}")
columnViewHolder.onPageDestroy(pageIndex)
}
}

View File

@ -63,7 +63,7 @@ class UpdateRelationEnv(val column: Column) {
UserRelation.saveListMisskey(now, column.access_info.db_id, who_list, start, step)
start += step
}
Column.log.d("updateRelation: update %d relations.", end)
Column.log.d("updateRelation: update ${end} relations.")
}
// 2018/11/1 Misskeyにもリレーション取得APIができた
@ -108,7 +108,7 @@ class UpdateRelationEnv(val column: Column) {
UserRelation.saveList2(now, column.access_info.db_id, list)
}
}
Column.log.d("updateRelation: update %d relations.", n)
Column.log.d("updateRelation: update ${n} relations.")
}
@ -139,7 +139,7 @@ class UpdateRelationEnv(val column: Column) {
list
)
}
Column.log.d("updateRelation: update %d relations.", n)
Column.log.d("updateRelation: update ${n} relations.")
}
}
@ -158,7 +158,7 @@ class UpdateRelationEnv(val column: Column) {
AcctSet.saveList(now, acct_list, n, length)
n += length
}
Column.log.d("updateRelation: update %d acct.", n)
Column.log.d("updateRelation: update ${n} acct.")
}
@ -177,7 +177,7 @@ class UpdateRelationEnv(val column: Column) {
TagSet.saveList(now, tag_list, n, length)
n += length
}
Column.log.d("updateRelation: update %d tag.", n)
Column.log.d("updateRelation: update ${n} tag.")
}
}
}

View File

@ -231,7 +231,7 @@ private fun appServerUnregister(context: Context, account: SavedAccount) {
val response = call.await()
log.e("appServerUnregister: %s", response)
log.e("appServerUnregister: ${response}")
} catch (ex: Throwable) {
log.trace(ex, "appServerUnregister failed.")
}

View File

@ -132,7 +132,7 @@ private fun ActMain.conversationRemote(
val (result, status) = client.syncStatus(access_info, remote_status_url)
if (status != null) {
local_status_id = status.id
log.d("status id conversion %s => %s", remote_status_url, status.id)
log.d("status id conversion ${remote_status_url}=>${status.id}")
}
result
}

View File

@ -8,34 +8,34 @@ import jp.juggler.util.asciiPattern
import jp.juggler.util.groupEx
import java.util.*
class TootList(parser:TootParser,src : JsonObject): TimelineItem(), Comparable<TootList> {
class TootList(parser: TootParser, src: JsonObject) : TimelineItem(), Comparable<TootList> {
val id : EntityId
val id: EntityId
val title : String?
val title: String?
// タイトルの数字列部分は数字の大小でソートされるようにしたい
private val title_for_sort : ArrayList<Any>?
private val title_for_sort: ArrayList<Any>?
// 内部で使用する
var isRegistered : Boolean = false
var isRegistered: Boolean = false
var userIds :ArrayList<EntityId>? = null
var userIds: ArrayList<EntityId>? = null
init {
if( parser.serviceType == ServiceType.MISSKEY){
id = EntityId.mayDefault(src.string("id") )
if (parser.serviceType == ServiceType.MISSKEY) {
id = EntityId.mayDefault(src.string("id"))
title = src.string("name") ?: src.string("title") // v11,v10
this.title_for_sort = makeTitleForSort(this.title)
val user_list = ArrayList<EntityId>()
userIds = user_list
src.jsonArray("userIds")?.forEach {
val id = EntityId.mayNull( it as? String )
if(id != null ) user_list.add(id )
val id = EntityId.mayNull(it as? String)
if (id != null) user_list.add(id)
}
}else {
id = EntityId.mayDefault(src.string("id") )
} else {
id = EntityId.mayDefault(src.string("id"))
title = src.string("title")
this.title_for_sort = makeTitleForSort(this.title)
}
@ -48,20 +48,20 @@ class TootList(parser:TootParser,src : JsonObject): TimelineItem(), Comparable<T
private val reNumber = """(\d+)""".asciiPattern()
private fun makeTitleForSort(title : String?) : ArrayList<Any> {
private fun makeTitleForSort(title: String?): ArrayList<Any> {
val list = ArrayList<Any>()
if(title != null) {
if (title != null) {
val m = reNumber.matcher(title)
var last_end = 0
while(m.find()) {
while (m.find()) {
val match_start = m.start()
val match_end = m.end()
if(match_start > last_end) {
if (match_start > last_end) {
list.add(title.substring(last_end, match_start))
}
try {
list.add(m.groupEx(1)!!.toLong())
} catch(ex : Throwable) {
} catch (ex: Throwable) {
list.clear()
list.add(title)
return list
@ -70,29 +70,29 @@ class TootList(parser:TootParser,src : JsonObject): TimelineItem(), Comparable<T
last_end = match_end
}
val end = title.length
if(end > last_end) {
if (end > last_end) {
list.add(title.substring(last_end, end))
}
}
return list
}
private fun compareLong(a : Long, b : Long) : Int {
private fun compareLong(a: Long, b: Long): Int {
return a.compareTo(b)
}
private fun compareString(a : String, b : String) : Int {
private fun compareString(a: String, b: String): Int {
return a.compareTo(b)
}
}
override fun compareTo(other : TootList) : Int {
override fun compareTo(other: TootList): Int {
val la = this.title_for_sort
val lb = other.title_for_sort
if(la == null) {
return if(lb == null) 0 else - 1
} else if(lb == null) {
if (la == null) {
return if (lb == null) 0 else -1
} else if (lb == null) {
return 1
}
@ -100,28 +100,31 @@ class TootList(parser:TootParser,src : JsonObject): TimelineItem(), Comparable<T
val sb = lb.size
var i = 0
while(true) {
val oa = if(i >= sa) null else la[i]
val ob = if(i >= sb) null else lb[i]
while (true) {
val oa = if (i >= sa) null else la[i]
val ob = if (i >= sb) null else lb[i]
if(oa == null && ob == null) return 0
if (oa == null && ob == null) return 0
val delta = when {
oa == null -> - 1
oa == null -> -1
ob == null -> 1
oa is Long && ob is Long -> compareLong(oa, ob)
oa is String && ob is String -> compareString(oa, ob)
else -> (ob is Long).b2i() - (oa is Long).b2i()
}
log.d(
"%s %s %s"
, oa
, if(delta < 0) "<" else if(delta > 0) ">" else "="
, ob
)
if(delta != 0) return delta
++ i
}
"${oa} ${
when {
delta < 0 -> "<"
delta > 0 -> ">"
else -> "="
}
} ${ob}"
)
if (delta != 0) return delta
++i
}
}
}

View File

@ -11,16 +11,16 @@ object TootPayload {
// ストリーミングAPIのペイロード部分をTootStatus,TootNotification,整数IDのどれかに解釈する
fun parsePayload(
parser : TootParser,
event : String,
parent : JsonObject,
parent_text : String
) : Any? {
parser: TootParser,
event: String,
parent: JsonObject,
parent_text: String
): Any? {
try {
val payload = parent["payload"] ?: return null
if(payload is JsonObject) {
return when(event) {
if (payload is JsonObject) {
return when (event) {
// ここを通るケースはまだ確認できていない
"update" -> parser.status(payload)
@ -30,25 +30,25 @@ object TootPayload {
// ここを通るケースはまだ確認できていない
else -> {
log.e("unknown payload(1). message=%s", parent_text)
log.e("unknown payload(1). message=${parent_text}")
null
}
}
} else if(payload is JsonArray) {
log.e("unknown payload(1b). message=%s", parent_text)
} else if (payload is JsonArray) {
log.e("unknown payload(1b). message=${parent_text}")
return null
}
if(payload is Number) {
if (payload is Number) {
// 2017/8/24 18:37 mastodon.juggler.jpでここを通った
return payload.toLong()
}
if(payload is String) {
if (payload is String) {
if(payload[0] == '{') {
if (payload[0] == '{') {
val src = payload.decodeJsonObject()
return when(event) {
return when (event) {
// 2017/8/24 18:37 mastodon.juggler.jpでここを通った
"update" -> parser.status(src)
@ -63,26 +63,26 @@ object TootPayload {
"announcement.reaction" -> parseItem(TootReaction::parseFedibird, src)
else -> {
log.e("unknown payload(2). message=%s", parent_text)
log.e("unknown payload(2). message=${parent_text}")
// ここを通るケースはまだ確認できていない
}
}
} else if(payload[0] == '[') {
log.e("unknown payload(2b). message=%s", parent_text)
} else if (payload[0] == '[') {
log.e("unknown payload(2b). message=${parent_text}")
return null
}
// 2017/8/24 18:37 mdx.ggtea.org でここを通った
val m = reNumber.matcher(payload)
if(m.find()) {
return m.groupEx(1) !!.toLong(10)
if (m.find()) {
return m.groupEx(1)!!.toLong(10)
}
}
// ここを通るケースはまだ確認できていない
log.e("unknown payload(3). message=%s", parent_text)
log.e("unknown payload(3). message=${parent_text}")
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}

View File

@ -951,24 +951,24 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
return list
}
fun updateReactionMastodon( newReactionSet: TootReactionSet ) {
fun updateReactionMastodon(newReactionSet: TootReactionSet) {
synchronized(this) {
this.reactionSet = newReactionSet
}
}
fun updateReactionMastodonByEvent( newReaction: TootReaction ) {
fun updateReactionMastodonByEvent(newReaction: TootReaction) {
synchronized(this) {
var reactionSet = this.reactionSet
if( newReaction.count <= 0 ){
reactionSet?.get(newReaction.name)?.let{ reactionSet?.remove(it) }
}else{
if (newReaction.count <= 0) {
reactionSet?.get(newReaction.name)?.let { reactionSet?.remove(it) }
} else {
if (reactionSet == null) {
reactionSet = TootReactionSet(isMisskey = false)
this.reactionSet = reactionSet
}
when(val old = reactionSet[newReaction.name]) {
when (val old = reactionSet[newReaction.name]) {
null -> reactionSet.add(newReaction)
// 同一オブジェクトならマージは不要
@ -1007,7 +1007,7 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
if (byMe) {
// 自分でリアクションしたらUIで更新した後にストリーミングイベントが届くことがある
// その場合はカウントを変更しない
if(reactionSet.any{ it.me && it.name == code}) return false
if (reactionSet.any { it.me && it.name == code }) return false
}
log.d("increaseReaction noteId=$id byMe=$byMe caller=$caller")
@ -1017,7 +1017,7 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
reactionSet[code]?.also { it.count = max(0, it.count + 1L) }
?: TootReaction(name = code, count = 1L).also { reactionSet.add(it) }
if(byMe) reaction.me = true
if (byMe) reaction.me = true
return true
}
@ -1037,7 +1037,7 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
if (byMe) {
// 自分でリアクションしたらUIで更新した後にストリーミングイベントが届くことがある
// その場合はカウントを変更しない
if(reactionSet.any{ !it.me && it.name == code}) return false
if (reactionSet.any { !it.me && it.name == code }) return false
}
log.d("decreaseReaction noteId=$id byMe=$byMe caller=$caller")
@ -1046,7 +1046,7 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
val reaction = reactionSet[code]
?.also { it.count = max(0L, it.count - 1L) }
if(byMe) reaction?.me = false
if (byMe) reaction?.me = false
return true
}
@ -1210,10 +1210,10 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
m = reDate.matcher(strTime)
if (m.find()) return parseTime("${strTime}T00:00:00.000Z")
log.w("invalid time format: %s", strTime)
log.w("invalid time format: ${strTime}")
} catch (ex: Throwable) { // ParseException, ArrayIndexOutOfBoundsException
log.trace(ex)
log.e(ex, "TootStatus.parseTime failed. src=%s", strTime)
log.e(ex, "TootStatus.parseTime failed. src=$strTime")
}
}
return 0L
@ -1224,7 +1224,7 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
try {
val m = reMSPTime.matcher(strTime)
if (!m.find()) {
log.d("invalid time format: %s", strTime)
log.d("invalid time format: $strTime")
} else {
val g = GregorianCalendar(tz_utc)
g.set(
@ -1240,7 +1240,7 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
}
} catch (ex: Throwable) { // ParseException, ArrayIndexOutOfBoundsException
log.trace(ex)
log.e(ex, "parseTimeMSP failed. src=%s", strTime)
log.e(ex, "parseTimeMSP failed. src=${strTime}" )
}
}

View File

@ -103,7 +103,7 @@ class PollingForegrounder : IntentService("PollingForegrounder") {
if (sv.isEmpty() || sv == last_status) return@handleFCMMessage
// 状況が変化したらログと通知領域に出力する
last_status = sv
log.d("onStatus %s", sv)
log.d("onStatus $sv")
startForeground(NOTIFICATION_ID_FOREGROUNDER, createNotification(context, sv))
}
}

View File

@ -357,10 +357,7 @@ class PollingWorker private constructor(contextArg: Context) {
// ジョブが完了した?
val now = SystemClock.elapsedRealtime()
if (!pw.hasJob(JobId.Push)) {
log.d(
"handleFCMMessage: JOB_FCM completed. time=%.2f",
(now - time_start) / 1000f
)
log.d("handleFCMMessage: JOB_FCM completed. time=${String.format("%.2f", (now - time_start) / 1000f)}")
break
}

View File

@ -77,7 +77,7 @@ object NotestockHelper {
parseList(parser, data)
.also {
if (it.isEmpty())
log.d("search result is empty. %s", result.bodyString)
log.d("search result is empty. ${result.bodyString}")
}
)

View File

@ -72,7 +72,7 @@ object TootsearchHelper {
parseList(parser, root)
.also {
if (it.isEmpty())
log.d("search result is empty. %s", result.bodyString)
log.d("search result is empty. ${result.bodyString}")
}
)
}

View File

@ -164,12 +164,7 @@ class AcctColor {
log.e(ex, "load failed.")
}
log.d(
"lruCache size=%s,hit=%s,miss=%s",
mMemoryCache.size(),
mMemoryCache.hitCount(),
mMemoryCache.missCount()
)
log.d("lruCache size=${mMemoryCache.size()},hit=${mMemoryCache.hitCount()},miss=${mMemoryCache.missCount()}")
val ac = AcctColor(key, acctPretty)
mMemoryCache.put(key, ac)
return ac

View File

@ -69,14 +69,7 @@ class NotificationTracking {
post_id.putTo(cv, COL_POST_ID)
cv.put(COL_POST_TIME, post_time)
val rows = App1.database.update(table, cv, WHERE_AID, arrayOf(account_db_id.toString(),notificationType))
log.d(
"updatePost account_db_id=%s, nt=%s, post=%s,%s update_rows=%s"
, account_db_id
, notificationType
, post_id
, post_time
, rows
)
log.d("updatePost account_db_id=${account_db_id}, nt=${notificationType}, post=${post_id},${post_time} update_rows=${rows}")
dirty=false
clearCache(account_db_id,notificationType)
} catch(ex : Throwable) {

View File

@ -12,16 +12,16 @@ import jp.juggler.util.decodeJsonObject
class PostDraft {
var id : Long = 0
var time_save : Long = 0
var json : JsonObject? = null
var hash : String? = null
var id: Long = 0
var time_save: Long = 0
var json: JsonObject? = null
var hash: String? = null
class ColIdx(cursor : Cursor) {
internal val idx_id : Int
internal val idx_time_save : Int
internal val idx_json : Int
internal val idx_hash : Int
class ColIdx(cursor: Cursor) {
internal val idx_id: Int
internal val idx_time_save: Int
internal val idx_json: Int
internal val idx_hash: Int
init {
idx_id = cursor.getColumnIndex(COL_ID)
@ -35,7 +35,7 @@ class PostDraft {
fun delete() {
try {
App1.database.delete(table, "$COL_ID=?", arrayOf(id.toString()))
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.e(ex, "delete failed.")
}
@ -51,7 +51,7 @@ class PostDraft {
private const val COL_JSON = "json"
private const val COL_HASH = "hash"
override fun onDBCreate(db : SQLiteDatabase) {
override fun onDBCreate(db: SQLiteDatabase) {
log.d("onDBCreate!")
db.execSQL(
"create table if not exists " + table
@ -69,24 +69,24 @@ class PostDraft {
)
}
override fun onDBUpgrade(db : SQLiteDatabase, oldVersion : Int, newVersion : Int) {
if(oldVersion < 12 && newVersion >= 12) {
override fun onDBUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
if (oldVersion < 12 && newVersion >= 12) {
onDBCreate(db)
}
}
private fun deleteOld(now : Long) {
private fun deleteOld(now: Long) {
try {
// 古いデータを掃除する
val expire = now - 86400000L * 30
App1.database.delete(table, "$COL_TIME_SAVE<?", arrayOf(expire.toString()))
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.e(ex, "deleteOld failed.")
}
}
fun save(now : Long, json : JsonObject) {
fun save(now: Long, json: JsonObject) {
deleteOld(now)
@ -108,22 +108,22 @@ class PostDraft {
put(COL_JSON, json.toString())
put(COL_HASH, hash)
})
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.e(ex, "save failed.")
}
}
fun hasDraft() : Boolean {
fun hasDraft(): Boolean {
try {
App1.database.query(table, arrayOf("count(*)"), null, null, null, null, null)
.use { cursor ->
if(cursor.moveToNext()) {
if (cursor.moveToNext()) {
val count = cursor.getInt(0)
return count > 0
}
}
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
log.e(ex, "hasDraft failed.")
}
@ -131,7 +131,7 @@ class PostDraft {
return false
}
fun createCursor() : Cursor? {
fun createCursor(): Cursor? {
try {
return App1.database.query(
table,
@ -142,7 +142,7 @@ class PostDraft {
null,
"$COL_TIME_SAVE desc"
)
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
log.e(ex, "createCursor failed.")
}
@ -150,11 +150,11 @@ class PostDraft {
return null
}
fun loadFromCursor(cursor : Cursor, colIdxArg : ColIdx?, position : Int) : PostDraft? {
fun loadFromCursor(cursor: Cursor, colIdxArg: ColIdx?, position: Int): PostDraft? {
val colIdx = colIdxArg ?: ColIdx(cursor)
if(! cursor.moveToPosition(position)) {
log.d("loadFromCursor: move failed. position=%s", position)
if (!cursor.moveToPosition(position)) {
log.d("loadFromCursor: move failed. position=${position}")
return null
}
@ -163,7 +163,7 @@ class PostDraft {
dst.time_save = cursor.getLong(colIdx.idx_time_save)
try {
dst.json = cursor.getString(colIdx.idx_json).decodeJsonObject()
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
dst.json = JsonObject()
}

View File

@ -353,13 +353,7 @@ class CustomEmojiCache(
if (cache_used) continue
if (DEBUG)
log.d(
"start get image. queue_size=%d, cache_size=%d url=%s",
queue_size,
cache_size,
request.url
)
if (DEBUG) log.d("start get image. queue_size=${queue_size}, cache_size=${cache_size} url=${request.url}")
val now = System.currentTimeMillis()
@ -377,8 +371,7 @@ class CustomEmojiCache(
data = try {
App1.getHttpCached(request.url)
} catch (ex: Throwable) {
log.e("get failed. url=%s", request.url)
log.trace(ex)
log.trace(ex, "get failed. url=${request.url}")
null
}
te = elapsedTime
@ -473,7 +466,7 @@ class CustomEmojiCache(
// fall thru
} catch (ex: Throwable) {
if (DEBUG) log.trace(ex)
log.e(ex, "PNG decode failed. %s ", url)
log.e(ex, "PNG decode failed. $url ")
}
// 通常のビットマップでのロードを試みる
@ -483,12 +476,12 @@ class CustomEmojiCache(
if (DEBUG) log.d("bitmap decoded.")
return ApngFrames(b)
} else {
log.e("Bitmap decode returns null. %s", url)
log.e("Bitmap decode returns null. $url")
}
// fall thru
} catch (ex: Throwable) {
log.e(ex, "Bitmap decode failed. %s", url)
log.e(ex, "Bitmap decode failed. $url")
}
// SVGのロードを試みる
@ -501,7 +494,7 @@ class CustomEmojiCache(
// fall thru
} catch (ex: Throwable) {
log.e(ex, "SVG decode failed. %s", url)
log.e(ex, "SVG decode failed. $url")
}
return null

View File

@ -13,8 +13,8 @@ import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
class CustomEmojiLister(
val context : Context,
private val handler : Handler
val context: Context,
private val handler: Handler
) {
companion object {
@ -25,24 +25,24 @@ class CustomEmojiLister(
internal const val ERROR_EXPIRE = 60000L * 5
private val elapsedTime : Long
private val elapsedTime: Long
get() = SystemClock.elapsedRealtime()
}
internal class CacheItem(
val key : String,
var list : ArrayList<CustomEmoji>? = null,
var listWithAliases : ArrayList<CustomEmoji>? = null,
val key: String,
var list: ArrayList<CustomEmoji>? = null,
var listWithAliases: ArrayList<CustomEmoji>? = null,
// ロードした時刻
var time_update : Long = elapsedTime,
var time_update: Long = elapsedTime,
// 参照された時刻
var time_used : Long = time_update
var time_used: Long = time_update
)
internal class Request(
val accessInfo : SavedAccount,
val reportWithAliases : Boolean = false,
val onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit?
val accessInfo: SavedAccount,
val reportWithAliases: Boolean = false,
val onListLoaded: (list: ArrayList<CustomEmoji>) -> Unit?
)
// 成功キャッシュ
@ -56,7 +56,7 @@ class CustomEmojiLister(
// ロード要求
internal val queue = ConcurrentLinkedQueue<Request>()
private val worker : Worker
private val worker: Worker
init {
this.worker = Worker()
@ -67,19 +67,19 @@ class CustomEmojiLister(
cache_error.clear()
}
private fun getCached(now : Long, accessInfo : SavedAccount) : CacheItem? {
private fun getCached(now: Long, accessInfo: SavedAccount): CacheItem? {
val host = accessInfo.apiHost.ascii
// 成功キャッシュ
val item = cache[host]
if(item != null && now - item.time_update <= ERROR_EXPIRE) {
if (item != null && now - item.time_update <= ERROR_EXPIRE) {
item.time_used = now
return item
}
// エラーキャッシュ
val time_error = cache_error[host]
if(time_error != null && now < time_error + ERROR_EXPIRE) {
if (time_error != null && now < time_error + ERROR_EXPIRE) {
return cache_error_item
}
@ -87,31 +87,31 @@ class CustomEmojiLister(
}
fun getList(
accessInfo : SavedAccount,
onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit
) : ArrayList<CustomEmoji>? {
accessInfo: SavedAccount,
onListLoaded: (list: ArrayList<CustomEmoji>) -> Unit
): ArrayList<CustomEmoji>? {
try {
synchronized(cache) {
val item = getCached(elapsedTime, accessInfo)
if(item != null) return item.list
if (item != null) return item.list
}
queue.add(Request(accessInfo, onListLoaded = onListLoaded))
worker.notifyEx()
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
return null
}
fun getListWithAliases(
accessInfo : SavedAccount,
onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit
) : ArrayList<CustomEmoji>? {
accessInfo: SavedAccount,
onListLoaded: (list: ArrayList<CustomEmoji>) -> Unit
): ArrayList<CustomEmoji>? {
try {
synchronized(cache) {
val item = getCached(elapsedTime, accessInfo)
if(item != null) return item.listWithAliases
if (item != null) return item.listWithAliases
}
queue.add(
@ -122,19 +122,19 @@ class CustomEmojiLister(
)
)
worker.notifyEx()
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
return null
}
fun getMap(accessInfo : SavedAccount) : HashMap<String, CustomEmoji>? {
fun getMap(accessInfo: SavedAccount): HashMap<String, CustomEmoji>? {
val list = getList(accessInfo) {
// 遅延ロード非対応
} ?: return null
//
val dst = HashMap<String, CustomEmoji>()
for(e in list) {
for (e in list) {
dst[e.shortcode] = e
}
return dst
@ -147,11 +147,11 @@ class CustomEmojiLister(
}
override suspend fun run() {
while(true) {
while (true) {
try {
// リクエストを取得する
val request = queue.poll()
if(request == null) {
if (request == null) {
// なければ待機
waitEx(86400000L)
continue
@ -160,10 +160,10 @@ class CustomEmojiLister(
val cached = synchronized(cache) {
val item = getCached(elapsedTime, request.accessInfo)
return@synchronized if(item != null) {
return@synchronized if (item != null) {
val list = item.list
val listWithAliases = item.listWithAliases
if(list != null && listWithAliases != null) {
if (list != null && listWithAliases != null) {
fireCallback(request, list, listWithAliases)
}
true
@ -173,14 +173,14 @@ class CustomEmojiLister(
false
}
}
if(cached) continue
if (cached) continue
val accessInfo = request.accessInfo
val cacheKey = accessInfo.apiHost.ascii
var list : ArrayList<CustomEmoji>? = null
var listWithAlias : ArrayList<CustomEmoji>? = null
var list: ArrayList<CustomEmoji>? = null
var listWithAlias: ArrayList<CustomEmoji>? = null
try {
val data = if(accessInfo.isMisskey) {
val data = if (accessInfo.isMisskey) {
App1.getHttpCachedString(
"https://${cacheKey}/api/meta",
accessInfo = accessInfo
@ -194,23 +194,23 @@ class CustomEmojiLister(
)
}
if(data != null) {
if (data != null) {
val a = decodeEmojiList(data, accessInfo)
list = a
listWithAlias = makeListWithAlias(a)
}
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
synchronized(cache) {
val now = elapsedTime
if(list == null || listWithAlias == null) {
if (list == null || listWithAlias == null) {
cache_error.put(cacheKey, now)
} else {
var item : CacheItem? = cache[cacheKey]
if(item == null) {
var item: CacheItem? = cache[cacheKey]
if (item == null) {
item = CacheItem(cacheKey, list, listWithAlias)
cache[cacheKey] = item
} else {
@ -221,7 +221,7 @@ class CustomEmojiLister(
fireCallback(request, list, listWithAlias)
}
}
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
waitEx(3000L)
}
@ -229,13 +229,13 @@ class CustomEmojiLister(
}
private fun fireCallback(
request : Request,
list : ArrayList<CustomEmoji>,
listWithAliases : ArrayList<CustomEmoji>
request: Request,
list: ArrayList<CustomEmoji>,
listWithAliases: ArrayList<CustomEmoji>
) {
handler.post {
request.onListLoaded(
if(request.reportWithAliases) {
if (request.reportWithAliases) {
listWithAliases
} else {
list
@ -248,13 +248,13 @@ class CustomEmojiLister(
private fun sweep_cache() {
// 超過してる数
val over = cache.size - CACHE_MAX
if(over <= 0) return
if (over <= 0) return
// 古い要素を一時リストに集める
val now = elapsedTime
val list = ArrayList<CacheItem>(over)
for(item in cache.values) {
if(now - item.time_used > 1000L) list.add(item)
for (item in cache.values) {
if (now - item.time_used > 1000L) list.add(item)
}
// 昇順ソート
@ -262,18 +262,18 @@ class CustomEmojiLister(
// 古い物から順に捨てる
var removed = 0
for(item in list) {
for (item in list) {
cache.remove(item.key)
if(++ removed >= over) break
if (++removed >= over) break
}
}
private fun decodeEmojiList(
data : String,
accessInfo : SavedAccount
) : ArrayList<CustomEmoji>? {
data: String,
accessInfo: SavedAccount
): ArrayList<CustomEmoji>? {
return try {
val list = if(accessInfo.isMisskey) {
val list = if (accessInfo.isMisskey) {
parseList(
CustomEmoji.decodeMisskey,
accessInfo.apDomain,
@ -288,20 +288,20 @@ class CustomEmojiLister(
}
list.sortWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.shortcode })
list
} catch(ex : Throwable) {
log.e(ex, "decodeEmojiList failed. instance=%s", accessInfo.apiHost.ascii)
} catch (ex: Throwable) {
log.e(ex, "decodeEmojiList failed. instance=${accessInfo.apiHost.ascii}")
null
}
}
private fun makeListWithAlias(list : ArrayList<CustomEmoji>?) : ArrayList<CustomEmoji> {
private fun makeListWithAlias(list: ArrayList<CustomEmoji>?): ArrayList<CustomEmoji> {
val dst = ArrayList<CustomEmoji>()
if(list != null) {
if (list != null) {
dst.addAll(list)
for(item in list) {
for (item in list) {
val aliases = item.aliases ?: continue
for(alias in aliases) {
if(alias.equals(item.shortcode, ignoreCase = true)) continue
for (alias in aliases) {
if (alias.equals(item.shortcode, ignoreCase = true)) continue
dst.add(item.makeAlias(alias))
}
}

View File

@ -178,7 +178,8 @@ class SpanList {
src.list.forEach { addLast(it.start + offset, it.end + offset, it.span) }
}
fun addFirst(start: Int, end: Int, span: Any) = when {
fun addFirst(start: Int, end: Int, span: Any) {
when {
start == end -> {
// empty span allowed
}
@ -191,8 +192,10 @@ class SpanList {
list.addFirst(SpanPos(start, end, span))
}
}
}
fun addLast(start: Int, end: Int, span: Any) = when {
fun addLast(start: Int, end: Int, span: Any) {
when {
start == end -> {
// empty span allowed
}
@ -205,6 +208,7 @@ class SpanList {
list.addLast(SpanPos(start, end, span))
}
}
}
fun insert(offset: Int, length: Int) {
for (sp in list) {
@ -778,7 +782,7 @@ object MisskeyMarkdownDecoder {
spanList.addFirst(
start,
sb.length,
SvgEmojiSpan(context, "emj_1f5bc.svg",scale=1f),
SvgEmojiSpan(context, "emj_1f5bc.svg", scale = 1f),
)
}
@ -1490,6 +1494,7 @@ object MisskeyMarkdownDecoder {
return null
}
@Suppress("SpellCheckingInspection")
private val latexEscape = listOf(
"\\#" to "#",
"\\$" to "$",
@ -1508,20 +1513,20 @@ object MisskeyMarkdownDecoder {
"\\textbar" to "|",
"\\textless" to "<",
"\\textgreater" to ">",
).sortedByDescending{ it.first.length}
).sortedByDescending { it.first.length }
private fun partialEquals(src:String,start:Int,needle:String):Boolean{
for( i in needle.indices){
if( src[start+i] != needle[i]) return false
private fun partialEquals(src: String, start: Int, needle: String): Boolean {
for (i in needle.indices) {
if (src[start + i] != needle[i]) return false
}
return true
}
private fun String.unescapeLatex():String{
private fun String.unescapeLatex(): String {
val sb = StringBuilder(length)
val end = length
var i = 0
while(i<end) {
while (i < end) {
val c = this[i]
if (c == '\\') {
val pair = latexEscape.find { partialEquals(this, i, it.first) }
@ -1539,17 +1544,21 @@ object MisskeyMarkdownDecoder {
// \} \]はムダなエスケープに見えるが、androidでは必要なので削ってはいけない
@Suppress("RegExpRedundantEscape")
private val reLatexRemove = """\\(?:quad|Huge|atop|sf|scriptsize|bf|small|tiny|underline|large|(?:color)\{[^}]*\})""".toRegex()
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()
private val reLatex1 =
"""\\(?:(?:url)|(?:textcolor|colorbox)\{[^}]*\}|(?:fcolorbox|raisebox)\{[^}]*\}\{[^}]*\}|includegraphics\[[^]]*\])\{([^}]*)\}""".toRegex()
@Suppress("RegExpRedundantEscape")
private val reLatex2reversed = """\\(?:overset|href)\{([^}]+)\}\{([^}]+)\}""".toRegex()
private fun String.removeLatex(): String {
return this
.replace(reLatexRemove,"")
.replace(reLatex1,"$1")
.replace(reLatex2reversed,"$2 $1")
.replace(reLatexRemove, "")
.replace(reLatex1, "$1")
.replace(reLatex2reversed, "$2 $1")
.unescapeLatex()
}
@ -1943,8 +1952,10 @@ object MisskeyMarkdownDecoder {
if (src != null) {
val root = Node(NodeType.ROOT, emptyArray(), null)
NodeParseEnv(useFunction = (options.linkHelper?.misskeyVersion
?: 12) >= 11, root, src, 0, src.length).parseInside()
NodeParseEnv(
useFunction = (options.linkHelper?.misskeyVersion
?: 12) >= 11, root, src, 0, src.length
).parseInside()
env.fireRender(root).setSpan(env.sb)
}

View File

@ -350,7 +350,7 @@ class PostHelper(
if (visibility == checkVisibility && !checkFun(instance)) {
val strVisibility = Styler.getVisibilityString(activity, account.isMisskey, checkVisibility)
return@runApiTask TootApiResult(
getString(R.string.server_has_no_support_of_visibility,strVisibility)
getString(R.string.server_has_no_support_of_visibility, strVisibility)
)
}
}
@ -783,7 +783,7 @@ class PostHelper(
val limit = 100
val s = src.substring(start, end)
val acct_list = AcctSet.searchPrefix(s, limit)
log.d("search for %s, result=%d", s, acct_list.size)
log.d("search for ${s}, result=${acct_list.size}")
if (acct_list.isEmpty()) {
closeAcctPopup()
} else {
@ -811,7 +811,7 @@ class PostHelper(
val limit = 100
val s = src.substring(last_sharp + 1, end)
val tag_list = TagSet.searchPrefix(s, limit)
log.d("search for %s, result=%d", s, tag_list.size)
log.d("search for ${s}, result=${tag_list.size}")
if (tag_list.isEmpty()) {
closeAcctPopup()
} else {
@ -863,7 +863,7 @@ class PostHelper(
val s =
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)
log.d("checkEmoji: search for ${s}, result=${matches.size}")
code_list.addAll(matches)
}

View File

@ -15,11 +15,11 @@ class TaskList {
private const val FILE_TASK_LIST = "JOB_TASK_LIST"
}
private lateinit var _list : LinkedList<JsonObject>
private lateinit var _list: LinkedList<JsonObject>
@Synchronized
private fun prepareList(context : Context) : LinkedList<JsonObject> {
if(! ::_list.isInitialized) {
private fun prepareList(context: Context): LinkedList<JsonObject> {
if (!::_list.isInitialized) {
_list = LinkedList()
try {
@ -30,9 +30,9 @@ class TaskList {
_list.add(it)
}
}
} catch(ex : FileNotFoundException) {
} catch (ex: FileNotFoundException) {
log.e(ex, "prepareList: file not found.")
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex, "TaskList: prepareArray failed.")
}
}
@ -41,28 +41,27 @@ class TaskList {
}
@Synchronized
private fun saveArray(context : Context) {
private fun saveArray(context: Context) {
val list = prepareList(context)
try {
log.d("saveArray size=%s", list.size)
log.d("saveArray size=${list.size}")
val data = JsonArray(list).toString().encodeUTF8()
context.openFileOutput(FILE_TASK_LIST, Context.MODE_PRIVATE)
.use { IOUtils.write(data, it) }
} catch(ex : Throwable) {
log.trace(ex)
log.e(ex, "TaskList: saveArray failed.size=%s", list.size)
} catch (ex: Throwable) {
log.trace(ex, "TaskList: saveArray failed.size=${list.size}")
}
}
@Synchronized
fun addLast(context : Context, removeOld : Boolean, taskData : JsonObject) {
fun addLast(context: Context, removeOld: Boolean, taskData: JsonObject) {
val list = prepareList(context)
if(removeOld) {
if (removeOld) {
val it = list.iterator()
while(it.hasNext()) {
while (it.hasNext()) {
val item = it.next()
if(taskData == item) it.remove()
if (taskData == item) it.remove()
}
}
list.addLast(taskData)
@ -71,14 +70,14 @@ class TaskList {
@Suppress("unused")
@Synchronized
fun hasNext(context : Context) : Boolean {
fun hasNext(context: Context): Boolean {
return prepareList(context).isNotEmpty()
}
@Synchronized
fun next(context : Context) : JsonObject? {
fun next(context: Context): JsonObject? {
val list = prepareList(context)
val item = if(list.isEmpty()) null else list.removeFirst()
val item = if (list.isEmpty()) null else list.removeFirst()
saveArray(context)
return item
}

View File

@ -16,24 +16,24 @@ class MyListView : ListView {
private val log = LogCategory("MyListView")
}
constructor(context : Context) : super(context)
constructor(context : Context, attrs : AttributeSet) : super(context, attrs)
constructor(context : Context, attrs : AttributeSet, defStyleAttr : Int) : super(context, attrs, defStyleAttr)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev : MotionEvent) : Boolean {
override fun onTouchEvent(ev: MotionEvent): Boolean {
// ポップアップを閉じた時にクリックでリストを触ったことになってしまう不具合の回避
val now = SystemClock.elapsedRealtime()
if(now - StatusButtonsPopup.last_popup_close < 30L) {
if (now - StatusButtonsPopup.last_popup_close < 30L) {
val action = ev.action
if(action == MotionEvent.ACTION_DOWN) {
if (action == MotionEvent.ACTION_DOWN) {
// ポップアップを閉じた直後はタッチダウンを無視する
return false
}
val rv = super.onTouchEvent(ev)
log.d("onTouchEvent action=%s, rv=%s", action, rv)
log.d("onTouchEvent action=${action}, rv=${rv}")
return rv
}
@ -43,7 +43,7 @@ class MyListView : ListView {
override fun layoutChildren() {
try {
super.layoutChildren()
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}

View File

@ -35,59 +35,59 @@ class MyNetworkImageView : AppCompatImageView {
}
// ロード中などに表示するDrawableのリソースID
private var mDefaultImage : Drawable? = null
private var mDefaultImage: Drawable? = null
// エラー時に表示するDrawableのリソースID
private var mErrorImage : Drawable? = null
private var mErrorImage: Drawable? = null
// 角丸の半径。元画像の短辺に対する割合を指定するらしい
internal var mCornerRadius = 0f
// 表示したい画像のURL
private var mUrl : String? = null
private var mMayGif : Boolean = false
private var mUrl: String? = null
private var mMayGif: Boolean = false
// 非同期処理のキャンセル
private var mTarget : Target<*>? = null
private var mTarget: Target<*>? = null
private val proc_load_image : Runnable = Runnable { loadImageIfNecessary() }
private val proc_focus_point : Runnable = Runnable { updateFocusPoint() }
private val proc_load_image: Runnable = Runnable { loadImageIfNecessary() }
private val proc_focus_point: Runnable = Runnable { updateFocusPoint() }
private var media_type_drawable : Drawable? = null
private var media_type_drawable: Drawable? = null
private var media_type_bottom = 0
private var media_type_left = 0
constructor(context : Context)
constructor(context: Context)
: super(context)
constructor(context : Context, attrs : AttributeSet)
constructor(context: Context, attrs: AttributeSet)
: super(context, attrs)
constructor(context : Context, attrs : AttributeSet, defStyleAttr : Int)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int)
: super(context, attrs, defStyleAttr)
fun setDefaultImage(defaultImage : Drawable?) {
fun setDefaultImage(defaultImage: Drawable?) {
mDefaultImage = defaultImage
loadImageIfNecessary()
}
fun setErrorImage(errorImage : Drawable?) {
fun setErrorImage(errorImage: Drawable?) {
mErrorImage = errorImage
loadImageIfNecessary()
}
fun setImageUrl(
pref : SharedPreferences,
r : Float,
url : String?,
gifUrlArg : String? = null
pref: SharedPreferences,
r: Float,
url: String?,
gifUrlArg: String? = null
) {
mCornerRadius = r
val gif_url = if(Pref.bpEnableGifAnimation(pref)) gifUrlArg else null
val gif_url = if (Pref.bpEnableGifAnimation(pref)) gifUrlArg else null
if(gif_url?.isNotEmpty() == true) {
if (gif_url?.isNotEmpty() == true) {
mUrl = gif_url
mMayGif = true
} else {
@ -97,26 +97,26 @@ class MyNetworkImageView : AppCompatImageView {
loadImageIfNecessary()
}
private fun getGlide() : RequestManager? {
private fun getGlide(): RequestManager? {
try {
return Glide.with(context)
} catch(ex : IllegalArgumentException) {
if(ex.message?.contains("destroyed activity") == true) {
} catch (ex: IllegalArgumentException) {
if (ex.message?.contains("destroyed activity") == true) {
// ignore it
} else {
log.e(ex, "Glide.with() failed.")
}
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.e(ex, "Glide.with() failed.")
}
return null
}
fun cancelLoading(defaultDrawable : Drawable? = null) {
fun cancelLoading(defaultDrawable: Drawable? = null) {
val d = drawable
if(d is Animatable) {
if(d.isRunning) {
if (d is Animatable) {
if (d.isRunning) {
//warning.d("cancelLoading: Animatable.stop()")
d.stop()
}
@ -125,10 +125,10 @@ class MyNetworkImageView : AppCompatImageView {
setImageDrawable(defaultDrawable)
val target = mTarget
if(target != null) {
if (target != null) {
try {
getGlide()?.clear(target)
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.e(ex, "Glide.clear() failed.")
}
@ -141,7 +141,7 @@ class MyNetworkImageView : AppCompatImageView {
private fun loadImageIfNecessary() {
try {
val url = mUrl
if(url?.isEmpty() != false) {
if (url?.isEmpty() != false) {
// if the URL to be loaded in this view is empty,
// cancel any old requests and clear the currently loaded image.
cancelLoading(mDefaultImage)
@ -149,27 +149,27 @@ class MyNetworkImageView : AppCompatImageView {
}
// すでにリクエストが発行済みで、リクエストされたURLが同じなら何もしない
if((mTarget as? UrlTarget)?.urlLoading == url) return
if ((mTarget as? UrlTarget)?.urlLoading == url) return
// if there is a pre-existing request, cancel it if it's fetching a different URL.
cancelLoading(mDefaultImage)
// 非表示状態ならロードを延期する
if(! isShown) return
if (!isShown) return
var wrapWidth = false
var wrapHeight = false
val lp = layoutParams
if(lp != null) {
if (lp != null) {
wrapWidth = lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
wrapHeight = lp.height == ViewGroup.LayoutParams.WRAP_CONTENT
}
// Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
val desiredWidth = if(wrapWidth) Target.SIZE_ORIGINAL else width
val desiredHeight = if(wrapHeight) Target.SIZE_ORIGINAL else height
val desiredWidth = if (wrapWidth) Target.SIZE_ORIGINAL else width
val desiredHeight = if (wrapHeight) Target.SIZE_ORIGINAL else height
if(desiredWidth != Target.SIZE_ORIGINAL && desiredWidth <= 0
if (desiredWidth != Target.SIZE_ORIGINAL && desiredWidth <= 0
|| desiredHeight != Target.SIZE_ORIGINAL && desiredHeight <= 0
) {
// desiredWidth,desiredHeight の指定がおかしいと非同期処理中にSimpleTargetが落ちる
@ -183,7 +183,7 @@ class MyNetworkImageView : AppCompatImageView {
val glideUrl = GlideUrl(url, glideHeaders)
mTarget = if(mMayGif) {
mTarget = if (mMayGif) {
getGlide()
?.load(glideUrl)
?.into(MyTargetGif(url))
@ -192,78 +192,78 @@ class MyNetworkImageView : AppCompatImageView {
?.load(glideUrl)
?.into(MyTarget(url))
}
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
}
private fun replaceGifDrawable(resource : GifDrawable) : Drawable {
private fun replaceGifDrawable(resource: GifDrawable): Drawable {
// ディスクキャッシュから読んだ画像は角丸が正しく扱われない
// MyGifDrawable に差し替えて描画させる
try {
return MyGifDrawable(resource, mCornerRadius)
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
return resource
}
private fun replaceBitmapDrawable(resource : BitmapDrawable) : Drawable {
private fun replaceBitmapDrawable(resource: BitmapDrawable): Drawable {
try {
val bitmap = resource.bitmap
if(bitmap != null) return replaceBitmapDrawable(bitmap)
} catch(ex : Throwable) {
if (bitmap != null) return replaceBitmapDrawable(bitmap)
} catch (ex: Throwable) {
log.trace(ex)
}
return resource
}
private fun replaceBitmapDrawable(bitmap : Bitmap) : Drawable {
private fun replaceBitmapDrawable(bitmap: Bitmap): Drawable {
val d = RoundedBitmapDrawableFactory.create(resources, bitmap)
d.cornerRadius = mCornerRadius
return d
}
private fun onLoadFailed(urlLoading : String) {
private fun onLoadFailed(urlLoading: String) {
try {
// 別の画像を表示するよう指定が変化していたなら何もしない
if(urlLoading != mUrl) return
if (urlLoading != mUrl) return
// エラー表示用の画像リソースが指定されていたら使う
when(val drawable = mErrorImage) {
when (val drawable = mErrorImage) {
null -> {
// このタイミングでImageViewのDrawableを変更するとチラつきの元になるので何もしない
}
else -> setImageDrawable(drawable)
}
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
}
private interface UrlTarget {
val urlLoading : String
val urlLoading: String
}
// 静止画用のターゲット
private inner class MyTarget(
override val urlLoading : String
override val urlLoading: String
) : ImageViewTarget<Drawable>(this@MyNetworkImageView), UrlTarget {
// errorDrawable The error drawable to optionally show, or null.
override fun onLoadFailed(errorDrawable : Drawable?) {
override fun onLoadFailed(errorDrawable: Drawable?) {
onLoadFailed(urlLoading)
}
override fun setResource(resource : Drawable?) {
override fun setResource(resource: Drawable?) {
try {
// 別の画像を表示するよう指定が変化していたなら何もしない
if(urlLoading != mUrl) return
if (urlLoading != mUrl) return
if(mCornerRadius > 0f) {
if(resource is BitmapDrawable) {
if (mCornerRadius > 0f) {
if (resource is BitmapDrawable) {
// BitmapDrawableは角丸処理が可能。
setImageDrawable(replaceBitmapDrawable(resource.bitmap))
return
@ -276,7 +276,7 @@ class MyNetworkImageView : AppCompatImageView {
setImageDrawable(resource)
return
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
}
@ -284,20 +284,20 @@ class MyNetworkImageView : AppCompatImageView {
}
private inner class MyTargetGif(
override val urlLoading : String
override val urlLoading: String
) : ImageViewTarget<Drawable>(this@MyNetworkImageView), UrlTarget {
private var glide_drawable : Drawable? = null
private var glide_drawable: Drawable? = null
override fun onLoadFailed(errorDrawable : Drawable?) = onLoadFailed(urlLoading)
override fun onLoadFailed(errorDrawable: Drawable?) = onLoadFailed(urlLoading)
override fun onResourceReady(
drawable : Drawable,
transition : Transition<in Drawable>?
drawable: Drawable,
transition: Transition<in Drawable>?
) {
try {
// 別の画像を表示するよう指定が変化していたなら何もしない
if(urlLoading != mUrl) return
if (urlLoading != mUrl) return
afterResourceReady(
transition,
@ -314,17 +314,17 @@ class MyNetworkImageView : AppCompatImageView {
drawable is BitmapDrawable -> replaceBitmapDrawable(drawable)
else -> {
log.d("onResourceReady: drawable class=%s", drawable.javaClass)
log.d("onResourceReady: drawable class=${drawable.javaClass.simpleName}")
drawable
}
}
)
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
}
private fun afterResourceReady(transition : Transition<in Drawable>?, drawable : Drawable) {
private fun afterResourceReady(transition: Transition<in Drawable>?, drawable: Drawable) {
super.onResourceReady(drawable, transition)
// if( ! drawable.isAnimated() ){
@ -333,7 +333,7 @@ class MyNetworkImageView : AppCompatImageView {
// // by forcing both the smaller thumb and the larger version to have exactly the same intrinsic dimensions.
// // If a drawable is replaced in an ImageView by another drawable with different intrinsic dimensions,
// // the ImageView requests a layout. Scrolling rapidly while replacing thumbs with larger images triggers
// // lots of these calls and causes significant amounts of jank.
// // lots of these calls and causes significant amounts of junk.
// float viewRatio = view.getWidth() / (float) view.getHeight();
// float drawableRatio = drawable.getIntrinsicWidth() / (float) drawable.getIntrinsicHeight();
// if( Math.abs( viewRatio - 1f ) <= SQUARE_RATIO_MARGIN
@ -343,50 +343,50 @@ class MyNetworkImageView : AppCompatImageView {
// }
this.glide_drawable = drawable
if(drawable is GifDrawable) {
if (drawable is GifDrawable) {
drawable.setLoopCount(GifDrawable.LOOP_FOREVER)
drawable.start()
} else if(drawable is MyGifDrawable) {
} else if (drawable is MyGifDrawable) {
drawable.setLoopCount(GifDrawable.LOOP_FOREVER)
drawable.start()
}
}
// super.onResourceReady から呼ばれる
override fun setResource(drawable : Drawable?) {
override fun setResource(drawable: Drawable?) {
setImageDrawable(drawable)
}
override fun onStart() {
val drawable = glide_drawable
if(drawable is Animatable && ! drawable.isRunning) {
log.d("MyTargetGif onStart glide_drawable=%s", drawable)
if (drawable is Animatable && !drawable.isRunning) {
log.d("MyTargetGif onStart glide_drawable=${drawable}")
drawable.start()
}
}
override fun onStop() {
val drawable = glide_drawable
if(drawable is Animatable && drawable.isRunning) {
log.d("MyTargetGif onStop glide_drawable=%s", drawable)
if (drawable is Animatable && drawable.isRunning) {
log.d("MyTargetGif onStop glide_drawable=${drawable}")
drawable.stop()
}
}
override fun onDestroy() {
val drawable = glide_drawable
log.d("MyTargetGif onDestroy glide_drawable=%s", drawable)
log.d("MyTargetGif onDestroy glide_drawable=${drawable}")
super.onDestroy()
}
}
override fun onSizeChanged(w : Int, h : Int, oldw : Int, oldh : Int) {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
post(proc_load_image)
post(proc_focus_point)
}
override fun onLayout(changed : Boolean, left : Int, top : Int, right : Int, bottom : Int) {
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
post(proc_load_image)
}
@ -406,13 +406,13 @@ class MyNetworkImageView : AppCompatImageView {
invalidate()
}
override fun onVisibilityChanged(changedView : View, visibility : Int) {
override fun onVisibilityChanged(changedView: View, visibility: Int) {
super.onVisibilityChanged(changedView, visibility)
loadImageIfNecessary()
}
fun setMediaType(drawable_id : Int) {
if(drawable_id == 0) {
fun setMediaType(drawable_id: Int) {
if (drawable_id == 0) {
media_type_drawable = null
} else {
media_type_drawable = ContextCompat.getDrawable(context, drawable_id)?.mutate()
@ -423,18 +423,18 @@ class MyNetworkImageView : AppCompatImageView {
invalidate()
}
override fun onDraw(canvas : Canvas) {
override fun onDraw(canvas: Canvas) {
// bitmapがrecycledされた場合に例外をキャッチする
try {
super.onDraw(canvas)
} catch(ex : Throwable) {
} catch (ex: Throwable) {
log.trace(ex)
}
// media type の描画
val media_type_drawable = this.media_type_drawable
if(media_type_drawable != null) {
if (media_type_drawable != null) {
val drawable_w = media_type_drawable.intrinsicWidth
val drawable_h = media_type_drawable.intrinsicHeight
// int view_w = getWidth();
@ -454,18 +454,18 @@ class MyNetworkImageView : AppCompatImageView {
// プロフ表示の背景画像のレイアウト崩れの対策
var measureProfileBg = false
override fun onMeasure(widthMeasureSpec : Int, heightMeasureSpec : Int) {
if(measureProfileBg) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (measureProfileBg) {
// このモードではコンテンツを一切見ずにサイズを決める
val w_size = MeasureSpec.getSize(widthMeasureSpec)
val w_measured = when(MeasureSpec.getMode(widthMeasureSpec)) {
val w_measured = when (MeasureSpec.getMode(widthMeasureSpec)) {
MeasureSpec.EXACTLY -> w_size
MeasureSpec.AT_MOST -> w_size
MeasureSpec.UNSPECIFIED -> 0
else -> 0
}
val h_size = MeasureSpec.getSize(heightMeasureSpec)
val h_measured = when(MeasureSpec.getMode(heightMeasureSpec)) {
val h_measured = when (MeasureSpec.getMode(heightMeasureSpec)) {
MeasureSpec.EXACTLY -> h_size
MeasureSpec.AT_MOST -> h_size
MeasureSpec.UNSPECIFIED -> 0
@ -474,31 +474,31 @@ class MyNetworkImageView : AppCompatImageView {
setMeasuredDimension(w_measured, h_measured)
} else {
// 通常のImageViewは内容を見てサイズを決める
// たとえLayputParamがw,hともmatchParentでも内容を見てしまう
// たとえLayoutParamがw,hともmatchParentでも内容を見てしまう
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}
/////////////////////////////////////////////////////////////////////
private var focusX : Float = 0f
private var focusY : Float = 0f
private var focusX: Float = 0f
private var focusY: Float = 0f
fun setFocusPoint(focusX : Float, focusY : Float) {
fun setFocusPoint(focusX: Float, focusY: Float) {
// フォーカスポイントは上がプラスで下がマイナス
// https://github.com/jonom/jquery-focuspoint#1-calculate-your-images-focus-point
// このタイミングで正規化してしまう
this.focusX = clipRange(- 1f, 1f, focusX)
this.focusY = - clipRange(- 1f, 1f, focusY)
this.focusX = clipRange(-1f, 1f, focusX)
this.focusY = -clipRange(-1f, 1f, focusY)
}
override fun setImageBitmap(bm : Bitmap?) {
override fun setImageBitmap(bm: Bitmap?) {
super.setImageBitmap(bm)
updateFocusPoint()
}
override fun setImageDrawable(drawable : Drawable?) {
override fun setImageDrawable(drawable: Drawable?) {
super.setImageDrawable(drawable)
updateFocusPoint()
}
@ -508,30 +508,30 @@ class MyNetworkImageView : AppCompatImageView {
// ビューのサイズが0より大きい
val view_w = width.toFloat()
val view_h = height.toFloat()
if(view_w <= 0f || view_h <= 0f) return
if (view_w <= 0f || view_h <= 0f) return
// 画像のサイズが0より大きい
val drawable = this.drawable ?: return
val drawable_w = drawable.intrinsicWidth.toFloat()
val drawable_h = drawable.intrinsicHeight.toFloat()
if(drawable_w <= 0f || drawable_h <= 0f) return
if (drawable_w <= 0f || drawable_h <= 0f) return
when(scaleType) {
when (scaleType) {
ScaleType.CENTER_CROP, ScaleType.MATRIX -> {
val view_aspect = view_w / view_h
val drawable_aspect = drawable_w / drawable_h
if(drawable_aspect >= view_aspect) {
if (drawable_aspect >= view_aspect) {
// ビューより画像の方が横長
val focus_x = this.focusX
if(focus_x == 0f) {
if (focus_x == 0f) {
scaleType = ScaleType.CENTER_CROP
} else {
val matrix = Matrix()
val scale = view_h / drawable_h
val delta = focus_x * ((drawable_w * scale) - view_w)
log.d("updateFocusPoint x delta=$delta")
matrix.postTranslate(drawable_w / - 2f, drawable_h / - 2f)
matrix.postTranslate(drawable_w / -2f, drawable_h / -2f)
matrix.postScale(scale, scale)
matrix.postTranslate((view_w - delta) / 2f, view_h / 2f)
scaleType = ScaleType.MATRIX
@ -540,13 +540,13 @@ class MyNetworkImageView : AppCompatImageView {
} else {
// ビューより画像の方が縦長
val focus_y = this.focusY
if(focus_y == 0f) {
if (focus_y == 0f) {
scaleType = ScaleType.CENTER_CROP
} else {
val matrix = Matrix()
val scale = view_w / drawable_w
val delta = focus_y * ((drawable_h * scale) - view_h)
matrix.postTranslate(drawable_w / - 2f, drawable_h / - 2f)
matrix.postTranslate(drawable_w / -2f, drawable_h / -2f)
matrix.postScale(scale, scale)
matrix.postTranslate(view_w / 2f, (view_h - delta) / 2f)
scaleType = ScaleType.MATRIX
@ -562,7 +562,7 @@ class MyNetworkImageView : AppCompatImageView {
}
fun setScaleTypeForMedia() {
when(scaleType) {
when (scaleType) {
ScaleType.CENTER_CROP, ScaleType.MATRIX -> {
// nothing to do
}

View File

@ -17,7 +17,7 @@ import kotlin.math.abs
import kotlin.math.max
import kotlin.math.sqrt
class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int) :
class PinchBitmapView(context: Context, attrs: AttributeSet?, defStyle: Int) :
View(context, attrs, defStyle) {
companion object {
@ -25,47 +25,47 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
internal val log = LogCategory("PinchImageView")
// 数値を範囲内にクリップする
private fun clip(min : Float, max : Float, v : Float) : Float {
return if(v < min) min else if(v > max) max else v
private fun clip(min: Float, max: Float, v: Float): Float {
return if (v < min) min else if (v > max) max else v
}
// ビューの幅と画像の描画サイズを元に描画位置をクリップする
private fun clipTranslate(
view_w : Float // ビューの幅
, bitmap_w : Float // 画像の幅
, current_scale : Float // 画像の拡大率
, trans_x : Float // タッチ操作による表示位置
) : Float {
view_w: Float // ビューの幅
, bitmap_w: Float // 画像の幅
, current_scale: Float // 画像の拡大率
, trans_x: Float // タッチ操作による表示位置
): Float {
// 余白(拡大率が小さい場合はプラス、拡大率が大きい場合はマイナス)
val padding = view_w - bitmap_w * current_scale
// 余白が>=0なら画像を中心に表示する。 <0なら操作された位置をクリップする。
return if(padding >= 0f) padding / 2f else clip(padding, 0f, trans_x)
return if (padding >= 0f) padding / 2f else clip(padding, 0f, trans_x)
}
}
private var callback : Callback? = null
private var callback: Callback? = null
private var bitmap : Bitmap? = null
private var bitmap_w : Float = 0.toFloat()
private var bitmap_h : Float = 0.toFloat()
private var bitmap_aspect : Float = 0.toFloat()
private var bitmap: Bitmap? = null
private var bitmap_w: Float = 0.toFloat()
private var bitmap_h: Float = 0.toFloat()
private var bitmap_aspect: Float = 0.toFloat()
// 画像を表示する位置と拡大率
private var current_trans_x : Float = 0.toFloat()
private var current_trans_y : Float = 0.toFloat()
private var current_scale : Float = 0.toFloat()
private var current_trans_x: Float = 0.toFloat()
private var current_trans_y: Float = 0.toFloat()
private var current_scale: Float = 0.toFloat()
// 画像表示に使う構造体
private val drawMatrix = Matrix()
internal val paint = Paint()
// タッチ操作中に指を動かした
private var bDrag : Boolean = false
private var bDrag: Boolean = false
// タッチ操作中に指の数を変えた
private var bPointerCountChanged : Boolean = false
private var bPointerCountChanged: Boolean = false
// ページめくりに必要なスワイプ強度
private var swipe_velocity = 0f
@ -77,7 +77,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
private var time_touch_start = 0L
// フリック操作の検出に使う
private var velocityTracker : VelocityTracker? = null
private var velocityTracker: VelocityTracker? = null
private var click_time = 0L
private var click_count = 0
@ -89,27 +89,27 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
private val start_pos = PointerAvg()
// 移動開始時の画像の位置
private var start_image_trans_x : Float = 0.toFloat()
private var start_image_trans_y : Float = 0.toFloat()
private var start_image_scale : Float = 0.toFloat()
private var start_image_trans_x: Float = 0.toFloat()
private var start_image_trans_y: Float = 0.toFloat()
private var start_image_scale: Float = 0.toFloat()
private var scale_min : Float = 0.toFloat()
private var scale_max : Float = 0.toFloat()
private var scale_min: Float = 0.toFloat()
private var scale_max: Float = 0.toFloat()
private var view_w : Float = 0.toFloat()
private var view_h : Float = 0.toFloat()
private var view_aspect : Float = 0.toFloat()
private var view_w: Float = 0.toFloat()
private var view_h: Float = 0.toFloat()
private var view_aspect: Float = 0.toFloat()
private val tracking_matrix = Matrix()
private val tracking_matrix_inv = Matrix()
private val avg_on_image1 = FloatArray(2)
private val avg_on_image2 = FloatArray(2)
constructor(context : Context) : this(context, null) {
constructor(context: Context) : this(context, null) {
init(context)
}
constructor(context : Context, attrs : AttributeSet?) : this(context, attrs, 0) {
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {
init(context)
}
@ -117,7 +117,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
init(context)
}
internal fun init(context : Context) {
internal fun init(context: Context) {
// 定数をdpからpxに変換
val density = context.resources.displayMetrics.density
@ -129,16 +129,16 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
// ページめくり操作のコールバック
interface Callback {
fun onSwipe(deltaX : Int, deltaY : Int)
fun onSwipe(deltaX: Int, deltaY: Int)
fun onMove(bitmap_w : Float, bitmap_h : Float, tx : Float, ty : Float, scale : Float)
fun onMove(bitmap_w: Float, bitmap_h: Float, tx: Float, ty: Float, scale: Float)
}
fun setCallback(callback : Callback?) {
fun setCallback(callback: Callback?) {
this.callback = callback
}
fun setBitmap(b : Bitmap?) {
fun setBitmap(b: Bitmap?) {
bitmap?.recycle()
@ -147,11 +147,11 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
initializeScale()
}
override fun onDraw(canvas : Canvas) {
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val bitmap = this.bitmap
if(bitmap != null && ! bitmap.isRecycled) {
if (bitmap != null && !bitmap.isRecycled) {
drawMatrix.reset()
drawMatrix.postScale(current_scale, current_scale)
@ -162,7 +162,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
}
}
override fun onSizeChanged(w : Int, h : Int, oldw : Int, oldh : Int) {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
view_w = max(1f, w.toFloat())
@ -172,7 +172,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
initializeScale()
}
override fun performClick() : Boolean {
override fun performClick(): Boolean {
super.performClick()
initializeScale()
@ -180,28 +180,28 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
return true
}
private var defaultScale : Float = 1f
private var defaultScale: Float = 1f
// 表示位置の初期化
// 呼ばれるのは、ビットマップを変更した時、ビューのサイズが変わった時、画像をクリックした時
private fun initializeScale() {
val bitmap = this.bitmap
if(bitmap != null && ! bitmap.isRecycled && view_w >= 1f) {
if (bitmap != null && !bitmap.isRecycled && view_w >= 1f) {
bitmap_w = max(1f, bitmap.width.toFloat())
bitmap_h = max(1f, bitmap.height.toFloat())
bitmap_aspect = bitmap_w / bitmap_h
if(view_aspect > bitmap_aspect) {
if (view_aspect > bitmap_aspect) {
scale_min = view_h / bitmap_h / 2f
scale_max = view_w / bitmap_w * 8f
} else {
scale_min = view_w / bitmap_w / 2f
scale_max = view_h / bitmap_h * 8f
}
if(scale_max < scale_min) scale_max = scale_min * 16f
if (scale_max < scale_min) scale_max = scale_min * 16f
defaultScale = if(view_aspect > bitmap_aspect) {
defaultScale = if (view_aspect > bitmap_aspect) {
view_h / bitmap_h
} else {
view_w / bitmap_w
@ -232,17 +232,18 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev : MotionEvent) : Boolean {
override fun onTouchEvent(ev: MotionEvent): Boolean {
val bitmap = this.bitmap
if(bitmap == null
if (bitmap == null
|| bitmap.isRecycled
|| view_w < 1f)
|| view_w < 1f
)
return false
val action = ev.action
if(action == MotionEvent.ACTION_DOWN) {
if (action == MotionEvent.ACTION_DOWN) {
time_touch_start = SystemClock.elapsedRealtime()
velocityTracker?.clear()
@ -257,7 +258,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
velocityTracker?.addMovement(ev)
when(action) {
when (action) {
MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_POINTER_UP -> {
// タッチ操作中に指の数を変えた
bPointerCountChanged = true
@ -281,12 +282,12 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
private fun checkClickOrPaging() {
if(! bDrag) {
if (!bDrag) {
// 指を動かしていないなら
val now = SystemClock.elapsedRealtime()
if(now - time_touch_start >= 1000L) {
if (now - time_touch_start >= 1000L) {
// ロングタップはタップカウントをリセットする
log.d("click count reset by long tap")
click_count = 0
@ -296,17 +297,17 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
val delta = now - click_time
click_time = now
if(delta > 334L) {
if (delta > 334L) {
// 前回のタップからの時刻が長いとタップカウントをリセットする
log.d("click count reset by long interval")
click_count = 0
}
++ click_count
++click_count
log.d("click %d %d", click_count, delta)
log.d("click ${click_count} ${delta}")
if(click_count >= 2) {
if (click_count >= 2) {
// ダブルタップでクリック操作
click_count = 0
performClick()
@ -318,7 +319,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
click_count = 0
val velocityTracker = this.velocityTracker
if(! bPointerCountChanged && velocityTracker != null) {
if (!bPointerCountChanged && velocityTracker != null) {
// 指の数を変えていないならページめくり操作かもしれない
@ -327,7 +328,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
abs(current_trans_x - start_image_trans_x),
abs(current_trans_y - start_image_trans_y)
)
if(image_moved >= drag_length) {
if (image_moved >= drag_length) {
log.d("image moved. not flick action. $image_moved")
return
}
@ -340,7 +341,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
val velocity = sqrt(vx * vx + vy * vy)
val aspect = try {
avx / avy
} catch(ex : Throwable) {
} catch (ex: Throwable) {
Float.MAX_VALUE
}
@ -353,13 +354,13 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
else -> swipe_velocity
}
if(velocity < vMin) {
if (velocity < vMin) {
log.d("velocity $velocity not enough to pagingX")
return
}
log.d("pagingX! m=$image_moved a=$aspect v=$velocity")
runOnMainLooper { callback?.onSwipe(if(vx >= 0f) - 1 else 1, 0) }
runOnMainLooper { callback?.onSwipe(if (vx >= 0f) -1 else 1, 0) }
}
aspect <= 0.333f -> {
@ -370,13 +371,13 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
else -> swipe_velocity
}
if(velocity < vMin) {
if (velocity < vMin) {
log.d("velocity $velocity not enough to pagingY")
return
}
log.d("pagingY! m=$image_moved a=$aspect v=$velocity")
runOnMainLooper { callback?.onSwipe(0, if(vy >= 0f) - 1 else 1) }
runOnMainLooper { callback?.onSwipe(0, if (vy >= 0f) -1 else 1) }
}
else -> log.d("flick is not horizontal/vertical. aspect=$aspect")
@ -388,18 +389,18 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
internal class PointerAvg {
// タッチ位置の数
var count : Int = 0
var count: Int = 0
// タッチ位置の平均
val avg = FloatArray(2)
// 中心と、中心から最も離れたタッチ位置の間の距離
var max_radius : Float = 0.toFloat()
var max_radius: Float = 0.toFloat()
fun update(ev : MotionEvent) {
fun update(ev: MotionEvent) {
count = ev.pointerCount
if(count <= 1) {
if (count <= 1) {
avg[0] = ev.x
avg[1] = ev.y
max_radius = 0f
@ -407,26 +408,26 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
} else {
avg[0] = 0f
avg[1] = 0f
for(i in 0 until count) {
for (i in 0 until count) {
avg[0] += ev.getX(i)
avg[1] += ev.getY(i)
}
avg[0] /= count.toFloat()
avg[1] /= count.toFloat()
max_radius = 0f
for(i in 0 until count) {
for (i in 0 until count) {
val dx = ev.getX(i) - avg[0]
val dy = ev.getY(i) - avg[1]
val radius = dx * dx + dy * dy
if(radius > max_radius) max_radius = radius
if (radius > max_radius) max_radius = radius
}
max_radius = sqrt(max_radius.toDouble()).toFloat()
if(max_radius < 1f) max_radius = 1f
if (max_radius < 1f) max_radius = 1f
}
}
}
private fun trackStart(ev : MotionEvent) {
private fun trackStart(ev: MotionEvent) {
// 追跡開始時の指の位置
start_pos.update(ev)
@ -439,7 +440,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
}
// 画面上の指の位置から画像中の指の位置を調べる
private fun getCoordinateOnImage(dst : FloatArray, src : FloatArray) {
private fun getCoordinateOnImage(dst: FloatArray, src: FloatArray) {
tracking_matrix.reset()
tracking_matrix.postScale(current_scale, current_scale)
tracking_matrix.postTranslate(current_trans_x, current_trans_y)
@ -447,10 +448,10 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
tracking_matrix_inv.mapPoints(dst, src)
}
private fun trackNext(ev : MotionEvent) {
private fun trackNext(ev: MotionEvent) {
pos.update(ev)
if(pos.count != start_pos.count) {
if (pos.count != start_pos.count) {
// タッチ操作中に指の数が変わった
log.d("nextTracking: pointer count changed")
bPointerCountChanged = true
@ -460,7 +461,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
}
// ズーム操作
if(pos.count > 1) {
if (pos.count > 1) {
// タッチ位置にある絵柄の座標を調べる
getCoordinateOnImage(avg_on_image1, pos.avg)
@ -488,7 +489,7 @@ class PinchBitmapView(context : Context, attrs : AttributeSet?, defStyle : Int)
val move_y = pos.avg[1] - start_pos.avg[1]
// 「指を動かした」と判断したらフラグを立てる
if(abs(move_x) >= drag_length || abs(move_y) >= drag_length) {
if (abs(move_x) >= drag_length || abs(move_y) >= drag_length) {
bDrag = true
}

View File

@ -248,11 +248,7 @@ fun createResizedBitmap(
val paint = Paint()
paint.isFilterBitmap = true
canvas.drawBitmap(sourceBitmap, matrix, paint)
log.d(
"createResizedBitmap: resized to %sx%s",
dstSizeInt.x,
dstSizeInt.y
)
log.d("createResizedBitmap: resized to ${dstSizeInt.x}x${dstSizeInt.y}")
val tmp = dst
dst = null
tmp

View File

@ -167,7 +167,7 @@ import java.util.*
private const val MIME_TYPE_APPLICATION_OCTET_STREAM = "application/octet-stream"
private val mimeTypeExMap : HashMap<String, String> by lazy {
private val mimeTypeExMap: HashMap<String, String> by lazy {
val map = HashMap<String, String>()
map["BDM"] = "application/vnd.syncml.dm+wbxml"
map["DAT"] = ""
@ -179,33 +179,33 @@ private val mimeTypeExMap : HashMap<String, String> by lazy {
}
@Suppress("unused")
fun getMimeType(log : LogCategory?, src : String) : String {
fun getMimeType(log: LogCategory?, src: String): String {
var ext = MimeTypeMap.getFileExtensionFromUrl(src)
if(ext != null && ext.isNotEmpty()) {
if (ext != null && ext.isNotEmpty()) {
ext = ext.lowercase()
//
var mime_type : String? = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext)
if(mime_type?.isNotEmpty() == true) return mime_type
var mime_type: String? = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext)
if (mime_type?.isNotEmpty() == true) return mime_type
//
mime_type = mimeTypeExMap[ext]
if(mime_type?.isNotEmpty() == true) return mime_type
if (mime_type?.isNotEmpty() == true) return mime_type
// 戻り値が空文字列の場合とnullの場合があり、空文字列の場合は既知なのでログ出力しない
if(mime_type == null && log != null) {
log.w("getMimeType(): unknown file extension '%s'", ext)
if (mime_type == null && log != null) {
log.w("getMimeType(): unknown file extension '${ext}'")
}
}
return MIME_TYPE_APPLICATION_OCTET_STREAM
}
fun getDocumentName(contentResolver : ContentResolver, uri : Uri) : String {
fun getDocumentName(contentResolver: ContentResolver, uri: Uri): String {
val errorName = "no_name"
return contentResolver.query(uri, null, null, null, null, null)
?.use { cursor ->
return if(! cursor.moveToFirst()) {
return if (!cursor.moveToFirst()) {
errorName
} else {
cursor.getStringOrNull(OpenableColumns.DISPLAY_NAME) ?: errorName
@ -214,18 +214,18 @@ fun getDocumentName(contentResolver : ContentResolver, uri : Uri) : String {
?: errorName
}
fun getStreamSize(bClose : Boolean, inStream : InputStream) : Long {
fun getStreamSize(bClose: Boolean, inStream: InputStream): Long {
try {
var size = 0L
while(true) {
while (true) {
val r = IOUtils.skip(inStream, 16384)
if(r <= 0) break
if (r <= 0) break
size += r
}
return size
} finally {
@Suppress("DEPRECATION")
if(bClose) IOUtils.closeQuietly(inStream)
if (bClose) IOUtils.closeQuietly(inStream)
}
}
@ -242,7 +242,7 @@ fun getStreamSize(bClose : Boolean, inStream : InputStream) : Long {
// }
//}
fun Context.loadRawResource(resId : Int) : ByteArray {
fun Context.loadRawResource(resId: Int): ByteArray {
resources.openRawResource(resId).use { inStream ->
val bao = ByteArrayOutputStream(inStream.available())
IOUtils.copy(inStream, bao)
@ -250,7 +250,7 @@ fun Context.loadRawResource(resId : Int) : ByteArray {
}
}
fun intentOpenDocument(mimeType : String) : Intent {
fun intentOpenDocument(mimeType: String): Intent {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = mimeType // "image/*"
@ -258,14 +258,14 @@ fun intentOpenDocument(mimeType : String) : Intent {
}
fun intentGetContent(
allowMultiple : Boolean,
caption : String,
mimeTypes : Array<out String>
) : Intent {
allowMultiple: Boolean,
caption: String,
mimeTypes: Array<out String>
): Intent {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
if(allowMultiple) {
if (allowMultiple) {
// EXTRA_ALLOW_MULTIPLE は API 18 (4.3)以降。ACTION_GET_CONTENT でも ACTION_OPEN_DOCUMENT でも指定できる
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
@ -287,13 +287,13 @@ fun intentGetContent(
}
data class GetContentResultEntry(
val uri : Uri,
val mimeType : String? = null,
var time : Long? = null
val uri: Uri,
val mimeType: String? = null,
var time: Long? = null
)
// returns list of pair of uri and mime-type.
fun Intent.handleGetContentResult(contentResolver : ContentResolver) : ArrayList<GetContentResultEntry> {
fun Intent.handleGetContentResult(contentResolver: ContentResolver): ArrayList<GetContentResultEntry> {
val urlList = ArrayList<GetContentResultEntry>()
// 単一選択
this.data?.let {
@ -301,10 +301,10 @@ fun Intent.handleGetContentResult(contentResolver : ContentResolver) : ArrayList
}
// 複数選択
val cd = this.clipData
if(cd != null) {
for(i in 0 until cd.itemCount) {
if (cd != null) {
for (i in 0 until cd.itemCount) {
cd.getItemAt(i)?.uri?.let { uri ->
if(null == urlList.find { it.uri == uri }) {
if (null == urlList.find { it.uri == uri }) {
urlList.add(GetContentResultEntry(uri))
}
}
@ -316,7 +316,7 @@ fun Intent.handleGetContentResult(contentResolver : ContentResolver) : ArrayList
it.uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
} catch(_ : Throwable) {
} catch (_: Throwable) {
}
}
return urlList