2021-05-19 09:51:34 +02:00
|
|
|
package jp.juggler.subwaytooter
|
|
|
|
|
|
|
|
import android.view.View
|
|
|
|
import android.widget.ImageView
|
|
|
|
import com.omadahealth.github.swipyrefreshlayout.library.SwipyRefreshLayoutDirection
|
|
|
|
import jp.juggler.subwaytooter.util.endPadding
|
|
|
|
import jp.juggler.subwaytooter.util.startPadding
|
|
|
|
import jp.juggler.subwaytooter.view.ListDivider
|
|
|
|
import jp.juggler.util.*
|
|
|
|
import kotlinx.coroutines.*
|
|
|
|
import org.jetbrains.anko.backgroundColor
|
|
|
|
import org.jetbrains.anko.bottomPadding
|
|
|
|
import org.jetbrains.anko.topPadding
|
|
|
|
|
|
|
|
fun ColumnViewHolder.closeBitmaps() {
|
|
|
|
try {
|
|
|
|
ivColumnBackgroundImage.visibility = View.GONE
|
|
|
|
ivColumnBackgroundImage.setImageDrawable(null)
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
lastImageBitmap?.recycle()
|
|
|
|
lastImageBitmap = null
|
2021-05-19 09:51:34 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
lastImageTask?.cancel()
|
|
|
|
lastImageTask = null
|
2021-05-19 09:51:34 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
lastImageUri = null
|
2021-05-19 09:51:34 +02:00
|
|
|
} catch (ex: Throwable) {
|
|
|
|
ColumnViewHolder.log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun ColumnViewHolder.loadBackgroundImage(iv: ImageView, url: String?) {
|
|
|
|
try {
|
2021-06-22 10:31:51 +02:00
|
|
|
if (url == null || url.isEmpty() || PrefB.bpDontShowColumnBackgroundImage(activity.pref)) {
|
2021-05-19 09:51:34 +02:00
|
|
|
// 指定がないなら閉じる
|
|
|
|
closeBitmaps()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (url == lastImageUri) {
|
2021-05-19 09:51:34 +02:00
|
|
|
// 今表示してるのと同じ
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 直前の処理をキャンセルする。Bitmapも破棄する
|
|
|
|
closeBitmaps()
|
|
|
|
|
|
|
|
// ロード開始
|
2021-06-20 15:12:25 +02:00
|
|
|
lastImageUri = url
|
|
|
|
val screenW = iv.resources.displayMetrics.widthPixels
|
|
|
|
val screenH = iv.resources.displayMetrics.heightPixels
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
// 非同期処理を開始
|
2021-06-20 15:12:25 +02:00
|
|
|
lastImageTask = launchMain {
|
2021-05-19 09:51:34 +02:00
|
|
|
val bitmap = try {
|
|
|
|
withContext(Dispatchers.IO) {
|
|
|
|
try {
|
|
|
|
createResizedBitmap(
|
|
|
|
activity, url.toUri(),
|
2021-06-20 15:12:25 +02:00
|
|
|
when {
|
|
|
|
screenW > screenH -> screenW
|
|
|
|
else -> screenH
|
|
|
|
}
|
2021-05-19 09:51:34 +02:00
|
|
|
)
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
ColumnViewHolder.log.trace(ex)
|
|
|
|
null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (ex: Throwable) {
|
2021-06-20 15:12:25 +02:00
|
|
|
ColumnViewHolder.log.w(ex, "loadBackgroundImage failed.")
|
2021-05-19 09:51:34 +02:00
|
|
|
null
|
|
|
|
}
|
|
|
|
if (bitmap != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (!coroutineContext.isActive || url != lastImageUri) {
|
2021-05-19 09:51:34 +02:00
|
|
|
bitmap.recycle()
|
|
|
|
} else {
|
2021-06-20 15:12:25 +02:00
|
|
|
lastImageBitmap = bitmap
|
|
|
|
iv.setImageBitmap(lastImageBitmap)
|
2021-05-19 09:51:34 +02:00
|
|
|
iv.visibility = View.VISIBLE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
ColumnViewHolder.log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
fun ColumnViewHolder.onPageDestroy(pageIdx: Int) {
|
2021-05-19 09:51:34 +02:00
|
|
|
// タブレットモードの場合、onPageCreateより前に呼ばれる
|
|
|
|
val column = this.column
|
|
|
|
if (column != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
ColumnViewHolder.log.d("onPageDestroy [$pageIdx] ${tvColumnName.text}")
|
2021-05-19 09:51:34 +02:00
|
|
|
saveScrollPosition()
|
|
|
|
listView.adapter = null
|
|
|
|
column.removeColumnViewHolder(this)
|
|
|
|
this.column = null
|
|
|
|
}
|
|
|
|
|
|
|
|
closeBitmaps()
|
|
|
|
|
|
|
|
activity.closeListItemPopup()
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
fun ColumnViewHolder.onPageCreate(column: Column, pageIdx: Int, pageCount: Int) {
|
|
|
|
bindingBusy = true
|
2021-05-19 09:51:34 +02:00
|
|
|
try {
|
|
|
|
this.column = column
|
2021-06-20 15:12:25 +02:00
|
|
|
this.pageIdx = pageIdx
|
2021-05-19 09:51:34 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
ColumnViewHolder.log.d("onPageCreate [$pageIdx] ${column.getColumnName(true)}")
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
val bSimpleList =
|
2021-06-22 10:31:51 +02:00
|
|
|
column.type != ColumnType.CONVERSATION && PrefB.bpSimpleList(activity.pref)
|
2021-05-19 09:51:34 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
tvColumnIndex.text = activity.getString(R.string.column_index, pageIdx + 1, pageCount)
|
2021-05-19 09:51:34 +02:00
|
|
|
tvColumnStatus.text = "?"
|
|
|
|
ivColumnIcon.setImageResource(column.getIconId())
|
|
|
|
|
|
|
|
listView.adapter = null
|
|
|
|
if (listView.itemDecorationCount == 0) {
|
|
|
|
listView.addItemDecoration(ListDivider(activity))
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val statusAdapter = ItemListAdapter(activity, column, this, bSimpleList)
|
|
|
|
this.statusAdapter = statusAdapter
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
val isNotificationColumn = column.isNotificationColumn
|
|
|
|
|
|
|
|
// 添付メディアや正規表現のフィルタ
|
|
|
|
val bAllowFilter = column.canStatusFilter()
|
|
|
|
|
|
|
|
showColumnSetting(false)
|
|
|
|
|
2021-05-21 10:20:14 +02:00
|
|
|
for (invalidator in emojiQueryInvalidatorList) {
|
|
|
|
invalidator.register(null)
|
|
|
|
}
|
|
|
|
emojiQueryInvalidatorList.clear()
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
for (invalidator in extraInvalidatorList) {
|
2021-05-21 10:20:14 +02:00
|
|
|
invalidator.register(null)
|
|
|
|
}
|
2021-06-20 15:12:25 +02:00
|
|
|
extraInvalidatorList.clear()
|
|
|
|
|
|
|
|
cbDontCloseColumn.isCheckedNoAnime = column.dontClose
|
|
|
|
cbRemoteOnly.isCheckedNoAnime = column.remoteOnly
|
|
|
|
cbWithAttachment.isCheckedNoAnime = column.withAttachment
|
|
|
|
cbWithHighlight.isCheckedNoAnime = column.withHighlight
|
|
|
|
cbDontShowBoost.isCheckedNoAnime = column.dontShowBoost
|
|
|
|
cbDontShowFollow.isCheckedNoAnime = column.dontShowFollow
|
|
|
|
cbDontShowFavourite.isCheckedNoAnime = column.dontShowFavourite
|
|
|
|
cbDontShowReply.isCheckedNoAnime = column.dontShowReply
|
|
|
|
cbDontShowReaction.isCheckedNoAnime = column.dontShowReaction
|
|
|
|
cbDontShowVote.isCheckedNoAnime = column.dontShowVote
|
|
|
|
cbDontShowNormalToot.isCheckedNoAnime = column.dontShowNormalToot
|
|
|
|
cbDontShowNonPublicToot.isCheckedNoAnime = column.dontShowNonPublicToot
|
|
|
|
cbInstanceLocal.isCheckedNoAnime = column.instanceLocal
|
|
|
|
cbDontStreaming.isCheckedNoAnime = column.dontStreaming
|
|
|
|
cbDontAutoRefresh.isCheckedNoAnime = column.dontAutoRefresh
|
|
|
|
cbHideMediaDefault.isCheckedNoAnime = column.hideMediaDefault
|
|
|
|
cbSystemNotificationNotRelated.isCheckedNoAnime = column.systemNotificationNotRelated
|
|
|
|
cbEnableSpeech.isCheckedNoAnime = column.enableSpeech
|
|
|
|
cbOldApi.isCheckedNoAnime = column.useOldApi
|
|
|
|
|
|
|
|
etRegexFilter.setText(column.regexText)
|
|
|
|
etSearch.setText(column.searchQuery)
|
|
|
|
cbResolve.isCheckedNoAnime = column.searchResolve
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
cbRemoteOnly.vg(column.canRemoteOnly())
|
|
|
|
|
|
|
|
cbWithAttachment.vg(bAllowFilter)
|
|
|
|
cbWithHighlight.vg(bAllowFilter)
|
|
|
|
etRegexFilter.vg(bAllowFilter)
|
|
|
|
llRegexFilter.vg(bAllowFilter)
|
|
|
|
btnLanguageFilter.vg(bAllowFilter)
|
|
|
|
|
|
|
|
cbDontShowBoost.vg(column.canFilterBoost())
|
|
|
|
cbDontShowReply.vg(column.canFilterReply())
|
|
|
|
cbDontShowNormalToot.vg(column.canFilterNormalToot())
|
|
|
|
cbDontShowNonPublicToot.vg(column.canFilterNonPublicToot())
|
|
|
|
cbDontShowReaction.vg(isNotificationColumn && column.isMisskey)
|
|
|
|
cbDontShowVote.vg(isNotificationColumn)
|
|
|
|
cbDontShowFavourite.vg(isNotificationColumn && !column.isMisskey)
|
|
|
|
cbDontShowFollow.vg(isNotificationColumn)
|
|
|
|
|
|
|
|
cbInstanceLocal.vg(column.type == ColumnType.HASHTAG)
|
|
|
|
|
2021-05-27 04:15:59 +02:00
|
|
|
cbDontStreaming.vg(column.canStreamingType())
|
2021-05-19 09:51:34 +02:00
|
|
|
cbDontAutoRefresh.vg(column.canAutoRefresh())
|
|
|
|
cbHideMediaDefault.vg(column.canNSFWDefault())
|
|
|
|
cbSystemNotificationNotRelated.vg(column.isNotificationColumn)
|
|
|
|
cbEnableSpeech.vg(column.canSpeech())
|
|
|
|
cbOldApi.vg(column.type == ColumnType.DIRECT_MESSAGES)
|
|
|
|
|
|
|
|
btnDeleteNotification.vg(column.isNotificationColumn)
|
|
|
|
|
2021-05-21 10:20:14 +02:00
|
|
|
when {
|
|
|
|
column.isSearchColumn -> {
|
|
|
|
llSearch.vg(true)
|
|
|
|
|
|
|
|
flEmoji.vg(false)
|
|
|
|
tvEmojiDesc.vg(false)
|
|
|
|
btnEmojiAdd.vg(false)
|
|
|
|
|
|
|
|
etSearch.vg(true)
|
2021-06-22 10:31:51 +02:00
|
|
|
btnSearchClear.vg(PrefB.bpShowSearchClear(activity.pref))
|
2021-05-21 10:20:14 +02:00
|
|
|
cbResolve.vg(column.type == ColumnType.SEARCH)
|
|
|
|
}
|
2021-05-22 14:02:55 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
column.type == ColumnType.REACTIONS && column.accessInfo.isMastodon -> {
|
2021-05-21 10:20:14 +02:00
|
|
|
llSearch.vg(true)
|
|
|
|
|
|
|
|
flEmoji.vg(true)
|
|
|
|
tvEmojiDesc.vg(true)
|
|
|
|
btnEmojiAdd.vg(true)
|
|
|
|
|
|
|
|
etSearch.vg(false)
|
|
|
|
btnSearchClear.vg(false)
|
|
|
|
cbResolve.vg(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> llSearch.vg(false)
|
2021-05-19 09:51:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
llListList.vg(column.type == ColumnType.LIST_LIST)
|
|
|
|
|
|
|
|
llHashtagExtra.vg(column.hasHashtagExtra)
|
2021-06-20 15:12:25 +02:00
|
|
|
etHashtagExtraAny.setText(column.hashtagAny)
|
|
|
|
etHashtagExtraAll.setText(column.hashtagAll)
|
|
|
|
etHashtagExtraNone.setText(column.hashtagNone)
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
// tvRegexFilterErrorの表示を更新
|
|
|
|
if (bAllowFilter) {
|
|
|
|
isRegexValid()
|
|
|
|
}
|
|
|
|
|
|
|
|
val canRefreshTop = column.canRefreshTopBySwipe()
|
|
|
|
val canRefreshBottom = column.canRefreshBottomBySwipe()
|
|
|
|
|
|
|
|
refreshLayout.isEnabled = canRefreshTop || canRefreshBottom
|
|
|
|
refreshLayout.direction = if (canRefreshTop && canRefreshBottom) {
|
|
|
|
SwipyRefreshLayoutDirection.BOTH
|
|
|
|
} else if (canRefreshTop) {
|
|
|
|
SwipyRefreshLayoutDirection.TOP
|
|
|
|
} else {
|
|
|
|
SwipyRefreshLayoutDirection.BOTTOM
|
|
|
|
}
|
|
|
|
|
|
|
|
bRefreshErrorWillShown = false
|
|
|
|
llRefreshError.clearAnimation()
|
|
|
|
llRefreshError.visibility = View.GONE
|
|
|
|
|
|
|
|
//
|
2021-06-20 15:12:25 +02:00
|
|
|
listView.adapter = statusAdapter
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
//XXX FastScrollerのサポートを諦める。ライブラリはいくつかあるんだけど、設定でON/OFFできなかったり頭文字バブルを無効にできなかったり
|
2021-06-22 10:31:51 +02:00
|
|
|
// listView.isFastScrollEnabled = ! PrefB.bpDisableFastScroller(Pref.pref(activity))
|
2021-05-19 09:51:34 +02:00
|
|
|
|
|
|
|
column.addColumnViewHolder(this)
|
|
|
|
|
|
|
|
lastAnnouncementShown = -1L
|
|
|
|
|
|
|
|
fun dip(dp: Int): Int = (activity.density * dp + 0.5f).toInt()
|
|
|
|
val context = activity
|
|
|
|
|
2021-06-22 10:31:51 +02:00
|
|
|
val announcementsBgColor = PrefI.ipAnnouncementsBgColor(App1.pref).notZero()
|
2021-05-19 09:51:34 +02:00
|
|
|
?: context.attrColor(R.attr.colorSearchFormBackground)
|
|
|
|
|
|
|
|
btnAnnouncementsCutout.apply {
|
|
|
|
color = announcementsBgColor
|
|
|
|
}
|
|
|
|
|
|
|
|
llAnnouncementsBox.apply {
|
|
|
|
background = createRoundDrawable(dip(6).toFloat(), announcementsBgColor)
|
2021-06-20 15:12:25 +02:00
|
|
|
val padV = dip(2)
|
|
|
|
setPadding(0, padV, 0, padV)
|
2021-05-19 09:51:34 +02:00
|
|
|
}
|
|
|
|
|
2021-06-22 10:31:51 +02:00
|
|
|
val searchBgColor = PrefI.ipSearchBgColor(App1.pref).notZero()
|
2021-05-19 09:51:34 +02:00
|
|
|
?: context.attrColor(R.attr.colorSearchFormBackground)
|
|
|
|
|
|
|
|
llSearch.apply {
|
|
|
|
backgroundColor = searchBgColor
|
|
|
|
startPadding = dip(12)
|
|
|
|
endPadding = dip(12)
|
|
|
|
topPadding = dip(3)
|
|
|
|
bottomPadding = dip(3)
|
|
|
|
}
|
|
|
|
|
|
|
|
llListList.apply {
|
|
|
|
backgroundColor = searchBgColor
|
|
|
|
startPadding = dip(12)
|
|
|
|
endPadding = dip(12)
|
|
|
|
topPadding = dip(3)
|
|
|
|
bottomPadding = dip(3)
|
|
|
|
}
|
|
|
|
|
|
|
|
showColumnColor()
|
|
|
|
|
|
|
|
showContent(reason = "onPageCreate", reset = true)
|
|
|
|
} finally {
|
2021-06-20 15:12:25 +02:00
|
|
|
bindingBusy = false
|
2021-05-19 09:51:34 +02:00
|
|
|
}
|
|
|
|
}
|