差分取得の並び順の修正、EntityIdの取り扱いのリファクタ
This commit is contained in:
parent
a320a91093
commit
4e6ae4a935
|
@ -2597,6 +2597,7 @@ class Column(
|
||||||
idMin is EntityIdString && ! isMisskey -> {
|
idMin is EntityIdString && ! isMisskey -> {
|
||||||
log.e("EntityId should be Long for non-misskey column! columnType=$column_type")
|
log.e("EntityId should be Long for non-misskey column! columnType=$column_type")
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val i = idOld?.compareTo(idMin)
|
val i = idOld?.compareTo(idMin)
|
||||||
if(i == null || i > 0) {
|
if(i == null || i > 0) {
|
||||||
|
@ -2815,7 +2816,6 @@ class Column(
|
||||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
@Suppress("NON_EXHAUSTIVE_WHEN")
|
||||||
when(pagingType) {
|
when(pagingType) {
|
||||||
PagingType.Default -> {
|
PagingType.Default -> {
|
||||||
if(isMisskey && ! bBottom) src.reverse()
|
|
||||||
saveRange(bBottom, ! bBottom, firstResult, src)
|
saveRange(bBottom, ! bBottom, firstResult, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2858,6 +2858,7 @@ class Column(
|
||||||
|
|
||||||
jsonObject = result?.jsonObject
|
jsonObject = result?.jsonObject
|
||||||
if(jsonObject != null) {
|
if(jsonObject != null) {
|
||||||
|
// pagingType is always default.
|
||||||
result !!.data = misskeyArrayFinder(jsonObject)
|
result !!.data = misskeyArrayFinder(jsonObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2869,12 +2870,19 @@ class Column(
|
||||||
}
|
}
|
||||||
|
|
||||||
src = misskeyCustomParser(parser, array)
|
src = misskeyCustomParser(parser, array)
|
||||||
src.reverse()
|
|
||||||
|
|
||||||
addAll(list_tmp, src)
|
addAll(list_tmp, src)
|
||||||
|
|
||||||
|
// pagingType is always default.
|
||||||
saveRange(false, true, result, src)
|
saveRange(false, true, result, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pagingType is always default.
|
||||||
|
if(isMisskey && ! bBottom){
|
||||||
|
list_tmp?.sortBy{ it.getOrderId() }
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
if(! isCancelled
|
if(! isCancelled
|
||||||
&& list_tmp?.isNotEmpty() == true
|
&& list_tmp?.isNotEmpty() == true
|
||||||
&& (bHeadGap || Pref.bpForceGap(context))
|
&& (bHeadGap || Pref.bpForceGap(context))
|
||||||
|
@ -3120,7 +3128,6 @@ class Column(
|
||||||
var jsonArray = result?.jsonArray
|
var jsonArray = result?.jsonArray
|
||||||
if(jsonArray != null) {
|
if(jsonArray != null) {
|
||||||
var src = parser.notificationList(jsonArray)
|
var src = parser.notificationList(jsonArray)
|
||||||
if(isMisskey && ! bBottom) src.reverse()
|
|
||||||
|
|
||||||
list_tmp = addWithFilterNotification(null, src)
|
list_tmp = addWithFilterNotification(null, src)
|
||||||
saveRange(bBottom, ! bBottom, result, src)
|
saveRange(bBottom, ! bBottom, result, src)
|
||||||
|
@ -3169,7 +3176,6 @@ class Column(
|
||||||
}
|
}
|
||||||
|
|
||||||
src = parser.notificationList(jsonArray)
|
src = parser.notificationList(jsonArray)
|
||||||
src.reverse()
|
|
||||||
|
|
||||||
saveRange(false, true, result, src)
|
saveRange(false, true, result, src)
|
||||||
if(! src.isEmpty()) {
|
if(! src.isEmpty()) {
|
||||||
|
@ -3178,6 +3184,11 @@ class Column(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isMisskey && ! bBottom){
|
||||||
|
list_tmp?.sortBy{it.getOrderId()}
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
if(! isCancelled
|
if(! isCancelled
|
||||||
&& list_tmp?.isNotEmpty() == true
|
&& list_tmp?.isNotEmpty() == true
|
||||||
&& (bHeadGap || Pref.bpForceGap(context))
|
&& (bHeadGap || Pref.bpForceGap(context))
|
||||||
|
@ -3300,8 +3311,7 @@ class Column(
|
||||||
fun getStatusList(
|
fun getStatusList(
|
||||||
client : TootApiClient,
|
client : TootApiClient,
|
||||||
path_base : String,
|
path_base : String,
|
||||||
misskeyParams : JSONObject? = null
|
misskeyParams : JSONObject? = null,
|
||||||
,
|
|
||||||
misskeyCustomParser : (parser : TootParser, jsonArray : JSONArray) -> ArrayList<TootStatus> =
|
misskeyCustomParser : (parser : TootParser, jsonArray : JSONArray) -> ArrayList<TootStatus> =
|
||||||
{ parser, jsonArray -> parser.statusList(jsonArray) }
|
{ parser, jsonArray -> parser.statusList(jsonArray) }
|
||||||
) : TootApiResult? {
|
) : TootApiResult? {
|
||||||
|
@ -3326,7 +3336,7 @@ class Column(
|
||||||
val jsonArray = result?.jsonArray
|
val jsonArray = result?.jsonArray
|
||||||
if(jsonArray != null) {
|
if(jsonArray != null) {
|
||||||
var src = misskeyCustomParser(parser, jsonArray)
|
var src = misskeyCustomParser(parser, jsonArray)
|
||||||
if(isMisskey && ! bBottom) src.reverse()
|
|
||||||
saveRange(bBottom, ! bBottom, result, src)
|
saveRange(bBottom, ! bBottom, result, src)
|
||||||
list_tmp = addWithFilterStatus(null, src)
|
list_tmp = addWithFilterStatus(null, src)
|
||||||
|
|
||||||
|
@ -3349,7 +3359,7 @@ class Column(
|
||||||
}
|
}
|
||||||
|
|
||||||
if((list_tmp?.size ?: 0) >= LOOP_READ_ENOUGH) {
|
if((list_tmp?.size ?: 0) >= LOOP_READ_ENOUGH) {
|
||||||
log.d("refresh-status-offset: read enough. make gap.")
|
log.d("refresh-status-top: read enough. make gap.")
|
||||||
bHeadGap = true
|
bHeadGap = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -3372,13 +3382,17 @@ class Column(
|
||||||
}
|
}
|
||||||
|
|
||||||
src = misskeyCustomParser(parser, jsonArray2)
|
src = misskeyCustomParser(parser, jsonArray2)
|
||||||
src.reverse()
|
|
||||||
|
|
||||||
saveRange(false, true, result, src)
|
saveRange(false, true, result, src)
|
||||||
|
|
||||||
addWithFilterStatus(list_tmp, src)
|
addWithFilterStatus(list_tmp, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isMisskey && ! bBottom ){
|
||||||
|
list_tmp?.sortBy { it.getOrderId() }
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
if(! isCancelled
|
if(! isCancelled
|
||||||
&& list_tmp?.isNotEmpty() == true
|
&& list_tmp?.isNotEmpty() == true
|
||||||
&& (bHeadGap || Pref.bpForceGap(context))
|
&& (bHeadGap || Pref.bpForceGap(context))
|
||||||
|
@ -3438,7 +3452,6 @@ class Column(
|
||||||
}
|
}
|
||||||
|
|
||||||
src = misskeyCustomParser(parser, jsonArray2)
|
src = misskeyCustomParser(parser, jsonArray2)
|
||||||
|
|
||||||
addWithFilterStatus(list_tmp, src)
|
addWithFilterStatus(list_tmp, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3495,7 +3508,6 @@ class Column(
|
||||||
}
|
}
|
||||||
|
|
||||||
src = misskeyCustomParser(parser, jsonArray2)
|
src = misskeyCustomParser(parser, jsonArray2)
|
||||||
|
|
||||||
addWithFilterStatus(list_tmp, src)
|
addWithFilterStatus(list_tmp, src)
|
||||||
|
|
||||||
if(! saveRangeEnd(result, src)) {
|
if(! saveRangeEnd(result, src)) {
|
||||||
|
@ -4001,7 +4013,6 @@ class Column(
|
||||||
result = r2
|
result = r2
|
||||||
|
|
||||||
val src = misskeyCustomParser(parser, jsonArray)
|
val src = misskeyCustomParser(parser, jsonArray)
|
||||||
src.reverse()
|
|
||||||
if(src.isEmpty()) {
|
if(src.isEmpty()) {
|
||||||
log.d("gap-account: empty.")
|
log.d("gap-account: empty.")
|
||||||
break
|
break
|
||||||
|
@ -4010,6 +4021,10 @@ class Column(
|
||||||
addAll(list_tmp, src)
|
addAll(list_tmp, src)
|
||||||
since_id = parseRange(result, src).second
|
since_id = parseRange(result, src).second
|
||||||
}
|
}
|
||||||
|
if(isMisskey ){
|
||||||
|
list_tmp?.sortBy{it.getOrderId()}
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
if(bHeadGap) {
|
if(bHeadGap) {
|
||||||
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
||||||
}
|
}
|
||||||
|
@ -4099,13 +4114,20 @@ class Column(
|
||||||
log.d("gap-report: empty.")
|
log.d("gap-report: empty.")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
src.reverse()
|
|
||||||
|
|
||||||
addAll(list_tmp, src)
|
addAll(list_tmp, src)
|
||||||
|
|
||||||
// 隙間の最新のステータスIDは取得データ末尾のステータスIDである
|
// 隙間の最新のステータスIDは取得データ末尾のステータスIDである
|
||||||
since_id = parseRange(result, src).second
|
since_id = parseRange(result, src).second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// レポート一覧ってそもそもMisskey対応してないので、ここをどうするかは不明
|
||||||
|
// 多分 sinceIDによるページングではないと思う
|
||||||
|
if(isMisskey ){
|
||||||
|
list_tmp?.sortBy{it.getOrderId()}
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
if(bHeadGap) {
|
if(bHeadGap) {
|
||||||
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
||||||
}
|
}
|
||||||
|
@ -4196,7 +4218,6 @@ class Column(
|
||||||
log.d("gap-notification: empty.")
|
log.d("gap-notification: empty.")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
src.reverse()
|
|
||||||
|
|
||||||
// 隙間の最新のステータスIDは取得データ末尾のステータスIDである
|
// 隙間の最新のステータスIDは取得データ末尾のステータスIDである
|
||||||
since_id = parseRange(result, src).second
|
since_id = parseRange(result, src).second
|
||||||
|
@ -4206,6 +4227,11 @@ class Column(
|
||||||
PollingWorker.injectData(context, access_info, src)
|
PollingWorker.injectData(context, access_info, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isMisskey ){
|
||||||
|
list_tmp?.sortBy{it.getOrderId()}
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
if(bHeadGap) {
|
if(bHeadGap) {
|
||||||
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
||||||
}
|
}
|
||||||
|
@ -4318,7 +4344,7 @@ class Column(
|
||||||
log.d("gap-statuses: empty.")
|
log.d("gap-statuses: empty.")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
src.reverse()
|
|
||||||
|
|
||||||
// 隙間の最新のステータスIDは取得データ末尾のステータスIDである
|
// 隙間の最新のステータスIDは取得データ末尾のステータスIDである
|
||||||
since_id = parseRange(result, src).second
|
since_id = parseRange(result, src).second
|
||||||
|
@ -4326,6 +4352,11 @@ class Column(
|
||||||
addWithFilterStatus(list_tmp, src)
|
addWithFilterStatus(list_tmp, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isMisskey ){
|
||||||
|
list_tmp?.sortBy { it.getOrderId() }
|
||||||
|
list_tmp?.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
if(bHeadGap) {
|
if(bHeadGap) {
|
||||||
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
addOneFirst(list_tmp, TootGap.mayNull(max_id, since_id))
|
||||||
}
|
}
|
||||||
|
@ -4990,15 +5021,14 @@ class Column(
|
||||||
return app_state.stream_reader.getStreamingStatus(access_info, stream_path, streamCallback)
|
return app_state.stream_reader.getStreamingStatus(access_info, stream_path, streamCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val mergeStreamingMessage : Runnable = object : Runnable {
|
||||||
private val mergeStreamingMessage :Runnable = object : Runnable {
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
|
|
||||||
// 前回マージしてから暫くは待機する
|
// 前回マージしてから暫くは待機する
|
||||||
val handler =App1.getAppState(context).handler
|
val handler = App1.getAppState(context).handler
|
||||||
val now = SystemClock.elapsedRealtime()
|
val now = SystemClock.elapsedRealtime()
|
||||||
val remain = last_show_stream_data.get() + 333L - now
|
val remain = last_show_stream_data.get() + 333L - now
|
||||||
if( remain > 0) {
|
if(remain > 0) {
|
||||||
handler.removeCallbacks(this)
|
handler.removeCallbacks(this)
|
||||||
handler.postDelayed(this, remain)
|
handler.postDelayed(this, remain)
|
||||||
return
|
return
|
||||||
|
@ -5006,7 +5036,7 @@ class Column(
|
||||||
last_show_stream_data.set(now)
|
last_show_stream_data.set(now)
|
||||||
|
|
||||||
val tmpList = ArrayList<TimelineItem>()
|
val tmpList = ArrayList<TimelineItem>()
|
||||||
while(stream_data_queue.isNotEmpty() ){
|
while(stream_data_queue.isNotEmpty()) {
|
||||||
tmpList.add(stream_data_queue.poll())
|
tmpList.add(stream_data_queue.poll())
|
||||||
}
|
}
|
||||||
if(tmpList.isEmpty()) return
|
if(tmpList.isEmpty()) return
|
||||||
|
@ -5017,8 +5047,8 @@ class Column(
|
||||||
val list_new = duplicate_map.filterDuplicate(tmpList)
|
val list_new = duplicate_map.filterDuplicate(tmpList)
|
||||||
if(list_new.isEmpty()) return
|
if(list_new.isEmpty()) return
|
||||||
|
|
||||||
for( item in list_new){
|
for(item in list_new) {
|
||||||
if( enable_speech && item is TootStatus ){
|
if(enable_speech && item is TootStatus) {
|
||||||
App1.getAppState(context).addSpeech(item.reblog ?: item)
|
App1.getAppState(context).addSpeech(item.reblog ?: item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5055,13 +5085,13 @@ class Column(
|
||||||
val tmpRecent = idRecent
|
val tmpRecent = idRecent
|
||||||
val tmpNewMax = new_id_max
|
val tmpNewMax = new_id_max
|
||||||
|
|
||||||
if(tmpNewMax is EntityIdString && !isMisskey ){
|
if(tmpNewMax is EntityIdString && ! isMisskey) {
|
||||||
log.e("EntityId should be Long for non-misskey column! columnType=$column_type")
|
log.e("EntityId should be Long for non-misskey column! columnType=$column_type")
|
||||||
}else if( tmpRecent is EntityIdString && tmpNewMax is EntityIdLong){
|
} else if(tmpRecent is EntityIdString && tmpNewMax is EntityIdLong) {
|
||||||
log.e("EntityId type mismatch! recent=String,newMax=Long,columnType=$column_type")
|
log.e("EntityId type mismatch! recent=String,newMax=Long,columnType=$column_type")
|
||||||
}else if( tmpRecent is EntityIdLong && tmpNewMax is EntityIdString){
|
} else if(tmpRecent is EntityIdLong && tmpNewMax is EntityIdString) {
|
||||||
log.e("EntityId type mismatch! recent=Long,newMax=String,columnType=$column_type")
|
log.e("EntityId type mismatch! recent=Long,newMax=String,columnType=$column_type")
|
||||||
}else if(tmpNewMax != null && (tmpRecent?.compareTo(tmpNewMax) ?: - 1) == - 1 ) {
|
} else if(tmpNewMax != null && (tmpRecent?.compareTo(tmpNewMax) ?: - 1) == - 1) {
|
||||||
idRecent = tmpNewMax
|
idRecent = tmpNewMax
|
||||||
// XXX: コレはリフレッシュ時に取得漏れを引き起こすのでは…?
|
// XXX: コレはリフレッシュ時に取得漏れを引き起こすのでは…?
|
||||||
// しかしコレなしだとリフレッシュ時に大量に読むことになる…
|
// しかしコレなしだとリフレッシュ時に大量に読むことになる…
|
||||||
|
|
|
@ -1,65 +1,49 @@
|
||||||
package jp.juggler.subwaytooter.api
|
package jp.juggler.subwaytooter.api
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.Timeline
|
||||||
import jp.juggler.subwaytooter.api.entity.*
|
import jp.juggler.subwaytooter.api.entity.*
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
|
|
||||||
class DuplicateMap {
|
class DuplicateMap {
|
||||||
|
|
||||||
private val set_status_id = HashSet<EntityId>()
|
private val set_id = HashSet<EntityId>()
|
||||||
private val set_notification_id = HashSet<EntityId>()
|
private val set_uri = HashSet<String>()
|
||||||
private val set_report_id = HashSet<EntityId>()
|
|
||||||
private val set_account_id = HashSet<EntityId>()
|
|
||||||
private val set_status_uri = HashSet<String>()
|
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
set_status_id.clear()
|
set_id.clear()
|
||||||
set_notification_id.clear()
|
set_uri.clear()
|
||||||
set_report_id.clear()
|
|
||||||
set_account_id.clear()
|
|
||||||
set_status_uri.clear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isDuplicate(o : TimelineItem) : Boolean {
|
fun isDuplicate(o : TimelineItem) : Boolean {
|
||||||
|
|
||||||
when(o) {
|
if(o is TootStatus) {
|
||||||
|
val uri = o.uri
|
||||||
|
val url = o.url
|
||||||
|
when {
|
||||||
|
uri?.isNotEmpty() == true -> {
|
||||||
|
if(set_uri.contains(uri)) return true
|
||||||
|
set_uri.add(uri)
|
||||||
|
}
|
||||||
|
|
||||||
is TootStatus ->{
|
url?.isNotEmpty() == true -> {
|
||||||
val uri = o.uri
|
// URIとURLで同じマップを使いまわすが、害はないと思う…
|
||||||
val url = o.url
|
if(set_uri.contains(url)) return true
|
||||||
when {
|
set_uri.add(url)
|
||||||
uri?.isNotEmpty() == true -> {
|
|
||||||
if(set_status_uri.contains(uri)) return true
|
|
||||||
set_status_uri.add(uri)
|
|
||||||
}
|
|
||||||
url?.isNotEmpty() == true -> {
|
|
||||||
// URIとURLで同じマップを使いまわすが、害はないと思う…
|
|
||||||
if(set_status_uri.contains(url)) return true
|
|
||||||
set_status_uri.add(url)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if(set_status_id.contains(o.id)) return true
|
|
||||||
set_status_id.add(o.id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when(o) {
|
||||||
|
is TootReport,
|
||||||
|
is TootStatus,
|
||||||
|
is TootAccount,
|
||||||
is TootNotification -> {
|
is TootNotification -> {
|
||||||
if(set_notification_id.contains(o.id)) return true
|
val id = o.getOrderId()
|
||||||
set_notification_id.add(o.id)
|
if(id.notDefault){
|
||||||
|
if(set_id.contains(o.getOrderId())) return true
|
||||||
}
|
set_id.add(o.getOrderId())
|
||||||
|
}
|
||||||
is TootReport -> {
|
|
||||||
if(set_report_id.contains(o.id)) return true
|
|
||||||
set_report_id.add(o.id)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
is TootAccountRef -> {
|
|
||||||
val id = o.get().id
|
|
||||||
if(set_account_id.contains(id)) return true
|
|
||||||
set_account_id.add(id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +52,7 @@ class DuplicateMap {
|
||||||
|
|
||||||
fun filterDuplicate(src : Collection<TimelineItem>?) : ArrayList<TimelineItem> {
|
fun filterDuplicate(src : Collection<TimelineItem>?) : ArrayList<TimelineItem> {
|
||||||
val list_new = ArrayList<TimelineItem>()
|
val list_new = ArrayList<TimelineItem>()
|
||||||
if( src != null ) {
|
if(src != null) {
|
||||||
for(o in src) {
|
for(o in src) {
|
||||||
if(isDuplicate(o)) continue
|
if(isDuplicate(o)) continue
|
||||||
list_new.add(o)
|
list_new.add(o)
|
||||||
|
|
|
@ -10,18 +10,26 @@ abstract class EntityId : Comparable<EntityId> {
|
||||||
abstract fun putMisskeyUntil(dst : JSONObject) : JSONObject
|
abstract fun putMisskeyUntil(dst : JSONObject) : JSONObject
|
||||||
abstract fun putMisskeySince(dst : JSONObject) : JSONObject
|
abstract fun putMisskeySince(dst : JSONObject) : JSONObject
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun from(x : Long) = EntityIdLong(x)
|
val defaultLong = EntityIdLong(TootStatus.INVALID_ID)
|
||||||
|
val defaultString = EntityIdString("")
|
||||||
|
|
||||||
|
fun mayDefault(x : Long?) = when(x) {
|
||||||
|
null -> defaultLong
|
||||||
|
else -> EntityIdLong(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mayDefault(x : String?) = when(x) {
|
||||||
|
null -> defaultString
|
||||||
|
else -> EntityIdString(x)
|
||||||
|
}
|
||||||
|
|
||||||
fun mayNull(x : Long?) = when(x) {
|
fun mayNull(x : Long?) = when(x) {
|
||||||
null -> null
|
null -> null
|
||||||
else -> EntityIdLong(x)
|
else -> EntityIdLong(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun from(x : String) = EntityIdString(x)
|
|
||||||
|
|
||||||
fun mayNull(x : String?) = when(x) {
|
fun mayNull(x : String?) = when(x) {
|
||||||
null -> null
|
null -> null
|
||||||
else -> EntityIdString(x)
|
else -> EntityIdString(x)
|
||||||
|
@ -29,8 +37,8 @@ abstract class EntityId : Comparable<EntityId> {
|
||||||
|
|
||||||
fun String.decode():EntityId?{
|
fun String.decode():EntityId?{
|
||||||
if(this.isEmpty()) return null
|
if(this.isEmpty()) return null
|
||||||
if(this[0]=='L') return from(this.substring(1).toLong())
|
if(this[0]=='L') return EntityIdLong(this.substring(1).toLong())
|
||||||
if(this[0]=='S') return from(this.substring(1))
|
if(this[0]=='S') return EntityIdString(this.substring(1))
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +70,8 @@ abstract class EntityId : Comparable<EntityId> {
|
||||||
|
|
||||||
fun putTo(data:JSONObject, key : String):JSONObject = data.put( key,encode())
|
fun putTo(data:JSONObject, key : String):JSONObject = data.put( key,encode())
|
||||||
|
|
||||||
|
val notDefault :Boolean
|
||||||
|
get()= !(this == defaultLong || this== defaultString)
|
||||||
}
|
}
|
||||||
|
|
||||||
class EntityIdLong(val x : Long) : EntityId() {
|
class EntityIdLong(val x : Long) : EntityId() {
|
||||||
|
|
|
@ -10,14 +10,14 @@ class NicoProfileEmoji(
|
||||||
val url : String,
|
val url : String,
|
||||||
private val shortcode : String,
|
private val shortcode : String,
|
||||||
@Suppress("unused") private val account_url : String?,
|
@Suppress("unused") private val account_url : String?,
|
||||||
@Suppress("unused") private val account_id : EntityId?
|
@Suppress("unused") private val account_id : EntityId
|
||||||
) : Mappable<String> {
|
) : Mappable<String> {
|
||||||
|
|
||||||
constructor(src : JSONObject) : this(
|
constructor(src : JSONObject) : this(
|
||||||
url = src.notEmptyOrThrow("url"),
|
url = src.notEmptyOrThrow("url"),
|
||||||
shortcode = src.notEmptyOrThrow("shortcode"),
|
shortcode = src.notEmptyOrThrow("shortcode"),
|
||||||
account_url = src.parseString("account_url"),
|
account_url = src.parseString("account_url"),
|
||||||
account_id = EntityId.mayNull( src.parseLong("account_id") )
|
account_id = EntityId.mayDefault( src.parseLong("account_id") )
|
||||||
)
|
)
|
||||||
|
|
||||||
override val mapKey : String
|
override val mapKey : String
|
||||||
|
|
|
@ -7,7 +7,6 @@ open class TimelineItem{
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val listViewItemIdSeed = AtomicLong(3) // ヘッダ用にいくつか空けておく
|
val listViewItemIdSeed = AtomicLong(3) // ヘッダ用にいくつか空けておく
|
||||||
val defaultOrderId = EntityIdLong(TootStatus.INVALID_ID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdapterView用のIDを採番する
|
// AdapterView用のIDを採番する
|
||||||
|
@ -15,5 +14,5 @@ open class TimelineItem{
|
||||||
|
|
||||||
// 大小比較のためのIDを取得する
|
// 大小比較のためのIDを取得する
|
||||||
// 比較が不要な場合は0Lを返す
|
// 比較が不要な場合は0Lを返す
|
||||||
open fun getOrderId() :EntityId = defaultOrderId
|
open fun getOrderId() :EntityId = EntityId.defaultLong
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
||||||
|
|
||||||
// this.user_hides_network = src.optBoolean("user_hides_network")
|
// this.user_hides_network = src.optBoolean("user_hides_network")
|
||||||
|
|
||||||
this.id = EntityId.mayNull(src.parseString("id")) ?: error("missing id")
|
this.id = EntityId.mayDefault(src.parseString("id"))
|
||||||
|
|
||||||
this.host = instance
|
this.host = instance
|
||||||
this.acct = when {
|
this.acct = when {
|
||||||
|
@ -193,7 +193,7 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
||||||
|
|
||||||
val hostAccess = parser.linkHelper.host
|
val hostAccess = parser.linkHelper.host
|
||||||
|
|
||||||
this.id = EntityId.from(src.parseLong("id") ?: INVALID_ID)
|
this.id = EntityId.mayDefault(src.parseLong("id"))
|
||||||
|
|
||||||
this.acct = src.notEmptyOrThrow("acct")
|
this.acct = src.notEmptyOrThrow("acct")
|
||||||
this.host = findHostFromUrl(acct, hostAccess, url)
|
this.host = findHostFromUrl(acct, hostAccess, url)
|
||||||
|
@ -215,7 +215,7 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
||||||
|
|
||||||
ServiceType.TOOTSEARCH -> {
|
ServiceType.TOOTSEARCH -> {
|
||||||
// tootsearch のアカウントのIDはどのタンス上のものか分からないので役に立たない
|
// tootsearch のアカウントのIDはどのタンス上のものか分からないので役に立たない
|
||||||
this.id = EntityId.from(INVALID_ID) // src.parseLong( "id", INVALID_ID)
|
this.id = EntityId.defaultLong
|
||||||
|
|
||||||
sv = src.notEmptyOrThrow("acct")
|
sv = src.notEmptyOrThrow("acct")
|
||||||
this.host = findHostFromUrl(sv, null, url)
|
this.host = findHostFromUrl(sv, null, url)
|
||||||
|
@ -236,7 +236,7 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceType.MSP -> {
|
ServiceType.MSP -> {
|
||||||
this.id = EntityId.from(src.parseLong("id") ?: INVALID_ID)
|
this.id = EntityId.mayDefault(src.parseLong("id") )
|
||||||
|
|
||||||
// MSPはLTLの情報しか持ってないのでacctは常にホスト名部分を持たない
|
// MSPはLTLの情報しか持ってないのでacctは常にホスト名部分を持たない
|
||||||
this.host = findHostFromUrl(null, null, url)
|
this.host = findHostFromUrl(null, null, url)
|
||||||
|
@ -304,8 +304,6 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LogCategory("TootAccount")
|
private val log = LogCategory("TootAccount")
|
||||||
|
|
||||||
const val INVALID_ID = - 1L
|
|
||||||
|
|
||||||
@Suppress("HasPlatformType")
|
@Suppress("HasPlatformType")
|
||||||
private val reWhitespace = Pattern.compile("[\\s\\t\\x0d\\x0a]+")
|
private val reWhitespace = Pattern.compile("[\\s\\t\\x0d\\x0a]+")
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class TootAttachment(serviceType:ServiceType,src : JSONObject) : TootAttachmentL
|
||||||
|
|
||||||
when(serviceType) {
|
when(serviceType) {
|
||||||
ServiceType.MISSKEY -> {
|
ServiceType.MISSKEY -> {
|
||||||
id = EntityId.from( src.parseString("id") ?: error("missing id"))
|
id = EntityId.mayDefault( src.parseString("id"))
|
||||||
|
|
||||||
val mimeType = src.parseString("type") ?: "?"
|
val mimeType = src.parseString("type") ?: "?"
|
||||||
this.type = when{
|
this.type = when{
|
||||||
|
@ -88,7 +88,7 @@ class TootAttachment(serviceType:ServiceType,src : JSONObject) : TootAttachmentL
|
||||||
isSensitive = src.optBoolean("isSensitive",false)
|
isSensitive = src.optBoolean("isSensitive",false)
|
||||||
}
|
}
|
||||||
else->{
|
else->{
|
||||||
id= EntityIdLong(src.parseLong("id") ?: - 1L)
|
id= EntityId.mayDefault(src.parseLong("id") )
|
||||||
type = src.parseString("type")
|
type = src.parseString("type")
|
||||||
url = src.parseString("url")
|
url = src.parseString("url")
|
||||||
remote_url = src.parseString("remote_url")
|
remote_url = src.parseString("remote_url")
|
||||||
|
|
|
@ -69,7 +69,7 @@ class TootFilter( src: JSONObject) :TimelineItem() {
|
||||||
val whole_word : Boolean
|
val whole_word : Boolean
|
||||||
|
|
||||||
init{
|
init{
|
||||||
id = EntityId.mayNull(src.parseLong("id") ) ?: error("missing id")
|
id = EntityId.mayDefault(src.parseLong("id") )
|
||||||
phrase = src.parseString("phrase")?: error("missing phrase")
|
phrase = src.parseString("phrase")?: error("missing phrase")
|
||||||
context = parseFilterContext(src.optJSONArray("context"))
|
context = parseFilterContext(src.optJSONArray("context"))
|
||||||
expires_at = src.parseString("expires_at") // may null
|
expires_at = src.parseString("expires_at") // may null
|
||||||
|
|
|
@ -45,24 +45,14 @@ class TootNotification(parser : TootParser, src : JSONObject) : TimelineItem() {
|
||||||
val account : TootAccount?
|
val account : TootAccount?
|
||||||
get() = accountRef?.get()
|
get() = accountRef?.get()
|
||||||
|
|
||||||
override fun getOrderId() = id
|
private val _orderId :EntityId
|
||||||
|
override fun getOrderId() = _orderId
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
json = src
|
json = src
|
||||||
|
|
||||||
if( parser.serviceType == ServiceType.MISSKEY){
|
if( parser.serviceType == ServiceType.MISSKEY){
|
||||||
id = when {
|
id = EntityId.mayDefault(src.parseString("id"))
|
||||||
|
|
||||||
// Misskeyはストリーミングからくる通知にIDが振られていない
|
|
||||||
parser.serviceType == ServiceType.MISSKEY ->
|
|
||||||
EntityId.mayNull(src.parseString("id")) ?: EntityIdString("")
|
|
||||||
|
|
||||||
// Mastodon
|
|
||||||
else -> EntityId.mayNull(src.parseLong("id")) ?: error("missing id")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type = src.notEmptyOrThrow("type")
|
type = src.notEmptyOrThrow("type")
|
||||||
|
|
||||||
|
@ -73,11 +63,14 @@ class TootNotification(parser : TootParser, src : JSONObject) : TimelineItem() {
|
||||||
status = parser.status(src.optJSONObject("note"))
|
status = parser.status(src.optJSONObject("note"))
|
||||||
|
|
||||||
reaction = src.parseString("reaction")
|
reaction = src.parseString("reaction")
|
||||||
|
|
||||||
|
|
||||||
|
// Misskeyの通知APIはページネーションをIDでしか行えない
|
||||||
|
// これは改善される予定 https://github.com/syuilo/misskey/issues/2275
|
||||||
|
_orderId = id
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
id = when {
|
id = EntityId.mayDefault(src.parseLong("id"))
|
||||||
parser.serviceType == ServiceType.MISSKEY -> EntityId.mayNull(src.parseString("id"))
|
|
||||||
else -> EntityId.mayNull(src.parseLong("id"))
|
|
||||||
} ?: error("missing id")
|
|
||||||
|
|
||||||
type = src.notEmptyOrThrow("type")
|
type = src.notEmptyOrThrow("type")
|
||||||
created_at = src.parseString("created_at")
|
created_at = src.parseString("created_at")
|
||||||
|
@ -85,6 +78,7 @@ class TootNotification(parser : TootParser, src : JSONObject) : TimelineItem() {
|
||||||
accountRef = TootAccountRef.mayNull(parser, parser.account(src.optJSONObject("account")))
|
accountRef = TootAccountRef.mayNull(parser, parser.account(src.optJSONObject("account")))
|
||||||
status = parser.status(src.optJSONObject("status"))
|
status = parser.status(src.optJSONObject("status"))
|
||||||
|
|
||||||
|
_orderId = id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@ import org.json.JSONObject
|
||||||
import jp.juggler.subwaytooter.util.parseString
|
import jp.juggler.subwaytooter.util.parseString
|
||||||
|
|
||||||
class TootPushSubscription(src : JSONObject){
|
class TootPushSubscription(src : JSONObject){
|
||||||
val id: EntityId?
|
val id: EntityId
|
||||||
val endpoint : String?
|
val endpoint : String?
|
||||||
private val alerts= HashMap<String,Boolean>()
|
private val alerts= HashMap<String,Boolean>()
|
||||||
val server_key : String?
|
val server_key : String?
|
||||||
|
|
||||||
init{
|
init{
|
||||||
id = EntityId.mayNull(src.parseLong("id"))
|
id = EntityId.mayDefault(src.parseLong("id"))
|
||||||
endpoint = src.parseString("endpoint")
|
endpoint = src.parseString("endpoint")
|
||||||
server_key = src.parseString("server_key")
|
server_key = src.parseString("server_key")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue