From db46d876232e5bbdb98483847c36deedf1b6cc31 Mon Sep 17 00:00:00 2001 From: tateisu Date: Sun, 30 Dec 2018 01:38:52 +0900 Subject: [PATCH] =?UTF-8?q?-=20(Misskey)=E3=82=A2=E3=82=AB=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=88TL=E3=81=A7=E3=82=AB=E3=83=A9=E3=83=A0?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=81=AB=E3=80=8C=E3=83=96=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=97=E3=81=AA=E3=81=84?= =?UTF-8?q?=E3=80=8D=E3=82=92=E3=81=A4=E3=81=91=E3=82=8B=E3=81=A8API?= =?UTF-8?q?=E3=81=AEincludeMyRenotes=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=82=92=E5=88=A9=E7=94=A8=E3=81=99=E3=82=8B=20-=20(M?= =?UTF-8?q?isskey)=E3=83=AA=E3=82=A2=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=AE=E8=A7=A3=E9=99=A4=20-=20=E3=83=A1=E3=83=B3=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=81=AE=E3=83=AA=E3=83=B3=E3=82=AF=E3=82=92?= =?UTF-8?q?=E3=82=BF=E3=83=83=E3=83=97=E3=81=97=E3=81=9F=E6=99=82=E3=81=AB?= =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E5=86=85=E3=81=A7=E3=83=97=E3=83=AD?= =?UTF-8?q?=E3=83=95=E3=82=92=E9=96=8B=E3=81=91=E3=81=AA=E3=81=84=E3=83=90?= =?UTF-8?q?=E3=82=B0=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dictionaries/tateisu.xml | 2 + .../java/jp/juggler/subwaytooter/Column.kt | 25 ++++-- .../jp/juggler/subwaytooter/ItemViewHolder.kt | 84 +++++++++++++++---- .../subwaytooter/action/Action_User.kt | 7 +- .../juggler/subwaytooter/api/TootApiClient.kt | 1 + .../api/entity/MisskeyNoteUpdate.kt | 7 +- .../subwaytooter/api/entity/TootStatus.kt | 29 +++++++ app/src/main/res/values-ja/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 9 files changed, 132 insertions(+), 29 deletions(-) diff --git a/.idea/dictionaries/tateisu.xml b/.idea/dictionaries/tateisu.xml index 206ba661..7cae5e81 100644 --- a/.idea/dictionaries/tateisu.xml +++ b/.idea/dictionaries/tateisu.xml @@ -63,6 +63,7 @@ reblog reblogged reblogs + renotes repeatly sephiroth sharedpref @@ -88,6 +89,7 @@ unfollowed unmute unmuted + unreacted unreblog userkey utoken diff --git a/app/src/main/java/jp/juggler/subwaytooter/Column.kt b/app/src/main/java/jp/juggler/subwaytooter/Column.kt index fcd19a5b..b4b332c1 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/Column.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/Column.kt @@ -2668,7 +2668,7 @@ class Column( when(profile_tab) { TAB_FOLLOWING -> return when { - + isMisskey -> { pagingType = PagingType.Cursor parseAccountList( @@ -2679,7 +2679,7 @@ class Column( misskeyArrayFinder = misskeyArrayFinderUsers ) } - + access_info.isPseudo -> { idRecent = null idOld = null @@ -2690,7 +2690,6 @@ class Column( TootApiResult() } - else -> { parseAccountList( client, @@ -2726,7 +2725,7 @@ class Column( ) TootApiResult() } - + else -> { parseAccountList( client, @@ -6360,7 +6359,11 @@ class Column( s.increaseReaction(ev.reaction, byMe, "onNoteUpdated ${ev.userId}") } } - + MisskeyNoteUpdate.Type.UNREACTION -> { + scanStatusAll { s -> + s.decreaseReaction(ev.reaction, byMe ,"onNoteUpdated ${ev.userId}") + } + } MisskeyNoteUpdate.Type.VOTED -> { scanStatusAll { s -> s.enquete?.increaseVote(context, ev.choice, byMe) ?: false @@ -6372,6 +6375,10 @@ class Column( s.markDeleted(context, ev.deletedAt) ?: false } } + + else ->{ + log.d("onNoteUpdated: unknown type: ${ev.type}") + } } if(changeList.isNotEmpty()) { @@ -6730,9 +6737,11 @@ class Column( makeMisskeyBaseParameter(parser).putMisskeyParamsTimeline() private fun makeMisskeyParamsProfileStatuses(parser : TootParser) = - makeMisskeyParamsUserId(parser) - .putMisskeyParamsTimeline() - .put("includeReplies", true) + makeMisskeyParamsUserId(parser).apply { + putMisskeyParamsTimeline() + if(! dont_show_reply) put("includeReplies", true) + if(! dont_show_boost) put("includeMyRenotes", true) + } private fun makePublicLocalUrl() : String { return when { diff --git a/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.kt b/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.kt index 08f9322a..c2e36866 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.kt @@ -1169,7 +1169,7 @@ internal class ItemViewHolder( ) } - makeReactionsView(status.reactionCounts) + makeReactionsView(status) buttons_for_status?.bind(status, (item as? TootNotification)) @@ -1993,15 +1993,10 @@ internal class ItemViewHolder( } - private fun makeReactionsView(reactionsCount : HashMap?) { - + private fun makeReactionsView(status:TootStatus ) { if(! access_info.isMisskey) return - - // reactionsCount?:return - // MisskeyReaction.values().find { - // val c = reactionsCount[it.shortcode] - // c != null && c > 0 - // } ?: return + + val reactionsCount = status.reactionCounts val density = activity.density @@ -2036,10 +2031,18 @@ internal class ItemViewHolder( activity, R.drawable.btn_bg_transparent ) - b.contentDescription = activity.getString(R.string.reaction_add) + + val hasMyReaction = status.myReaction?.isNotEmpty() == true + b.contentDescription = activity.getString(if(hasMyReaction) R.string.reaction_remove else R.string.reaction_add ) b.scaleType = ImageView.ScaleType.FIT_CENTER b.padding = paddingV - b.setOnClickListener { addReaction(status_showing, null) } + b.setOnClickListener { + if( hasMyReaction ){ + removeReaction(status, false) + }else{ + addReaction(status, null) + } + } b.setOnLongClickListener { Action_Toot.reactionFromAnotherAccount( @@ -2053,7 +2056,7 @@ internal class ItemViewHolder( setIconDrawableId( activity, b, - R.drawable.ic_add, + if(hasMyReaction) R.drawable.ic_remove else R.drawable.ic_add, color = content_color, alphaMultiplier = Styler.boost_alpha ) @@ -2088,7 +2091,7 @@ internal class ItemViewHolder( , compoundPaddingDp ) b.tag = mr.shortcode - b.setOnClickListener { addReaction(status_showing, it.tag as? String) } + b.setOnClickListener { addReaction(status, it.tag as? String) } b.setOnLongClickListener { Action_Toot.reactionFromAnotherAccount( @@ -2114,8 +2117,7 @@ internal class ItemViewHolder( llExtra.addView(box) } - private fun addReaction(status : TootStatus?, code : String?) { - status ?: return + private fun addReaction(status : TootStatus, code : String?) { if(status.myReaction?.isNotEmpty() == true) { showToast(activity, false, R.string.already_reactioned) @@ -2177,6 +2179,58 @@ internal class ItemViewHolder( }) } + private fun removeReaction(status : TootStatus, confirmed : Boolean = false) { + + val reaction = status.myReaction + + if(reaction?.isNotEmpty() != true) { + showToast(activity, false, R.string.not_reactioned) + return + } + + if(access_info.isPseudo || ! access_info.isMisskey) return + + if(!confirmed) { + AlertDialog.Builder(activity) + .setMessage(activity.getString(R.string.reaction_remove_confirm,reaction)) + .setNegativeButton(R.string.cancel, null) + .setPositiveButton(R.string.ok) { _, _ -> + removeReaction(status, confirmed = true) + } + .show() + return + } + + TootTaskRunner(activity, progress_style = TootTaskRunner.PROGRESS_NONE).run(access_info, + object : TootTask { + override fun background(client : TootApiClient) : TootApiResult? = + // 成功すると204 no content + client.request( + "/api/notes/reactions/delete", + access_info.putMisskeyApiToken(JSONObject()) + .put("noteId", status.id.toString()) + .toPostRequestBuilder() + ) + + + override fun handleResult(result : TootApiResult?) { + result ?: return + + val error = result.error + if(error != null) { + showToast(activity, false, error) + return + } + + if((result.response?.code() ?: - 1) in 200 until 300) { + if(status.decreaseReaction(reaction,true,"removeReaction" )) { + // 1個だけ描画更新するのではなく、TLにある複数の要素をまとめて更新する + list_adapter.notifyChange(reason = "removeReaction complete", reset = true) + } + } + } + }) + } private fun makeEnqueteChoiceView( enquete : NicoEnquete, now : Long, diff --git a/app/src/main/java/jp/juggler/subwaytooter/action/Action_User.kt b/app/src/main/java/jp/juggler/subwaytooter/action/Action_User.kt index 312c3e65..555fc2be 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/action/Action_User.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/action/Action_User.kt @@ -3,10 +3,7 @@ package jp.juggler.subwaytooter.action import android.app.AlertDialog import jp.juggler.subwaytooter.* import jp.juggler.subwaytooter.api.* -import jp.juggler.subwaytooter.api.entity.TootAccount -import jp.juggler.subwaytooter.api.entity.TootRelationShip -import jp.juggler.subwaytooter.api.entity.TootStatus -import jp.juggler.subwaytooter.api.entity.parseItem +import jp.juggler.subwaytooter.api.entity.* import jp.juggler.subwaytooter.dialog.AccountPicker import jp.juggler.subwaytooter.dialog.ReportForm import jp.juggler.subwaytooter.table.AcctColor @@ -305,7 +302,7 @@ object Action_User { override fun background(client : TootApiClient) : TootApiResult? = client.syncAccountByUrl(access_info, who_url)?.also { result -> - who = result.data as? TootAccount + who = (result.data as? TootAccountRef)?.get() } override fun handleResult(result : TootApiResult?) { diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt index 5e551184..33b3bf73 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt @@ -1412,6 +1412,7 @@ class TootApiClient( } +// result.data に TootAccountRefを格納して返す。もしくはエラーかキャンセル fun TootApiClient.syncAccountByUrl(accessInfo : SavedAccount, who_url : String) : TootApiResult? { // misskey由来のアカウントURLは https://host/@user@instance などがある diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/entity/MisskeyNoteUpdate.kt b/app/src/main/java/jp/juggler/subwaytooter/api/entity/MisskeyNoteUpdate.kt index 53049ff4..2638bc4b 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/entity/MisskeyNoteUpdate.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/api/entity/MisskeyNoteUpdate.kt @@ -8,6 +8,7 @@ class MisskeyNoteUpdate(src:JSONObject){ enum class Type { REACTION, + UNREACTION, DELETED, VOTED } @@ -32,7 +33,11 @@ class MisskeyNoteUpdate(src:JSONObject){ reaction = src2.parseString("reaction") userId = EntityId.mayDefault(src2.parseString("userId")) } - + "unreacted" -> { + type = Type.UNREACTION + reaction = src2.parseString("reaction") + userId = EntityId.mayDefault(src2.parseString("userId")) + } "deleted" -> { type = Type.DELETED deletedAt = TootStatus.parseTime(src2.optString("deletedAt")) diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt index a600de1d..2f5f8bfe 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt @@ -632,6 +632,35 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() { } } + fun decreaseReaction(reaction:String?,byMe:Boolean, caller : String) : Boolean { + reaction ?: return false + + MisskeyReaction.shortcodeMap[reaction] ?: return false + + synchronized(this) { + + if(byMe){ + if( this.myReaction != reaction ){ + // 自分でリアクションしたらUIで更新した後にストリーミングイベントが届くことがある + return false + } + myReaction = null + } + + log.d("decreaseReaction noteId=$id byMe=$byMe caller=$caller") + + // カウントを減らす + var map = this.reactionCounts + if(map == null) { + map = HashMap() + this.reactionCounts = map + } + map[reaction] = (map[reaction] ?: 1) - 1 + + return true + } + } + fun markDeleted(context : Context, deletedAt : Long?) : Boolean? { var sv = if(deletedAt != null) { diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 1fec7f6d..679fc488 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -41,6 +41,7 @@ 既にお気に入り済みです 既にフォローしてます リアクション済みです + まだリアクションしてません 投票済です アプリ名(via)を可能なら表示する APIエラー %1$s @@ -549,6 +550,7 @@ ストアで評価 リアクション (Misskey) リアクションの追加 + リアクションの削除 ギャップを読む 読込中: %1$s %2$s おすすめプラグイン @@ -830,5 +832,6 @@ プライバシーポリシー サービスの規約に同意します 疑似アカウントではフォローリストを読めません + あなたのリアクション \"%1$s\"を削除しますか? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b1441ba0..272e3396 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -748,6 +748,7 @@ Followers %1$d votes Add reaction + Remove reaction unknown notification from %1$s Don\'t show reaction Don\'t show enquete @@ -762,6 +763,7 @@ Reply to %1$s deleted at %1$s already reacted to. + not yet reacted to. \'Unlisted\' visibility \'Followers\' visibility \'Direct to users\' visibility @@ -850,5 +852,6 @@ Please specify the password. The user name must not contains \"@\" or \"/\". Can\'t read follow list from pseudo account. + Remove your reaction \"%1$s\"?