- トレンドタグのソートはタンス側の内部パラメータに依存する

- トレンドタグに表示される数字を増やす
- トレンドタグのカラム設定に余計なものが表示されないようにする
This commit is contained in:
tateisu 2018-05-31 04:50:07 +09:00
parent 4d5173808f
commit 1d104e4009
9 changed files with 101 additions and 67 deletions

View File

@ -212,7 +212,7 @@ class Column(
TYPE_LIST_MEMBER -> context.getString(R.string.list_member)
TYPE_LIST_TL -> context.getString(R.string.list_timeline)
TYPE_DIRECT_MESSAGES -> context.getString(R.string.direct_messages)
TYPE_TREND_TAG ->context.getString(R.string.trend_tag)
TYPE_TREND_TAG -> context.getString(R.string.trend_tag)
else -> "?"
}
}
@ -1570,7 +1570,7 @@ class Column(
)
else -> {
if(who != null && access_info.isRemoteUser(who)) list_tmp.add(
TootMessageHolder(
context.getString(
@ -1578,7 +1578,7 @@ class Column(
)
)
)
if(src.isEmpty())
list_tmp.add(TootMessageHolder(emptyMessage))
}
@ -1882,17 +1882,19 @@ class Column(
return result
}
TYPE_TREND_TAG ->{
result = client.request( "/api/v1/trends" )
TYPE_TREND_TAG -> {
result = client.request("/api/v1/trends")
val src = parser.trendTagList(result?.jsonArray)
src.sortBy { - it.history.first().uses }
// Gargron によるとレスポンスは既にソートされているらしい
// src.sortWith(Comparator { a, b ->
// val i = b.history.first().uses.compareTo(a.history.first().uses)
// if(i != 0) i else a.name.compareTo(b.name)
// })
this.list_tmp = addAll(this.list_tmp, src)
return result
}
TYPE_SEARCH -> {
if(access_info.isPseudo) {
// 1.5.0rc からマストドンの検索APIは認証を要求するようになった
@ -1900,39 +1902,41 @@ class Column(
}
var instance = access_info.instance
if( instance == null ){
// まだ取得してない
val r2 = getInstanceInformation(client, null)
if(instance == null) {
getInstanceInformation(client, null)
if(instance_tmp != null) {
instance = instance_tmp
access_info.instance = instance
}
}
if( instance != null && instance.versionGE(TootInstance.VERSION_2_4_0) ){
if( instance != null && instance.versionGE(TootInstance.VERSION_2_4_0)) {
// v2 api を試す
var path = String.format(
Locale.JAPAN,
PATH_SEARCH_V2,
search_query.encodePercent()
)
Locale.JAPAN,
PATH_SEARCH_V2,
search_query.encodePercent()
)
if(search_resolve) path += "&resolve=1"
result = client.request(path)
val jsonObject = result?.jsonObject
if( jsonObject != null ){
if(jsonObject != null) {
val tmp = parser.resultsV2(jsonObject)
if(tmp != null) {
list_tmp = ArrayList()
addAll(list_tmp, tmp.hashtags)
addAll(list_tmp, tmp.accounts)
addAll(list_tmp, tmp.statuses)
return result
}
}
if( instance.versionGE(TootInstance.VERSION_2_4_1_rc1)){
// 2.4.1rc1以降はv2が確実に存在するはずなので、v1へのフォールバックを行わない
return result
}
}
var path =
String.format(
Locale.JAPAN,
@ -3520,10 +3524,10 @@ class Column(
fun canStatusFilter() : Boolean {
return when(column_type) {
TYPE_REPORTS, TYPE_MUTES, TYPE_BLOCKS, TYPE_DOMAIN_BLOCKS, TYPE_FOLLOW_REQUESTS,
TYPE_BOOSTED_BY, TYPE_FAVOURITED_BY, TYPE_INSTANCE_INFORMATION, TYPE_LIST_LIST, TYPE_LIST_MEMBER -> false
TYPE_BOOSTED_BY, TYPE_FAVOURITED_BY, TYPE_INSTANCE_INFORMATION, TYPE_LIST_LIST, TYPE_LIST_MEMBER,
TYPE_TREND_TAG -> false
else -> true
}
}
// カラム設定に「すべての画像を隠す」ボタンを含めるなら真
@ -3564,8 +3568,8 @@ class Column(
TYPE_SEARCH_MSP,
TYPE_SEARCH_TS,
TYPE_CONVERSATION,
TYPE_LIST_LIST ,
TYPE_TREND_TAG-> true
TYPE_LIST_LIST,
TYPE_TREND_TAG -> true
else -> false
}
}

View File

@ -403,9 +403,8 @@ internal class ItemViewHolder(
private fun showTrendTag(item : TootTrendTag) {
llTrendTag.visibility = View.VISIBLE
tvTrendTagName.text = "#${item.name}"
val latest = item.history.first()
tvTrendTagDesc.text = activity.getString(R.string.people_talking, latest.accounts)
tvTrendTagCount.text = latest.uses.toString()
tvTrendTagDesc.text = activity.getString(R.string.people_talking, item.accountDaily,item.accountWeekly)
tvTrendTagCount.text = "${item.countDaily}(${item.countWeekly})"
cvTrendTagHistory.setHistory(item.history)
}

View File

@ -321,6 +321,9 @@ object Pref {
val ipResizeImage = IntPref("resize_image", 4)
val ipRefreshAfterToot = IntPref("refresh_after_toot", 0)
const val RAT_REFRESH_SCROLL = 0
const val RAT_REFRESH_DONT_SCROLL = 1
const val RAT_DONT_REFRESH = 2
val ipFooterButtonBgColor = IntPref("footer_button_bg_color", 0)
val ipFooterButtonFgColor = IntPref("footer_button_fg_color", 0)
@ -329,10 +332,9 @@ object Pref {
val ipFooterTabIndicatorColor = IntPref("footer_tab_indicator_color", 0)
val ipLastColumnPos = IntPref("last_column_pos", - 1)
// ipRefreshAfterToot の値
const val RAT_REFRESH_SCROLL = 0
const val RAT_REFRESH_DONT_SCROLL = 1
const val RAT_DONT_REFRESH = 2
val ipTrendTagCountShowing = IntPref("TrendTagCountShowing", 0)
const val TTCS_WEEKLY = 0
const val TTCS_DAILY = 1
// string
val spColumnWidth = StringPref("ColumnWidth", "")

View File

@ -14,6 +14,7 @@ class TootInstance(parser : TootParser, src : JSONObject) {
val VERSION_2_4_0_rc1 = VersionString("2.4.0rc1")
val VERSION_2_4_0_rc2 = VersionString("2.4.0rc2")
val VERSION_2_4_0 = VersionString("2.4.0")
val VERSION_2_4_1_rc1 = VersionString("2.4.1rc1")
}

View File

@ -1,9 +1,8 @@
package jp.juggler.subwaytooter.api.entity
import jp.juggler.subwaytooter.util.LogCategory
import jp.juggler.subwaytooter.util.notEmptyOrThrow
import jp.juggler.subwaytooter.util.parseLong
import jp.juggler.subwaytooter.util.parseString
import jp.juggler.subwaytooter.App1
import jp.juggler.subwaytooter.Pref
import jp.juggler.subwaytooter.util.*
import org.json.JSONArray
import org.json.JSONObject
@ -13,17 +12,30 @@ class TootTrendTag(
val history : ArrayList<History>
) : TootTag(name, url) {
val countDaily :Int
val countWeekly :Int
val accountDaily: Int
val accountWeekly: Int
init{
countDaily = history.first().uses
countWeekly = history.sumBy { it.uses }
accountDaily = history.first().accounts
accountWeekly = history.map { it.accounts }.max() ?: accountDaily
}
class History(src : JSONObject) {
val day : Long
val uses : Long
val accounts : Long
val uses : Int
val accounts : Int
init {
day = src.parseLong("day")
?: throw RuntimeException("TootTrendTag.History: missing day")
uses = src.parseLong("uses")
uses = src.parseInt("uses")
?: throw RuntimeException("TootTrendTag.History: missing uses")
accounts = src.parseLong("accounts")
accounts = src.parseInt("accounts")
?: throw RuntimeException("TootTrendTag.History: missing accounts")
}

View File

@ -4,9 +4,10 @@ import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.animation.PathInterpolator
import jp.juggler.subwaytooter.api.entity.TootTrendTag
import jp.juggler.subwaytooter.util.clipRange
import kotlin.math.max
import kotlin.math.min
class TrendTagHistoryView : View {
@ -35,9 +36,10 @@ class TrendTagHistoryView : View {
private fun init() {
val density = context.resources.displayMetrics.density
this.lineWidth = 2f * density
this.lineWidth = 1f * density
paint.style = Paint.Style.STROKE
paint.strokeWidth = lineWidth
paint.isAntiAlias = true
}
fun setColor(c : Int) {
@ -50,11 +52,11 @@ class TrendTagHistoryView : View {
delta = 0f
values = null
} else {
var min = Long.MAX_VALUE
var max = Long.MIN_VALUE
var min = Int.MAX_VALUE
var max = Int.MIN_VALUE
for(h in history) {
min = Math.min(min, h.uses)
max = Math.max(max, h.uses)
min = min(min, h.uses)
max = max(max, h.uses)
}
val delta = (max - min).toFloat()
this.delta = delta
@ -84,39 +86,54 @@ class TrendTagHistoryView : View {
}
val size = values.size
val x_step = view_w / (size - 1).toFloat()
var x = 0f
path.reset()
var lastSlope = 0f
var lastY = 0f
var lastX = 0f
val controlXStep = x_step / 2f
val y_workarea = this.y_workarea ?: return
val y_min = lineWidth * 2f
val y_max = view_h - lineWidth * 2f
// 0..1 の値を描画範囲の上端と下端に変換する
val y_min = lineWidth
val y_max = view_h - lineWidth
val y_width = y_max - y_min
for(i in 0 until size) {
y_workarea[i] = (1f - values[i]) * y_width + y_min
}
// プロットするX位置の初期値と増分
var x = 0f
val x_step = view_w / (size - 1).toFloat()
// 制御点をどれだけ左右にずらすか
val controlXStep = x_step / 2f
// 前回の値
var lastSlope = 0f
var lastY = 0f
var lastX = 0f
path.reset()
for(i in 0 until size) {
val y = y_workarea[i]
when(i) {
// 始端
0 -> {
path.moveTo(x, y)
lastSlope = (y_workarea[i + 1] - y) / x_step
val nextY = y_workarea[i + 1]
lastSlope = (nextY - y) / x_step
}
// 終端
size - 1 -> {
// 制御点1
val c1x = lastX + controlXStep
val c1y = clipRange(y_min, y_max, lastY + controlXStep * lastSlope)
// 制御点2
val slope = (y - lastY) / x_step
val c2x = x - controlXStep
val c2y = y - controlXStep * slope
path.cubicTo(c1x, c1y, c2x, c2y, x, y)
}
// 中間
else -> {
// 制御点1
val c1x = lastX + controlXStep
@ -124,17 +141,16 @@ class TrendTagHistoryView : View {
// 制御点2
val nextY = y_workarea[i + 1]
val slope = if((y > lastY && y > nextY) || (y < lastY && y < nextY)) {
// 極値は傾き0とみなす
0f
} else if(y == lastY || y == nextY) {
// 左右のどちらかが平坦なら平坦とみなす
0f
} else {
// 前後で同じように勾配しているなら傾きは平均とする
val slope = if((lastY < y && y < nextY) || (lastY > y && y > nextY)) {
// 点の前後で勾配の符号が変わらず、平坦でもない
// 前後の勾配の平均を使う
val slope1 = (y - lastY) / x_step
val slope2 = (nextY - y) / x_step
(slope1 + slope2) / 2f
} else {
// 極値であるか、前後のどちらかが平坦であるなら
// オーバーランを防ぐため勾配は0とみなす
0f
}
val c2x = x - controlXStep
val c2y = clipRange(y_min, y_max, y - controlXStep * slope)

View File

@ -679,7 +679,7 @@
<string name="yourself_can_see_your_network">Even if you choose to hide social graphs, yourself can see it.</string>
<string name="follow_follower_list_may_restrict">If remote user chooses to hide the social graph, only the followings/followers on this instance will be displayed.</string>
<string name="trend_tag">Trending tags</string>
<string name="people_talking">%1$d people talking</string>
<string name="people_talking">%1$d(%2$d) people talking</string>
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>-->
<!--<string name="abc_action_bar_home_description_format">%1$s, %2$s</string>-->

View File

@ -957,6 +957,6 @@
<string name="yourself_can_see_your_network">もしあなたがソーシャルグラフを隠す選択をした場合でも、あなた自身はそれを見ることができます。</string>
<string name="follow_follower_list_may_restrict">もしリモートのユーザがソーシャルグラフを隠す選択をした場合、表示されるのはこのタンスのユーザだけです。</string>
<string name="trend_tag">トレンドタグ</string>
<string name="people_talking">%1$d人がトゥート</string>
<string name="people_talking">%1$d(%2$d)人がトゥート</string>
</resources>

View File

@ -664,5 +664,5 @@
<string name="yourself_can_see_your_network">Even if you choose to hide social graphs, yourself can see it.</string>
<string name="follow_follower_list_may_restrict">If remote user chooses to hide the social graph, only the followings/followers on this instance will be displayed.</string>
<string name="trend_tag">Trending tags</string>
<string name="people_talking">%1$d people talking</string>
<string name="people_talking">%1$d(%2$d) people talking</string>
</resources>