カラムの処理状況表示の改善
This commit is contained in:
parent
26888a79f4
commit
f080f36a1a
|
@ -22,19 +22,26 @@ import jp.juggler.subwaytooter.api.entity.*
|
|||
import jp.juggler.subwaytooter.table.*
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
|
||||
enum class TaskIndicatorState {
|
||||
NO_TASK,
|
||||
SCHEDULED,
|
||||
BG_START,
|
||||
BG_END,
|
||||
}
|
||||
|
||||
enum class StreamingIndicatorState {
|
||||
NONE,
|
||||
REGISTERED, // registered, but not listening
|
||||
LISTENING,
|
||||
}
|
||||
|
||||
enum class ColumnTaskType{
|
||||
LOADING,
|
||||
REFRESH_TOP,
|
||||
REFRESH_BOTTOM,
|
||||
GAP
|
||||
}
|
||||
abstract class ColumnTask(
|
||||
val ctType: ColumnTaskType
|
||||
) : AsyncTask<Void, Void, TootApiResult?>() {
|
||||
val ctStarted = AtomicBoolean(false)
|
||||
val ctClosed = AtomicBoolean(false)
|
||||
}
|
||||
|
||||
|
||||
class Column(
|
||||
val app_state : AppState,
|
||||
val context : Context,
|
||||
|
@ -352,7 +359,8 @@ class Column(
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private var last_task : AsyncTask<Void, Void, TootApiResult?>? = null
|
||||
|
||||
internal var lastTask : ColumnTask? = null
|
||||
|
||||
internal var bInitialLoading : Boolean = false
|
||||
internal var bRefreshLoading : Boolean = false
|
||||
|
@ -1086,17 +1094,13 @@ class Column(
|
|||
}
|
||||
|
||||
private fun cancelLastTask() {
|
||||
if(last_task != null) {
|
||||
last_task?.cancel(true)
|
||||
last_task = null
|
||||
if(lastTask != null) {
|
||||
lastTask?.cancel(true)
|
||||
lastTask = null
|
||||
//
|
||||
bInitialLoading = false
|
||||
bRefreshLoading = false
|
||||
mInitialLoadingError = context.getString(R.string.cancelled)
|
||||
//
|
||||
indicatorLoading = TaskIndicatorState.NO_TASK
|
||||
indicatorRefresh = TaskIndicatorState.NO_TASK
|
||||
indicatorGap = TaskIndicatorState.NO_TASK
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1396,10 +1400,6 @@ class Column(
|
|||
env.update(client)
|
||||
}
|
||||
|
||||
var indicatorLoading = TaskIndicatorState.NO_TASK
|
||||
var indicatorRefresh = TaskIndicatorState.NO_TASK
|
||||
var indicatorGap = TaskIndicatorState.NO_TASK
|
||||
|
||||
internal fun startLoading() {
|
||||
cancelLastTask()
|
||||
|
||||
|
@ -1414,14 +1414,13 @@ class Column(
|
|||
bRefreshLoading = false
|
||||
max_id = ""
|
||||
since_id = ""
|
||||
indicatorLoading = TaskIndicatorState.SCHEDULED
|
||||
|
||||
duplicate_map.clear()
|
||||
list_data.clear()
|
||||
fireShowContent(reason = "loading start", reset = true)
|
||||
|
||||
val task = @SuppressLint("StaticFieldLeak")
|
||||
object : AsyncTask<Void, Void, TootApiResult?>() {
|
||||
object : ColumnTask(ColumnTaskType.LOADING){
|
||||
internal var parser = TootParser(context, access_info, highlightTrie = highlight_trie)
|
||||
|
||||
internal var instance_tmp : TootInstance? = null
|
||||
|
@ -1637,7 +1636,7 @@ class Column(
|
|||
}
|
||||
|
||||
override fun doInBackground(vararg params : Void) : TootApiResult? {
|
||||
indicatorLoading = TaskIndicatorState.BG_START
|
||||
ctStarted.set(true)
|
||||
|
||||
val client = TootApiClient(context, callback = object : TootApiCallback {
|
||||
override val isApiCancelled : Boolean
|
||||
|
@ -1909,8 +1908,10 @@ class Column(
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
indicatorLoading = TaskIndicatorState.BG_END
|
||||
client.publishApiProgress("")
|
||||
ctClosed.set(true)
|
||||
runOnMainLooperDelayed(333L){
|
||||
if( !isCancelled ) fireShowColumnStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1925,39 +1926,34 @@ class Column(
|
|||
return
|
||||
}
|
||||
|
||||
try {
|
||||
bInitialLoading = false
|
||||
last_task = null
|
||||
|
||||
if(result.error != null) {
|
||||
this@Column.mInitialLoadingError = result.error ?: ""
|
||||
} else {
|
||||
duplicate_map.clear()
|
||||
list_data.clear()
|
||||
val list_tmp = this.list_tmp
|
||||
if(list_tmp != null) {
|
||||
val list_pinned = this.list_pinned
|
||||
if(list_pinned?.isNotEmpty() == true) {
|
||||
val list_new = duplicate_map.filterDuplicate(list_pinned)
|
||||
list_data.addAll(list_new)
|
||||
}
|
||||
val list_new = duplicate_map.filterDuplicate(list_tmp)
|
||||
bInitialLoading = false
|
||||
lastTask = null
|
||||
|
||||
if(result.error != null) {
|
||||
this@Column.mInitialLoadingError = result.error ?: ""
|
||||
} else {
|
||||
duplicate_map.clear()
|
||||
list_data.clear()
|
||||
val list_tmp = this.list_tmp
|
||||
if(list_tmp != null) {
|
||||
val list_pinned = this.list_pinned
|
||||
if(list_pinned?.isNotEmpty() == true) {
|
||||
val list_new = duplicate_map.filterDuplicate(list_pinned)
|
||||
list_data.addAll(list_new)
|
||||
}
|
||||
|
||||
resumeStreaming(false)
|
||||
val list_new = duplicate_map.filterDuplicate(list_tmp)
|
||||
list_data.addAll(list_new)
|
||||
}
|
||||
fireShowContent(reason = "loading updated", reset = true)
|
||||
|
||||
// 初期ロードの直後は先頭に移動する
|
||||
viewHolder?.scrollToTop()
|
||||
} finally {
|
||||
indicatorLoading = TaskIndicatorState.NO_TASK
|
||||
fireShowColumnStatus()
|
||||
resumeStreaming(false)
|
||||
}
|
||||
fireShowContent(reason = "loading updated", reset = true)
|
||||
|
||||
// 初期ロードの直後は先頭に移動する
|
||||
viewHolder?.scrollToTop()
|
||||
}
|
||||
}
|
||||
this.last_task = task
|
||||
this.lastTask = task
|
||||
task.executeOnExecutor(App1.task_executor)
|
||||
}
|
||||
// int scroll_hack;
|
||||
|
@ -2044,7 +2040,7 @@ class Column(
|
|||
refresh_after_toot : Int
|
||||
) {
|
||||
|
||||
if(last_task != null) {
|
||||
if(lastTask != null) {
|
||||
if(! bSilent) {
|
||||
showToast(context, true, R.string.column_is_busy)
|
||||
val holder = viewHolder
|
||||
|
@ -2079,11 +2075,12 @@ class Column(
|
|||
|
||||
bRefreshLoading = true
|
||||
mRefreshLoadingError = ""
|
||||
indicatorRefresh = TaskIndicatorState.SCHEDULED
|
||||
fireShowColumnStatus()
|
||||
|
||||
val task = @SuppressLint("StaticFieldLeak")
|
||||
object : AsyncTask<Void, Void, TootApiResult?>() {
|
||||
object : ColumnTask( when{
|
||||
bBottom -> ColumnTaskType.REFRESH_BOTTOM
|
||||
else->ColumnTaskType.REFRESH_TOP
|
||||
}){
|
||||
internal var parser = TootParser(context, access_info, highlightTrie = highlight_trie)
|
||||
|
||||
internal var list_tmp : ArrayList<TimelineItem>? = null
|
||||
|
@ -2580,7 +2577,7 @@ class Column(
|
|||
}
|
||||
|
||||
override fun doInBackground(vararg params : Void) : TootApiResult? {
|
||||
indicatorRefresh = TaskIndicatorState.BG_START
|
||||
ctStarted.set(true)
|
||||
|
||||
val client = TootApiClient(context, callback = object : TootApiCallback {
|
||||
override val isApiCancelled : Boolean
|
||||
|
@ -2739,8 +2736,10 @@ class Column(
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
indicatorRefresh = TaskIndicatorState.BG_END
|
||||
client.publishApiProgress("")
|
||||
ctClosed.set(true)
|
||||
runOnMainLooperDelayed(333L){
|
||||
if( !isCancelled ) fireShowColumnStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2755,7 +2754,7 @@ class Column(
|
|||
return
|
||||
}
|
||||
try {
|
||||
last_task = null
|
||||
lastTask = null
|
||||
bRefreshLoading = false
|
||||
|
||||
val error = result.error
|
||||
|
@ -2854,7 +2853,6 @@ class Column(
|
|||
}
|
||||
}
|
||||
} finally {
|
||||
indicatorRefresh = TaskIndicatorState.NO_TASK
|
||||
fireShowColumnStatus()
|
||||
|
||||
if(! bBottom) {
|
||||
|
@ -2864,8 +2862,9 @@ class Column(
|
|||
}
|
||||
}
|
||||
}
|
||||
this.last_task = task
|
||||
this.lastTask = task
|
||||
task.executeOnExecutor(App1.task_executor)
|
||||
fireShowColumnStatus()
|
||||
}
|
||||
|
||||
internal fun startGap(gap : TootGap?) {
|
||||
|
@ -2873,7 +2872,7 @@ class Column(
|
|||
showToast(context, true, "gap is null")
|
||||
return
|
||||
}
|
||||
if(last_task != null) {
|
||||
if(lastTask != null) {
|
||||
showToast(context, true, R.string.column_is_busy)
|
||||
return
|
||||
}
|
||||
|
@ -2882,11 +2881,9 @@ class Column(
|
|||
|
||||
bRefreshLoading = true
|
||||
mRefreshLoadingError = ""
|
||||
indicatorGap = TaskIndicatorState.SCHEDULED
|
||||
fireShowColumnStatus()
|
||||
|
||||
val task = @SuppressLint("StaticFieldLeak")
|
||||
object : AsyncTask<Void, Void, TootApiResult?>() {
|
||||
object : ColumnTask(ColumnTaskType.GAP){
|
||||
internal var max_id = gap.max_id
|
||||
internal val since_id = gap.since_id
|
||||
internal var list_tmp : ArrayList<TimelineItem>? = null
|
||||
|
@ -3109,7 +3106,7 @@ class Column(
|
|||
}
|
||||
|
||||
override fun doInBackground(vararg params : Void) : TootApiResult? {
|
||||
indicatorGap = TaskIndicatorState.BG_START
|
||||
ctStarted.set(true)
|
||||
|
||||
val client = TootApiClient(context, callback = object : TootApiCallback {
|
||||
override val isApiCancelled : Boolean
|
||||
|
@ -3192,8 +3189,11 @@ class Column(
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
indicatorGap = TaskIndicatorState.BG_END
|
||||
client.publishApiProgress("")
|
||||
|
||||
ctClosed.set(true)
|
||||
runOnMainLooperDelayed(333L){
|
||||
if( !isCancelled ) fireShowColumnStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3210,7 +3210,7 @@ class Column(
|
|||
|
||||
try {
|
||||
|
||||
last_task = null
|
||||
lastTask = null
|
||||
bRefreshLoading = false
|
||||
|
||||
val error = result.error
|
||||
|
@ -3285,14 +3285,13 @@ class Column(
|
|||
}
|
||||
}
|
||||
} finally {
|
||||
indicatorGap = TaskIndicatorState.NO_TASK
|
||||
fireShowColumnStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
this.last_task = task
|
||||
|
||||
this.lastTask = task
|
||||
task.executeOnExecutor(App1.task_executor)
|
||||
fireShowColumnStatus()
|
||||
}
|
||||
|
||||
enum class HeaderType(val viewType : Int) {
|
||||
|
|
|
@ -28,6 +28,9 @@ import jp.juggler.subwaytooter.table.AcctColor
|
|||
import android.support.v7.widget.ListRecyclerView
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
import jp.juggler.subwaytooter.view.ListDivider
|
||||
import java.io.Closeable
|
||||
|
@ -515,46 +518,40 @@ class ColumnViewHolder(
|
|||
|
||||
fun showColumnStatus() {
|
||||
val column = this.column
|
||||
val sb = StringBuilder()
|
||||
|
||||
val sb = SpannableStringBuilder()
|
||||
|
||||
|
||||
|
||||
try {
|
||||
if(column == null) {
|
||||
sb.append('?')
|
||||
} else {
|
||||
when(column.indicatorLoading) {
|
||||
TaskIndicatorState.NO_TASK -> {
|
||||
}
|
||||
|
||||
TaskIndicatorState.SCHEDULED -> sb.append("L?")
|
||||
TaskIndicatorState.BG_START -> sb.append("L")
|
||||
TaskIndicatorState.BG_END -> sb.append("L!")
|
||||
}
|
||||
val tb = if(column.bRefreshingTop) {
|
||||
'T'
|
||||
} else {
|
||||
'B'
|
||||
}
|
||||
when(column.indicatorRefresh) {
|
||||
TaskIndicatorState.NO_TASK -> {
|
||||
}
|
||||
|
||||
TaskIndicatorState.SCHEDULED -> sb.append("${tb}?")
|
||||
TaskIndicatorState.BG_START -> sb.append(tb)
|
||||
TaskIndicatorState.BG_END -> sb.append("${tb}!")
|
||||
}
|
||||
when(column.indicatorGap) {
|
||||
TaskIndicatorState.NO_TASK -> {
|
||||
}
|
||||
|
||||
TaskIndicatorState.SCHEDULED -> sb.append("G?")
|
||||
TaskIndicatorState.BG_START -> sb.append("G")
|
||||
TaskIndicatorState.BG_END -> sb.append("G!")
|
||||
val task = column.lastTask
|
||||
if( task != null){
|
||||
sb.append(when(task.ctType){
|
||||
ColumnTaskType.LOADING -> 'L'
|
||||
ColumnTaskType.REFRESH_TOP ->'T'
|
||||
ColumnTaskType.REFRESH_BOTTOM ->'B'
|
||||
ColumnTaskType.GAP->'G'
|
||||
})
|
||||
sb.append(when{
|
||||
task.isCancelled -> "~"
|
||||
task.ctClosed.get() -> "!"
|
||||
task.ctStarted.get() -> ""
|
||||
else-> "?"
|
||||
})
|
||||
}
|
||||
when(column.getStreamingStatus()) {
|
||||
StreamingIndicatorState.NONE -> {
|
||||
}
|
||||
|
||||
StreamingIndicatorState.REGISTERED -> sb.append("S?")
|
||||
StreamingIndicatorState.LISTENING -> sb.append("S")
|
||||
StreamingIndicatorState.REGISTERED ->{
|
||||
sb.appendColorShadeIcon(activity,R.drawable.ic_pulse,"Streaming")
|
||||
sb.append("?")
|
||||
}
|
||||
StreamingIndicatorState.LISTENING -> {
|
||||
sb.appendColorShadeIcon(activity,R.drawable.ic_pulse,"Streaming")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,6 +561,10 @@ class ColumnViewHolder(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fun showColumnColor() {
|
||||
val column = this.column
|
||||
|
||||
|
|
|
@ -259,3 +259,19 @@ object Styler {
|
|||
Math.min(lp.width, lp.height).toFloat() * round_ratio
|
||||
|
||||
}
|
||||
|
||||
fun SpannableStringBuilder.appendColorShadeIcon(
|
||||
context:Context,
|
||||
drawable_id:Int,
|
||||
text:String
|
||||
){
|
||||
val start = this.length
|
||||
this.append(text)
|
||||
val end = this.length
|
||||
this.setSpan(
|
||||
EmojiImageSpan(context, drawable_id,useColorShader=true),
|
||||
start,
|
||||
end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package jp.juggler.subwaytooter.span
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.support.annotation.IntRange
|
||||
import android.support.v4.content.ContextCompat
|
||||
|
@ -10,7 +10,11 @@ import android.text.style.ReplacementSpan
|
|||
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class EmojiImageSpan(context : Context, private val res_id : Int) : ReplacementSpan() {
|
||||
class EmojiImageSpan(
|
||||
context : Context,
|
||||
private val res_id : Int,
|
||||
private val useColorShader:Boolean = false
|
||||
) : ReplacementSpan() {
|
||||
|
||||
|
||||
companion object {
|
||||
|
@ -62,6 +66,9 @@ class EmojiImageSpan(context : Context, private val res_id : Int) : ReplacementS
|
|||
return size
|
||||
}
|
||||
|
||||
private var lastColor :Int? = null
|
||||
private var lastColorFilter: PorterDuffColorFilter? = null
|
||||
|
||||
override fun draw(
|
||||
canvas : Canvas,
|
||||
text : CharSequence,
|
||||
|
@ -82,7 +89,19 @@ class EmojiImageSpan(context : Context, private val res_id : Int) : ReplacementS
|
|||
canvas.save()
|
||||
canvas.translate(x, transY.toFloat())
|
||||
d.setBounds(0, 0, size, size)
|
||||
d.draw(canvas)
|
||||
|
||||
if( useColorShader && d is BitmapDrawable){
|
||||
if( paint.color != lastColor || lastColorFilter == null) {
|
||||
lastColor = paint.color
|
||||
lastColorFilter = PorterDuffColorFilter(paint.color, PorterDuff.Mode.SRC_ATOP)
|
||||
}
|
||||
val saveColorFilter = d.colorFilter
|
||||
d.colorFilter = lastColorFilter
|
||||
d.draw(canvas)
|
||||
d.colorFilter = saveColorFilter
|
||||
}else {
|
||||
d.draw(canvas)
|
||||
}
|
||||
canvas.restore()
|
||||
}
|
||||
|
||||
|
|
|
@ -693,6 +693,10 @@ fun runOnMainLooper(proc : () -> Unit) {
|
|||
Handler(looper).post { proc() }
|
||||
}
|
||||
}
|
||||
fun runOnMainLooperDelayed(delayMs:Long, proc : () -> Unit) {
|
||||
val looper = Looper.getMainLooper()
|
||||
Handler(looper).postDelayed({ proc() },delayMs)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// View
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 896 B |
Binary file not shown.
After Width: | Height: | Size: 651 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -111,7 +111,9 @@ my $res_dir = "app/src/main/res";
|
|||
#resize_scales( "_ArtWork/ic_list_tl_dark.png" ,$res_dir,"drawable","ic_list_tl_dark",0,32);
|
||||
#resize_scales( "_ArtWork/ic_list_member_dark.png" ,$res_dir,"drawable","ic_list_member_dark",0,32);
|
||||
|
||||
resize_scales( "_ArtWork/media_bg_dark.png" ,$res_dir,"drawable","media_bg_dark",0,24);
|
||||
#resize_scales( "_ArtWork/media_bg_dark.png" ,$res_dir,"drawable","media_bg_dark",0,24);
|
||||
|
||||
#resize_scales( "_ArtWork/v0.5.1/ic_launcher_foreground.png" ,$res_dir,"mipmap","ic_launcher_foreground",0,108);
|
||||
#resize_scales( "_ArtWork/v0.5.1/ic_launcher_background.png" ,$res_dir,"mipmap","ic_launcher_background",0,108);
|
||||
|
||||
resize_scales( "_ArtWork/ic_pulse.png" ,$res_dir,"drawable","ic_pulse",0,32);
|
||||
|
|
Loading…
Reference in New Issue