2018-01-04 19:52:25 +01:00
|
|
|
package jp.juggler.subwaytooter.table
|
|
|
|
|
|
|
|
import android.content.ContentValues
|
|
|
|
import android.database.sqlite.SQLiteDatabase
|
2019-02-15 02:51:22 +01:00
|
|
|
import androidx.collection.LruCache
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.App1
|
2019-01-28 19:02:09 +01:00
|
|
|
import jp.juggler.subwaytooter.api.TootParser
|
2018-08-18 12:58:14 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.EntityId
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootAccount
|
|
|
|
import jp.juggler.subwaytooter.api.entity.TootRelationShip
|
2018-12-01 00:02:18 +01:00
|
|
|
import jp.juggler.util.LogCategory
|
|
|
|
import jp.juggler.util.getInt
|
2019-01-28 19:02:09 +01:00
|
|
|
import org.json.JSONObject
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2018-08-28 14:25:45 +02:00
|
|
|
class UserRelation {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2018-08-20 02:07:55 +02:00
|
|
|
var following : Boolean = false // 認証ユーザからのフォロー状態にある
|
2018-01-04 19:52:25 +01:00
|
|
|
var followed_by : Boolean = false // 認証ユーザは被フォロー状態にある
|
2018-10-30 20:29:00 +01:00
|
|
|
var blocking : Boolean = false // 認証ユーザからブロックした
|
|
|
|
var blocked_by : Boolean = false // 認証ユーザからブロックされた(Misskeyのみ。Mastodonでは常にfalse)
|
2018-01-04 19:52:25 +01:00
|
|
|
var muting : Boolean = false
|
2018-08-20 02:07:55 +02:00
|
|
|
var requested : Boolean = false // 認証ユーザからのフォローは申請中である
|
2018-10-30 20:29:00 +01:00
|
|
|
var requested_by : Boolean = false // 相手から認証ユーザへのフォローリクエスト申請中(Misskeyのみ。Mastodonでは常にfalse)
|
2018-01-04 19:52:25 +01:00
|
|
|
var following_reblogs : Int = 0 // このユーザからのブーストをTLに表示する
|
2018-08-28 14:25:45 +02:00
|
|
|
var endorsed : Boolean = false // ユーザをプロフィールで紹介する
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
// 認証ユーザからのフォロー状態
|
|
|
|
fun getFollowing(who : TootAccount?) : Boolean {
|
|
|
|
return if(requested && ! following && who != null && ! who.locked) true else following
|
|
|
|
}
|
|
|
|
|
|
|
|
// 認証ユーザからのフォローリクエスト申請中状態
|
|
|
|
fun getRequested(who : TootAccount?) : Boolean {
|
|
|
|
return if(requested && ! following && who != null && ! who.locked) false else requested
|
|
|
|
}
|
|
|
|
|
2018-08-18 12:58:14 +02:00
|
|
|
companion object : TableCompanion {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
const val REBLOG_HIDE =
|
|
|
|
0 // don't show the boosts from target account will be shown on authorized user's home TL.
|
|
|
|
const val REBLOG_SHOW =
|
|
|
|
1 // show the boosts from target account will be shown on authorized user's home TL.
|
|
|
|
const val REBLOG_UNKNOWN = 2 // not following, or instance don't support hide reblog.
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2019-02-15 02:51:22 +01:00
|
|
|
private val mMemoryCache = androidx.collection.LruCache<String, UserRelation>(2048)
|
2019-01-28 19:02:09 +01:00
|
|
|
|
|
|
|
private val log = LogCategory("UserRelationMisskey")
|
|
|
|
|
|
|
|
private const val table = "user_relation_misskey"
|
2018-01-04 19:52:25 +01:00
|
|
|
private const val COL_TIME_SAVE = "time_save"
|
|
|
|
private const val COL_DB_ID = "db_id" // SavedAccount のDB_ID
|
|
|
|
private const val COL_WHO_ID = "who_id" // ターゲットアカウントのID
|
|
|
|
private const val COL_FOLLOWING = "following"
|
|
|
|
private const val COL_FOLLOWED_BY = "followed_by"
|
|
|
|
private const val COL_BLOCKING = "blocking"
|
|
|
|
private const val COL_MUTING = "muting"
|
|
|
|
private const val COL_REQUESTED = "requested"
|
|
|
|
private const val COL_FOLLOWING_REBLOGS = "following_reblogs"
|
2019-01-28 19:02:09 +01:00
|
|
|
private const val COL_ENDORSED = "endorsed"
|
|
|
|
private const val COL_BLOCKED_BY = "blocked_by"
|
|
|
|
private const val COL_REQUESTED_BY = "requested_by"
|
2018-08-20 02:07:55 +02:00
|
|
|
|
2018-03-16 15:13:34 +01:00
|
|
|
override fun onDBCreate(db : SQLiteDatabase) {
|
2018-01-04 19:52:25 +01:00
|
|
|
log.d("onDBCreate!")
|
|
|
|
db.execSQL(
|
2018-08-28 14:25:45 +02:00
|
|
|
"""
|
|
|
|
create table if not exists $table
|
|
|
|
(_id INTEGER PRIMARY KEY
|
|
|
|
,$COL_TIME_SAVE integer not null
|
|
|
|
,$COL_DB_ID integer not null
|
2019-01-28 19:02:09 +01:00
|
|
|
,$COL_WHO_ID text not null
|
2018-08-28 14:25:45 +02:00
|
|
|
,$COL_FOLLOWING integer not null
|
|
|
|
,$COL_FOLLOWED_BY integer not null
|
|
|
|
,$COL_BLOCKING integer not null
|
|
|
|
,$COL_MUTING integer not null
|
|
|
|
,$COL_REQUESTED integer not null
|
|
|
|
,$COL_FOLLOWING_REBLOGS integer not null
|
|
|
|
,$COL_ENDORSED integer default 0
|
2019-01-28 19:02:09 +01:00
|
|
|
,$COL_BLOCKED_BY integer default 0
|
|
|
|
,$COL_REQUESTED_BY integer default 0
|
2018-08-28 14:25:45 +02:00
|
|
|
)"""
|
2018-01-04 19:52:25 +01:00
|
|
|
)
|
|
|
|
db.execSQL(
|
2018-08-28 14:25:45 +02:00
|
|
|
"create unique index if not exists ${table}_id on $table ($COL_DB_ID,$COL_WHO_ID)"
|
2018-01-04 19:52:25 +01:00
|
|
|
)
|
|
|
|
db.execSQL(
|
2018-08-28 14:25:45 +02:00
|
|
|
"create index if not exists ${table}_time on $table ($COL_TIME_SAVE)"
|
2018-01-04 19:52:25 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-03-16 15:13:34 +01:00
|
|
|
override fun onDBUpgrade(db : SQLiteDatabase, oldVersion : Int, newVersion : Int) {
|
2019-01-28 19:02:09 +01:00
|
|
|
if(oldVersion < 30 && newVersion >= 30) {
|
|
|
|
db.execSQL("drop table if exists $table")
|
2018-01-04 19:52:25 +01:00
|
|
|
onDBCreate(db)
|
|
|
|
}
|
2019-01-28 19:02:09 +01:00
|
|
|
if(oldVersion < 32 && newVersion >= 32) {
|
2018-01-04 19:52:25 +01:00
|
|
|
try {
|
2019-01-28 19:02:09 +01:00
|
|
|
db.execSQL("alter table $table add column $COL_ENDORSED integer default 0")
|
2018-01-04 19:52:25 +01:00
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
2019-01-28 19:02:09 +01:00
|
|
|
if(oldVersion < 34 && newVersion >= 34) {
|
2018-08-28 14:25:45 +02:00
|
|
|
try {
|
2019-01-28 19:02:09 +01:00
|
|
|
db.execSQL("alter table $table add column $COL_BLOCKED_BY integer default 0")
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(oldVersion < 35 && newVersion >= 35) {
|
|
|
|
try {
|
|
|
|
db.execSQL("alter table $table add column $COL_REQUESTED_BY integer default 0")
|
2018-08-28 14:25:45 +02:00
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fun deleteOld(now : Long) {
|
|
|
|
try {
|
|
|
|
val expire = now - 86400000L * 365
|
2018-08-18 12:58:14 +02:00
|
|
|
App1.database.delete(table, "$COL_TIME_SAVE<?", arrayOf(expire.toString()))
|
2018-01-04 19:52:25 +01:00
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.e(ex, "deleteOld failed.")
|
|
|
|
}
|
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
try {
|
|
|
|
// 旧型式のテーブルの古いデータの削除だけは時々回す
|
|
|
|
val table = "user_relation"
|
|
|
|
val COL_TIME_SAVE = "time_save"
|
|
|
|
val expire = now - 86400000L * 365
|
|
|
|
App1.database.delete(table, "$COL_TIME_SAVE<?", arrayOf(expire.toString()))
|
|
|
|
} catch(_ : Throwable) {
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
fun save1Misskey(now : Long, db_id : Long, whoId : String, src : UserRelation?) {
|
|
|
|
src?:return
|
|
|
|
try {
|
|
|
|
val cv = ContentValues()
|
|
|
|
cv.put(COL_TIME_SAVE, now)
|
|
|
|
cv.put(COL_DB_ID, db_id)
|
|
|
|
cv.put(COL_WHO_ID, whoId)
|
|
|
|
cv.put(COL_FOLLOWING, src.following.b2i())
|
|
|
|
cv.put(COL_FOLLOWED_BY, src.followed_by.b2i())
|
|
|
|
cv.put(COL_BLOCKING, src.blocking.b2i())
|
|
|
|
cv.put(COL_MUTING, src.muting.b2i())
|
|
|
|
cv.put(COL_REQUESTED, src.requested.b2i())
|
|
|
|
cv.put(COL_FOLLOWING_REBLOGS, src.following_reblogs)
|
|
|
|
cv.put(COL_ENDORSED, src.endorsed.b2i())
|
|
|
|
cv.put(COL_BLOCKED_BY,src.blocked_by.b2i())
|
|
|
|
cv.put(COL_REQUESTED_BY,src.requested_by.b2i())
|
|
|
|
App1.database.replace(table, null, cv)
|
|
|
|
|
|
|
|
val key = String.format("%s:%s", db_id, whoId)
|
|
|
|
mMemoryCache.remove(key)
|
|
|
|
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.e(ex, "save failed.")
|
|
|
|
}
|
|
|
|
}
|
2018-08-20 02:07:55 +02:00
|
|
|
// マストドン用
|
2019-01-28 19:02:09 +01:00
|
|
|
fun save1Mastodon(now : Long, db_id : Long, src : TootRelationShip) : UserRelation {
|
|
|
|
|
|
|
|
val id :String = src.id.toString()
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
try {
|
|
|
|
val cv = ContentValues()
|
|
|
|
cv.put(COL_TIME_SAVE, now)
|
|
|
|
cv.put(COL_DB_ID, db_id)
|
2019-01-28 19:02:09 +01:00
|
|
|
cv.put(COL_WHO_ID,id )
|
2018-08-28 14:25:45 +02:00
|
|
|
cv.put(COL_FOLLOWING, src.following.b2i())
|
|
|
|
cv.put(COL_FOLLOWED_BY, src.followed_by.b2i())
|
|
|
|
cv.put(COL_BLOCKING, src.blocking.b2i())
|
|
|
|
cv.put(COL_MUTING, src.muting.b2i())
|
|
|
|
cv.put(COL_REQUESTED, src.requested.b2i())
|
2018-01-04 19:52:25 +01:00
|
|
|
cv.put(COL_FOLLOWING_REBLOGS, src.showing_reblogs)
|
2018-08-28 14:25:45 +02:00
|
|
|
cv.put(COL_ENDORSED,src.endorsed.b2i() )
|
2019-01-28 19:02:09 +01:00
|
|
|
cv.put(COL_BLOCKED_BY,src.blocked_by.b2i())
|
|
|
|
cv.put(COL_REQUESTED_BY,src.requested_by.b2i())
|
2018-01-04 19:52:25 +01:00
|
|
|
App1.database.replace(table, null, cv)
|
2019-01-28 19:02:09 +01:00
|
|
|
val key = String.format("%s:%s", db_id, id)
|
2018-01-04 19:52:25 +01:00
|
|
|
mMemoryCache.remove(key)
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.e(ex, "save failed.")
|
|
|
|
}
|
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
return load(db_id, id)
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
2018-08-20 02:07:55 +02:00
|
|
|
// マストドン用
|
2019-01-28 19:02:09 +01:00
|
|
|
fun saveListMastodon(now : Long, db_id : Long, src_list : ArrayList<TootRelationShip>) {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
val cv = ContentValues()
|
|
|
|
cv.put(COL_TIME_SAVE, now)
|
|
|
|
cv.put(COL_DB_ID, db_id)
|
|
|
|
|
|
|
|
var bOK = false
|
|
|
|
val db = App1.database
|
|
|
|
db.execSQL("BEGIN TRANSACTION")
|
|
|
|
try {
|
|
|
|
for(src in src_list) {
|
2019-01-28 19:02:09 +01:00
|
|
|
val id = src.id.toString()
|
|
|
|
cv.put(COL_WHO_ID, id)
|
2018-08-18 12:58:14 +02:00
|
|
|
cv.put(COL_FOLLOWING, src.following.b2i())
|
|
|
|
cv.put(COL_FOLLOWED_BY, src.followed_by.b2i())
|
|
|
|
cv.put(COL_BLOCKING, src.blocking.b2i())
|
|
|
|
cv.put(COL_MUTING, src.muting.b2i())
|
|
|
|
cv.put(COL_REQUESTED, src.requested.b2i())
|
2018-01-04 19:52:25 +01:00
|
|
|
cv.put(COL_FOLLOWING_REBLOGS, src.showing_reblogs)
|
2018-08-28 14:25:45 +02:00
|
|
|
cv.put(COL_ENDORSED,src.endorsed.b2i() )
|
2018-01-04 19:52:25 +01:00
|
|
|
db.replace(table, null, cv)
|
|
|
|
|
|
|
|
}
|
|
|
|
bOK = true
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
log.e(ex, "saveList failed.")
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bOK) {
|
|
|
|
db.execSQL("COMMIT TRANSACTION")
|
|
|
|
for(src in src_list) {
|
2019-01-28 19:02:09 +01:00
|
|
|
val id = src.id.toString()
|
|
|
|
val key = String.format("%s:%s", db_id, id)
|
2018-01-04 19:52:25 +01:00
|
|
|
mMemoryCache.remove(key)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
db.execSQL("ROLLBACK TRANSACTION")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
|
|
|
|
fun saveListMisskey(
|
|
|
|
now : Long,
|
|
|
|
db_id : Long,
|
|
|
|
src_list : List<Map.Entry<EntityId, UserRelation>>,
|
|
|
|
start : Int,
|
|
|
|
end : Int
|
|
|
|
) {
|
|
|
|
|
|
|
|
val cv = ContentValues()
|
|
|
|
cv.put(COL_TIME_SAVE, now)
|
|
|
|
cv.put(COL_DB_ID, db_id)
|
|
|
|
|
|
|
|
var bOK = false
|
|
|
|
val db = App1.database
|
|
|
|
db.execSQL("BEGIN TRANSACTION")
|
|
|
|
try {
|
|
|
|
for(i in start until end) {
|
|
|
|
val entry = src_list[i]
|
|
|
|
val id = entry.key
|
|
|
|
val src = entry.value
|
|
|
|
cv.put(COL_WHO_ID, id.toString())
|
|
|
|
cv.put(COL_FOLLOWING, src.following.b2i())
|
|
|
|
cv.put(COL_FOLLOWED_BY, src.followed_by.b2i())
|
|
|
|
cv.put(COL_BLOCKING, src.blocking.b2i())
|
|
|
|
cv.put(COL_MUTING, src.muting.b2i())
|
|
|
|
cv.put(COL_REQUESTED, src.requested.b2i())
|
|
|
|
cv.put(COL_FOLLOWING_REBLOGS, src.following_reblogs)
|
|
|
|
cv.put(COL_ENDORSED, src.endorsed.b2i())
|
|
|
|
cv.put(COL_BLOCKED_BY,src.blocked_by.b2i())
|
|
|
|
cv.put(COL_REQUESTED_BY,src.requested_by.b2i())
|
|
|
|
db.replace(table, null, cv)
|
|
|
|
}
|
|
|
|
bOK = true
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
log.e(ex, "saveList failed.")
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bOK) {
|
|
|
|
db.execSQL("COMMIT TRANSACTION")
|
|
|
|
for(i in start until end) {
|
|
|
|
val entry = src_list[i]
|
|
|
|
val key = String.format("%s:%s", db_id, entry.key)
|
|
|
|
UserRelation.mMemoryCache.remove(key)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
db.execSQL("ROLLBACK TRANSACTION")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun saveList2(now : Long, db_id : Long, list : ArrayList<TootRelationShip>) {
|
|
|
|
val cv = ContentValues()
|
|
|
|
cv.put(COL_TIME_SAVE, now)
|
|
|
|
cv.put(COL_DB_ID, db_id)
|
|
|
|
|
|
|
|
var bOK = false
|
|
|
|
val db = App1.database
|
|
|
|
db.execSQL("BEGIN TRANSACTION")
|
|
|
|
try {
|
|
|
|
for(src in list) {
|
|
|
|
cv.put(COL_WHO_ID, src.id.toString())
|
|
|
|
cv.put(COL_FOLLOWING, src.following.b2i())
|
|
|
|
cv.put(COL_FOLLOWED_BY, src.followed_by.b2i())
|
|
|
|
cv.put(COL_BLOCKING, src.blocking.b2i())
|
|
|
|
cv.put(COL_MUTING, src.muting.b2i())
|
|
|
|
cv.put(COL_REQUESTED, src.requested.b2i())
|
|
|
|
cv.put(COL_FOLLOWING_REBLOGS, src.showing_reblogs)
|
|
|
|
cv.put(COL_ENDORSED, src.endorsed.b2i())
|
|
|
|
cv.put(COL_BLOCKED_BY,src.blocked_by.b2i())
|
|
|
|
cv.put(COL_REQUESTED_BY,src.requested_by.b2i())
|
|
|
|
db.replace(table, null, cv)
|
|
|
|
}
|
|
|
|
bOK = true
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
log.e(ex, "saveList2 failed.")
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bOK) {
|
|
|
|
db.execSQL("COMMIT TRANSACTION")
|
|
|
|
for(src in list) {
|
|
|
|
val key = String.format("%s:%s", db_id, src.id)
|
|
|
|
UserRelation.mMemoryCache.remove(key)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
db.execSQL("ROLLBACK TRANSACTION")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private const val load_where = "$COL_DB_ID=? and $COL_WHO_ID=?"
|
|
|
|
|
|
|
|
private val load_where_arg = object : ThreadLocal<Array<String?>>() {
|
|
|
|
override fun initialValue() : Array<String?> {
|
|
|
|
return Array(2) { null }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-08-28 14:25:45 +02:00
|
|
|
fun load(db_id : Long, whoId : EntityId) : UserRelation {
|
2018-08-20 02:07:55 +02:00
|
|
|
//
|
|
|
|
val key = String.format("%s:%s", db_id, whoId)
|
2018-01-04 19:52:25 +01:00
|
|
|
val cached : UserRelation? = mMemoryCache.get(key)
|
|
|
|
if(cached != null) return cached
|
2018-08-28 14:25:45 +02:00
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
val dst = load(db_id, whoId.toString())
|
2018-08-28 14:25:45 +02:00
|
|
|
|
2018-08-20 02:07:55 +02:00
|
|
|
mMemoryCache.put(key, dst)
|
|
|
|
return dst
|
|
|
|
}
|
|
|
|
|
2019-01-28 19:02:09 +01:00
|
|
|
fun load(db_id : Long, who_id : String) : UserRelation {
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
try {
|
2018-09-27 16:21:37 +02:00
|
|
|
val where_arg = load_where_arg.get() ?: arrayOfNulls<String?>(2)
|
2018-01-04 19:52:25 +01:00
|
|
|
where_arg[0] = db_id.toString()
|
2019-01-28 19:02:09 +01:00
|
|
|
where_arg[1] = who_id
|
2018-01-04 19:52:25 +01:00
|
|
|
App1.database.query(table, null, load_where, where_arg, null, null, null)
|
|
|
|
.use { cursor ->
|
|
|
|
if(cursor.moveToNext()) {
|
|
|
|
val dst = UserRelation()
|
2018-10-30 20:29:00 +01:00
|
|
|
dst.following = cursor.getBoolean(COL_FOLLOWING)
|
2019-01-28 19:02:09 +01:00
|
|
|
dst.followed_by = cursor.getBoolean(COL_FOLLOWED_BY)
|
2018-10-30 20:29:00 +01:00
|
|
|
dst.blocking = cursor.getBoolean(COL_BLOCKING)
|
|
|
|
dst.muting = cursor.getBoolean(COL_MUTING)
|
|
|
|
dst.requested = cursor.getBoolean(COL_REQUESTED)
|
|
|
|
dst.following_reblogs = cursor.getInt(COL_FOLLOWING_REBLOGS)
|
2019-01-28 19:02:09 +01:00
|
|
|
dst.endorsed =cursor.getBoolean(COL_ENDORSED)
|
|
|
|
dst.blocked_by = cursor.getBoolean(COL_BLOCKED_BY)
|
|
|
|
dst.requested_by = cursor.getBoolean(COL_REQUESTED_BY)
|
2018-01-04 19:52:25 +01:00
|
|
|
return dst
|
|
|
|
}
|
|
|
|
}
|
2019-01-28 19:02:09 +01:00
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
log.e(ex, "load failed.")
|
|
|
|
}
|
2019-01-28 19:02:09 +01:00
|
|
|
return UserRelation()
|
2018-08-20 02:07:55 +02:00
|
|
|
}
|
2019-01-28 19:02:09 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MisskeyはUserエンティティにユーザリレーションが含まれたり含まれなかったりする
|
|
|
|
fun fromAccount(parser: TootParser, src : JSONObject, id:EntityId) {
|
|
|
|
|
|
|
|
// アカウントのjsonがユーザリレーションを含まないなら何もしない
|
|
|
|
src.opt("isFollowing") ?:return
|
|
|
|
|
|
|
|
// プロフカラムで ユーザのプロフ(A)とアカウントTL(B)を順に取得すると
|
|
|
|
// (A)ではisBlockingに情報が入っているが、(B)では情報が入っていない
|
|
|
|
// 対策として(A)でリレーションを取得済みのユーザは(B)のタイミングではリレーションを読み捨てる
|
|
|
|
|
|
|
|
val map = parser.misskeyUserRelationMap
|
|
|
|
if( map.containsKey(id) ) return
|
|
|
|
|
|
|
|
map[id] = UserRelation().apply {
|
|
|
|
following = src.optBoolean("isFollowing")
|
|
|
|
followed_by = src.optBoolean("isFollowed")
|
|
|
|
muting = src.optBoolean("isMuted")
|
|
|
|
blocking = src.optBoolean("isBlocking")
|
|
|
|
blocked_by = src.optBoolean("isBlocked")
|
|
|
|
endorsed = false
|
|
|
|
requested = src.optBoolean("hasPendingFollowRequestFromYou")
|
|
|
|
requested_by = src.optBoolean("hasPendingFollowRequestToYou")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
}
|