(Mastodon)add notification type for post from specified followings. アカウント設定でプッシュ購読の更新を手動で行った時は以前の状況に関係なく購読を更新する。
This commit is contained in:
parent
5849ae8527
commit
8d47c7d283
|
@ -108,6 +108,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
private lateinit var cbNotificationFollowRequest : CheckBox
|
||||
private lateinit var cbNotificationReaction : CheckBox
|
||||
private lateinit var cbNotificationVote : CheckBox
|
||||
private lateinit var cbNotificationPost : CheckBox
|
||||
|
||||
private lateinit var cbConfirmFollow : CheckBox
|
||||
private lateinit var cbConfirmFollowLockedUser : CheckBox
|
||||
|
@ -284,6 +285,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
|
||||
cbNotificationReaction = findViewById(R.id.cbNotificationReaction)
|
||||
cbNotificationVote = findViewById(R.id.cbNotificationVote)
|
||||
cbNotificationPost = findViewById(R.id.cbNotificationPost)
|
||||
|
||||
cbConfirmFollow = findViewById(R.id.cbConfirmFollow)
|
||||
cbConfirmFollowLockedUser = findViewById(R.id.cbConfirmFollowLockedUser)
|
||||
|
@ -350,8 +352,11 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
cbNotificationFollowRequest.setOnCheckedChangeListener(this)
|
||||
cbNotificationReaction.setOnCheckedChangeListener(this)
|
||||
cbNotificationVote.setOnCheckedChangeListener(this)
|
||||
cbNotificationPost.setOnCheckedChangeListener(this)
|
||||
|
||||
cbLocked.setOnCheckedChangeListener(this)
|
||||
|
||||
|
||||
cbConfirmFollow.setOnCheckedChangeListener(this)
|
||||
cbConfirmFollowLockedUser.setOnCheckedChangeListener(this)
|
||||
cbConfirmUnfollow.setOnCheckedChangeListener(this)
|
||||
|
@ -463,6 +468,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
cbNotificationFollowRequest.isChecked = a.notification_follow_request
|
||||
cbNotificationReaction.isChecked = a.notification_reaction
|
||||
cbNotificationVote.isChecked = a.notification_vote
|
||||
cbNotificationPost.isChecked = a.notification_post
|
||||
|
||||
cbConfirmFollow.isChecked = a.confirm_follow
|
||||
cbConfirmFollowLockedUser.isChecked = a.confirm_follow_locked
|
||||
|
@ -500,6 +506,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
cbNotificationFollowRequest.isEnabled = enabled
|
||||
cbNotificationReaction.isEnabled = enabled
|
||||
cbNotificationVote.isEnabled = enabled
|
||||
cbNotificationPost.isEnabled = enabled
|
||||
|
||||
cbConfirmFollow.isEnabled = enabled
|
||||
cbConfirmFollowLockedUser.isEnabled = enabled
|
||||
|
@ -542,6 +549,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
account.notification_follow_request = cbNotificationFollowRequest.isChecked
|
||||
account.notification_reaction = cbNotificationReaction.isChecked
|
||||
account.notification_vote = cbNotificationVote.isChecked
|
||||
account.notification_post = cbNotificationPost.isChecked
|
||||
|
||||
account.sound_uri = notification_sound_uri ?: ""
|
||||
|
||||
|
@ -1574,7 +1582,7 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
|
|||
)
|
||||
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
return wps.updateSubscription(client)
|
||||
return wps.updateSubscription(client,true)
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
|
|
|
@ -135,8 +135,10 @@ class App1 : Application() {
|
|||
// 2020/6/8 46 => 54 別ブランチで色々してた。このブランチには影響ないが onDowngrade()を実装してないので上げてしまう
|
||||
// 2020/7/19 54=>55 UserRelation テーブルに項目追加。
|
||||
// 2020/9/7 55=>56 SavedAccountテーブルにCOL_DOMAINを追加。
|
||||
// 2020/9/20 56=>57 SavedAccountテーブルに項目追加
|
||||
// 2020/9/20 57=>58 UserRelationテーブルに項目追加
|
||||
|
||||
internal const val DB_VERSION = 56
|
||||
internal const val DB_VERSION = 58
|
||||
|
||||
private val tableList = arrayOf(
|
||||
LogData,
|
||||
|
|
|
@ -772,6 +772,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
Pref.ipConversationMainTootBgColor,
|
||||
R.string.conversation_main_toot_background_color
|
||||
)
|
||||
colorAlpha(Pref.ipEventBgColorStatus, R.string.status)
|
||||
}
|
||||
|
||||
group(R.string.button_accent_color) {
|
||||
|
|
|
@ -203,6 +203,7 @@ class Column(
|
|||
internal const val QUICK_FILTER_FOLLOW = 4
|
||||
internal const val QUICK_FILTER_REACTION = 5
|
||||
internal const val QUICK_FILTER_VOTE = 6
|
||||
internal const val QUICK_FILTER_POST = 7
|
||||
|
||||
internal const val HASHTAG_ELLIPSIZE = 26
|
||||
|
||||
|
@ -1059,6 +1060,7 @@ class Column(
|
|||
QUICK_FILTER_FOLLOW -> sb.append(context.getString(R.string.notification_type_follow))
|
||||
QUICK_FILTER_REACTION -> sb.append(context.getString(R.string.notification_type_reaction))
|
||||
QUICK_FILTER_VOTE -> sb.append(context.getString(R.string.notification_type_vote))
|
||||
QUICK_FILTER_POST -> sb.append(context.getString(R.string.notification_type_post))
|
||||
}
|
||||
|
||||
sb.append(")")
|
||||
|
@ -1619,6 +1621,8 @@ class Column(
|
|||
TootNotification.TYPE_VOTE,
|
||||
TootNotification.TYPE_POLL,
|
||||
TootNotification.TYPE_POLL_VOTE_MISSKEY -> dont_show_vote
|
||||
|
||||
TootNotification.TYPE_STATUS -> dont_show_normal_toot
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
@ -1641,6 +1645,8 @@ class Column(
|
|||
TootNotification.TYPE_VOTE,
|
||||
TootNotification.TYPE_POLL,
|
||||
TootNotification.TYPE_POLL_VOTE_MISSKEY -> quick_filter != QUICK_FILTER_VOTE
|
||||
|
||||
TootNotification.TYPE_STATUS -> quick_filter != QUICK_FILTER_POST
|
||||
else -> true
|
||||
}
|
||||
}) {
|
||||
|
@ -2347,6 +2353,7 @@ class Column(
|
|||
|
||||
fun canFilterNormalToot() : Boolean {
|
||||
return when(type) {
|
||||
ColumnType.NOTIFICATIONS -> true
|
||||
ColumnType.HOME, ColumnType.MISSKEY_HYBRID,
|
||||
ColumnType.LIST_TL, ColumnType.MISSKEY_ANTENNA_TL -> true
|
||||
ColumnType.LOCAL, ColumnType.FEDERATE, ColumnType.HASHTAG, ColumnType.SEARCH -> isMisskey
|
||||
|
|
|
@ -208,6 +208,9 @@ internal fun JsonObject.addMisskeyNotificationFilter(column : Column) : JsonObje
|
|||
if(column.dont_show_vote) {
|
||||
add("poll_vote")
|
||||
}
|
||||
if( column.dont_show_normal_toot){
|
||||
// FIXME Misskeyには特定フォロー者からの投稿を通知する機能があるのか?
|
||||
}
|
||||
}
|
||||
|
||||
if(excludeList.isNotEmpty()) put("excludeTypes", excludeList)
|
||||
|
@ -228,6 +231,9 @@ internal fun JsonObject.addMisskeyNotificationFilter(column : Column) : JsonObje
|
|||
)
|
||||
Column.QUICK_FILTER_REACTION -> put("includeTypes", jp.juggler.util.jsonArray("reaction"))
|
||||
Column.QUICK_FILTER_VOTE -> put("includeTypes", jp.juggler.util.jsonArray("poll_vote"))
|
||||
Column.QUICK_FILTER_POST ->{
|
||||
// FIXME Misskeyには特定フォロー者からの投稿を通知する機能があるのか?
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
|
@ -360,6 +366,7 @@ internal fun Column.makeNotificationUrl(
|
|||
if(dont_show_follow) sb.append("&exclude_types[]=follow")
|
||||
if(dont_show_reply) sb.append("&exclude_types[]=mention")
|
||||
if(dont_show_vote) sb.append("&exclude_types[]=poll")
|
||||
if(dont_show_normal_toot) sb.append("&exclude_types[]=status")
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -367,6 +374,7 @@ internal fun Column.makeNotificationUrl(
|
|||
if(quick_filter != Column.QUICK_FILTER_BOOST) sb.append("&exclude_types[]=reblog")
|
||||
if(quick_filter != Column.QUICK_FILTER_FOLLOW) sb.append("&exclude_types[]=follow")
|
||||
if(quick_filter != Column.QUICK_FILTER_MENTION) sb.append("&exclude_types[]=mention")
|
||||
if(quick_filter != Column.QUICK_FILTER_POST) sb.append("&exclude_types[]=status")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,8 @@ class ColumnViewHolder(
|
|||
private lateinit var btnQuickFilterFavourite : ImageButton
|
||||
private lateinit var btnQuickFilterBoost : ImageButton
|
||||
private lateinit var btnQuickFilterFollow : ImageButton
|
||||
private lateinit var btnQuickFilterPost : ImageButton
|
||||
|
||||
private lateinit var btnQuickFilterReaction : ImageButton
|
||||
private lateinit var btnQuickFilterVote : ImageButton
|
||||
|
||||
|
@ -337,6 +339,7 @@ class ColumnViewHolder(
|
|||
btnQuickFilterFavourite.setOnClickListener(this)
|
||||
btnQuickFilterBoost.setOnClickListener(this)
|
||||
btnQuickFilterFollow.setOnClickListener(this)
|
||||
btnQuickFilterPost.setOnClickListener(this)
|
||||
btnQuickFilterReaction.setOnClickListener(this)
|
||||
btnQuickFilterVote.setOnClickListener(this)
|
||||
|
||||
|
@ -1158,6 +1161,7 @@ class ColumnViewHolder(
|
|||
btnQuickFilterFavourite -> clickQuickFilter(Column.QUICK_FILTER_FAVOURITE)
|
||||
btnQuickFilterBoost -> clickQuickFilter(Column.QUICK_FILTER_BOOST)
|
||||
btnQuickFilterFollow -> clickQuickFilter(Column.QUICK_FILTER_FOLLOW)
|
||||
btnQuickFilterPost-> clickQuickFilter(Column.QUICK_FILTER_POST)
|
||||
btnQuickFilterReaction -> clickQuickFilter(Column.QUICK_FILTER_REACTION)
|
||||
btnQuickFilterVote -> clickQuickFilter(Column.QUICK_FILTER_VOTE)
|
||||
|
||||
|
@ -1664,6 +1668,12 @@ class ColumnViewHolder(
|
|||
column.quick_filter == Column.QUICK_FILTER_FOLLOW
|
||||
)
|
||||
|
||||
showQuickFilterButton(
|
||||
btnQuickFilterPost,
|
||||
R.drawable.ic_send,
|
||||
column.quick_filter == Column.QUICK_FILTER_POST
|
||||
)
|
||||
|
||||
showQuickFilterButton(
|
||||
btnQuickFilterReaction,
|
||||
R.drawable.ic_add,
|
||||
|
@ -2315,6 +2325,13 @@ class ColumnViewHolder(
|
|||
margin = 0
|
||||
}
|
||||
|
||||
btnQuickFilterPost = imageButton {
|
||||
backgroundResource = R.drawable.btn_bg_transparent_round6dp
|
||||
contentDescription = context.getString(R.string.notification_type_post)
|
||||
}.lparams(dip(40), matchParent) {
|
||||
margin = 0
|
||||
}
|
||||
|
||||
btnQuickFilterReaction = imageButton {
|
||||
backgroundResource = R.drawable.btn_bg_transparent_round6dp
|
||||
contentDescription = context.getString(R.string.reaction)
|
||||
|
|
|
@ -38,6 +38,7 @@ internal class DlgContextMenu(
|
|||
) : View.OnClickListener, View.OnLongClickListener {
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("DlgContextMenu")
|
||||
}
|
||||
|
||||
|
@ -78,6 +79,8 @@ internal class DlgContextMenu(
|
|||
private val llAccountExtraAction : View =
|
||||
viewRoot.findViewById(R.id.llAccountExtraAction)
|
||||
|
||||
private val btnPostNotification : Button = viewRoot.findViewById(R.id.btnPostNotification)
|
||||
|
||||
init {
|
||||
this.access_info = column.access_info
|
||||
|
||||
|
@ -226,6 +229,7 @@ internal class DlgContextMenu(
|
|||
btnBoostedBy,
|
||||
btnFavouritedBy,
|
||||
btnDomainTimeline,
|
||||
btnPostNotification,
|
||||
|
||||
viewRoot.findViewById(R.id.btnQuoteUrlStatus),
|
||||
viewRoot.findViewById(R.id.btnTranslate),
|
||||
|
@ -449,6 +453,15 @@ internal class DlgContextMenu(
|
|||
btnOpenInstanceInAdminWebUi.vg(! access_info.isPseudo)
|
||||
|
||||
btnReportUser.vg(! (access_info.isPseudo || access_info.isMe(who)))
|
||||
|
||||
btnPostNotification.vg(! access_info.isPseudo && access_info.isMastodon && relation.following)
|
||||
?.let {
|
||||
it.text = when(relation.notifying) {
|
||||
true -> activity.getString(R.string.stop_notify_posts_from_this_user)
|
||||
else -> activity.getString(R.string.notify_posts_from_this_user)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
viewRoot.findViewById<View>(R.id.btnAccountText).setOnClickListener(this)
|
||||
|
@ -749,10 +762,20 @@ internal class DlgContextMenu(
|
|||
return
|
||||
}
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.confirm_block_domain, whoApDomain))
|
||||
.setMessage(
|
||||
activity.getString(
|
||||
R.string.confirm_block_domain,
|
||||
whoApDomain
|
||||
)
|
||||
)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_Instance.blockDomain(activity, access_info, whoApDomain, true)
|
||||
Action_Instance.blockDomain(
|
||||
activity,
|
||||
access_info,
|
||||
whoApDomain,
|
||||
true
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
@ -837,8 +860,7 @@ internal class DlgContextMenu(
|
|||
pos,
|
||||
who.apiHost,
|
||||
status,
|
||||
ColumnType.ACCOUNT_AROUND
|
||||
, allowPseudo = false
|
||||
ColumnType.ACCOUNT_AROUND, allowPseudo = false
|
||||
)
|
||||
|
||||
R.id.btnAroundLTL -> Action_Instance.timelinePublicAround(
|
||||
|
@ -930,6 +952,12 @@ internal class DlgContextMenu(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnPostNotification ->
|
||||
if(! access_info.isPseudo && access_info.isMastodon && relation.following) {
|
||||
val toggle = ! relation.notifying
|
||||
Action_User.statusNotification(activity, access_info, who.id, toggle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -935,6 +935,23 @@ internal class ItemViewHolder(
|
|||
}
|
||||
}
|
||||
|
||||
TootNotification.TYPE_STATUS -> {
|
||||
val colorBg = Pref.ipEventBgColorStatus(activity.pref)
|
||||
if(n_account != null) showBoost(
|
||||
n_accountRef,
|
||||
n.time_created_at,
|
||||
if(n_status==null){
|
||||
R.drawable.ic_question
|
||||
}else{
|
||||
Styler.getVisibilityIconId(access_info.isMisskey,n_status.visibility)
|
||||
},
|
||||
R.string.display_name_posted_by
|
||||
)
|
||||
if(n_status != null) {
|
||||
showNotificationStatus(n_status, colorBg)
|
||||
}
|
||||
}
|
||||
|
||||
TootNotification.TYPE_FOLLOW_REQUEST,
|
||||
TootNotification.TYPE_FOLLOW_REQUEST_MISSKEY -> {
|
||||
val colorBg = Pref.ipEventBgColorFollowRequest(activity.pref)
|
||||
|
|
|
@ -1576,6 +1576,9 @@ class PollingWorker private constructor(contextArg : Context) {
|
|||
TootNotification.TYPE_QUOTE ->
|
||||
"- " + context.getString(R.string.display_name_quoted_by, name)
|
||||
|
||||
TootNotification.TYPE_STATUS->
|
||||
"- " + context.getString(R.string.display_name_posted_by, name)
|
||||
|
||||
TootNotification.TYPE_FOLLOW ->
|
||||
"- " + context.getString(R.string.display_name_followed_by, name)
|
||||
|
||||
|
|
|
@ -531,6 +531,7 @@ object Pref {
|
|||
val ipEventBgColorQuote = IntPref("EventBgColorQuote", 0)
|
||||
val ipEventBgColorVote = IntPref("EventBgColorVote", 0)
|
||||
val ipEventBgColorFollowRequest = IntPref("EventBgColorFollowRequest", 0)
|
||||
val ipEventBgColorStatus = IntPref("EventBgColorStatus", 0)
|
||||
|
||||
val ipCcdHeaderBg = IntPref("ipCcdHeaderBg", 0)
|
||||
val ipCcdHeaderFg = IntPref("ipCcdHeaderFg", 0)
|
||||
|
|
|
@ -77,6 +77,7 @@ internal fun addPseudoAccount(
|
|||
account.notification_mention = false
|
||||
account.notification_reaction = false
|
||||
account.notification_vote = false
|
||||
account.notification_post = false
|
||||
account.saveSetting()
|
||||
callback(account)
|
||||
return
|
||||
|
|
|
@ -807,4 +807,41 @@ object Action_User {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun statusNotification(
|
||||
activity : ActMain,
|
||||
accessInfo : SavedAccount,
|
||||
whoId : EntityId,
|
||||
enabled : Boolean
|
||||
) {
|
||||
TootTaskRunner(activity).run(accessInfo, object : TootTask {
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
return client.request(
|
||||
"/api/v1/accounts/$whoId/follow",
|
||||
jsonObject {
|
||||
put("notify",enabled)
|
||||
}.toPostRequestBuilder()
|
||||
)?.also{ result->
|
||||
val relation = parseItem( ::TootRelationShip, TootParser(activity,accessInfo),result.jsonObject)
|
||||
if(relation!=null){
|
||||
UserRelation.save1Mastodon(System.currentTimeMillis(),accessInfo.db_id,relation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
// cancelled
|
||||
result ?: return
|
||||
|
||||
// error
|
||||
val error = result.error
|
||||
if(error != null) {
|
||||
showToast(activity, true, result.error)
|
||||
return
|
||||
}
|
||||
|
||||
showToast(activity, false, R.string.operation_succeeded)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ class TootNotification(parser : TootParser, src : JsonObject) : TimelineItem() {
|
|||
|
||||
// (Mastodon 2.8)投票完了
|
||||
const val TYPE_POLL = "poll"
|
||||
|
||||
const val TYPE_STATUS = "status"
|
||||
}
|
||||
|
||||
val json : JsonObject
|
||||
|
|
|
@ -40,6 +40,8 @@ class TootRelationShip(parser:TootParser,src : JsonObject) {
|
|||
// misskey用
|
||||
val requested_by : Boolean
|
||||
|
||||
val notifying : Boolean
|
||||
|
||||
// (Mastodon 3.2)
|
||||
var note : String? = null
|
||||
|
||||
|
@ -56,6 +58,7 @@ class TootRelationShip(parser:TootParser,src : JsonObject) {
|
|||
requested = src.optBoolean("hasPendingFollowRequestFromYou")
|
||||
requested_by = src.optBoolean("hasPendingFollowRequestToYou")
|
||||
|
||||
notifying = false
|
||||
endorsed = false
|
||||
showing_reblogs = UserRelation.REBLOG_UNKNOWN
|
||||
|
||||
|
@ -95,6 +98,7 @@ class TootRelationShip(parser:TootParser,src : JsonObject) {
|
|||
this.requested = src.optBoolean("requested")
|
||||
this.endorsed = src.optBoolean("endorsed")
|
||||
this.note = src.optString( "note")
|
||||
this.notifying = src.optBoolean("notifying")
|
||||
|
||||
// https://github.com/tootsuite/mastodon/commit/9745de883b198375ba23f7fde879f6d75ce2df0f
|
||||
// Mastodon 2.8.0から
|
||||
|
|
|
@ -52,6 +52,7 @@ class SavedAccount(
|
|||
var notification_follow_request : Boolean = false
|
||||
var notification_reaction : Boolean = false
|
||||
var notification_vote : Boolean = false
|
||||
var notification_post : Boolean = false
|
||||
var sound_uri = ""
|
||||
|
||||
var confirm_follow : Boolean = false
|
||||
|
@ -131,6 +132,7 @@ class SavedAccount(
|
|||
notification_follow_request = cursor.getBoolean(COL_NOTIFICATION_FOLLOW_REQUEST)
|
||||
notification_reaction = cursor.getBoolean(COL_NOTIFICATION_REACTION)
|
||||
notification_vote = cursor.getBoolean(COL_NOTIFICATION_VOTE)
|
||||
notification_post = cursor.getBoolean(COL_NOTIFICATION_POST)
|
||||
|
||||
dont_hide_nsfw = cursor.getBoolean(COL_DONT_HIDE_NSFW)
|
||||
dont_show_timeout = cursor.getBoolean(COL_DONT_SHOW_TIMEOUT)
|
||||
|
@ -204,6 +206,7 @@ class SavedAccount(
|
|||
cv.put(COL_NOTIFICATION_FOLLOW_REQUEST, notification_follow_request.b2i())
|
||||
cv.put(COL_NOTIFICATION_REACTION, notification_reaction.b2i())
|
||||
cv.put(COL_NOTIFICATION_VOTE, notification_vote.b2i())
|
||||
cv.put(COL_NOTIFICATION_POST, notification_post.b2i())
|
||||
|
||||
cv.put(COL_CONFIRM_FOLLOW, confirm_follow.b2i())
|
||||
cv.put(COL_CONFIRM_FOLLOW_LOCKED, confirm_follow_locked.b2i())
|
||||
|
@ -270,6 +273,8 @@ class SavedAccount(
|
|||
this.notification_follow_request = b.notification_follow_request
|
||||
this.notification_reaction = b.notification_reaction
|
||||
this.notification_vote = b.notification_vote
|
||||
this.notification_post = b.notification_post
|
||||
|
||||
this.notification_tag = b.notification_tag
|
||||
this.default_text = b.default_text
|
||||
this.default_sensitive = b.default_sensitive
|
||||
|
@ -334,6 +339,7 @@ class SavedAccount(
|
|||
private const val COL_NOTIFICATION_FOLLOW_REQUEST = "notification_follow_request" // スキーマ44
|
||||
private const val COL_NOTIFICATION_REACTION = "notification_reaction" // スキーマ33
|
||||
private const val COL_NOTIFICATION_VOTE = "notification_vote" // スキーマ33
|
||||
private const val COL_NOTIFICATION_POST = "notification_post" // スキーマ57
|
||||
|
||||
private const val COL_CONFIRM_FOLLOW = "confirm_follow" // スキーマ10
|
||||
private const val COL_CONFIRM_FOLLOW_LOCKED = "confirm_follow_locked" // スキーマ10
|
||||
|
@ -459,9 +465,12 @@ class SavedAccount(
|
|||
// スキーマ46から
|
||||
+ ",$COL_LAST_PUSH_ENDPOINT text"
|
||||
|
||||
// スキーマ66から
|
||||
// スキーマ56から
|
||||
+ ",$COL_DOMAIN text"
|
||||
|
||||
// スキーマ57から
|
||||
+ ",$COL_NOTIFICATION_POST integer default 1"
|
||||
|
||||
+ ")"
|
||||
)
|
||||
db.execSQL("create index if not exists ${table}_user on ${table}(u)")
|
||||
|
@ -594,8 +603,8 @@ class SavedAccount(
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(oldVersion < 33 && newVersion >= 33) {
|
||||
try {
|
||||
db.execSQL("alter table $table add column $COL_NOTIFICATION_REACTION integer default 1")
|
||||
|
@ -607,8 +616,8 @@ class SavedAccount(
|
|||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(oldVersion < 38 && newVersion >= 38) {
|
||||
try {
|
||||
db.execSQL("alter table $table add column $COL_DEFAULT_SENSITIVE integer default 0")
|
||||
|
@ -668,6 +677,14 @@ class SavedAccount(
|
|||
log.trace(ex)
|
||||
}
|
||||
}
|
||||
if(oldVersion < 57 && newVersion >= 57) {
|
||||
try {
|
||||
db.execSQL("alter table $table add column $COL_NOTIFICATION_POST integer default 1")
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 横断検索用の、何とも紐ついていないアカウント
|
||||
|
@ -681,6 +698,7 @@ class SavedAccount(
|
|||
dst.notification_mention = false
|
||||
dst.notification_reaction = false
|
||||
dst.notification_vote = false
|
||||
dst.notification_post = false
|
||||
|
||||
dst
|
||||
}
|
||||
|
@ -1009,6 +1027,8 @@ class SavedAccount(
|
|||
TootNotification.TYPE_POLL,
|
||||
TootNotification.TYPE_POLL_VOTE_MISSKEY -> notification_vote
|
||||
|
||||
TootNotification.TYPE_STATUS -> notification_post
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
|
|
@ -17,16 +17,16 @@ import jp.juggler.util.getStringOrNull
|
|||
|
||||
class UserRelation {
|
||||
|
||||
var following : Boolean = false // 認証ユーザからのフォロー状態にある
|
||||
var followed_by : Boolean = false // 認証ユーザは被フォロー状態にある
|
||||
var blocking : Boolean = false // 認証ユーザからブロックした
|
||||
var blocked_by : Boolean = false // 認証ユーザからブロックされた(Misskeyのみ。Mastodonでは常にfalse)
|
||||
var muting : Boolean = false
|
||||
var requested : Boolean = false // 認証ユーザからのフォローは申請中である
|
||||
var requested_by : Boolean = false // 相手から認証ユーザへのフォローリクエスト申請中(Misskeyのみ。Mastodonでは常にfalse)
|
||||
var following_reblogs : Int = 0 // このユーザからのブーストをTLに表示する
|
||||
var endorsed : Boolean = false // ユーザをプロフィールで紹介する
|
||||
|
||||
var following = false // 認証ユーザからのフォロー状態にある
|
||||
var followed_by = false // 認証ユーザは被フォロー状態にある
|
||||
var blocking = false // 認証ユーザからブロックした
|
||||
var blocked_by = false // 認証ユーザからブロックされた(Misskeyのみ。Mastodonでは常にfalse)
|
||||
var muting = false
|
||||
var requested = false // 認証ユーザからのフォローは申請中である
|
||||
var requested_by = false // 相手から認証ユーザへのフォローリクエスト申請中(Misskeyのみ。Mastodonでは常にfalse)
|
||||
var following_reblogs = 0 // このユーザからのブーストをTLに表示する
|
||||
var endorsed = false // ユーザをプロフィールで紹介する
|
||||
var notifying = false // ユーザの投稿を通知する
|
||||
var note : String? = null
|
||||
|
||||
// 認証ユーザからのフォロー状態
|
||||
|
@ -66,6 +66,7 @@ class UserRelation {
|
|||
private const val COL_BLOCKED_BY = "blocked_by"
|
||||
private const val COL_REQUESTED_BY = "requested_by"
|
||||
private const val COL_NOTE = "note"
|
||||
private const val COL_NOTIFYING = "notifying"
|
||||
|
||||
private const val DB_ID_PSEUDO = - 2L
|
||||
|
||||
|
@ -88,6 +89,7 @@ class UserRelation {
|
|||
,$COL_BLOCKED_BY integer default 0
|
||||
,$COL_REQUESTED_BY integer default 0
|
||||
,$COL_NOTE text default null
|
||||
,$COL_NOTIFYING integer default 0
|
||||
)"""
|
||||
)
|
||||
db.execSQL(
|
||||
|
@ -131,6 +133,13 @@ class UserRelation {
|
|||
log.trace(ex)
|
||||
}
|
||||
}
|
||||
if(oldVersion < 58 && newVersion >= 58) {
|
||||
try {
|
||||
db.execSQL("alter table $table add column $COL_NOTIFYING integer default 0")
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteOld(now : Long) {
|
||||
|
@ -167,6 +176,8 @@ class UserRelation {
|
|||
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())
|
||||
cv.put(COL_NOTIFYING, src.notifying.b2i())
|
||||
|
||||
cv.putOrNull(COL_NOTE, src.note)
|
||||
App1.database.replaceOrThrow(table, null, cv)
|
||||
|
||||
|
@ -197,6 +208,8 @@ class UserRelation {
|
|||
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())
|
||||
cv.put(COL_NOTIFYING, src.notifying.b2i())
|
||||
|
||||
cv.putOrNull(COL_NOTE, src.note)
|
||||
App1.database.replaceOrThrow(table, null, cv)
|
||||
val key = String.format("%s:%s", db_id, id)
|
||||
|
@ -282,6 +295,8 @@ class UserRelation {
|
|||
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())
|
||||
cv.put(COL_NOTIFYING, src.notifying.b2i())
|
||||
|
||||
cv.putOrNull(COL_NOTE, src.note)
|
||||
db.replaceOrThrow(table, null, cv)
|
||||
}
|
||||
|
@ -323,6 +338,8 @@ class UserRelation {
|
|||
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())
|
||||
cv.put(COL_NOTIFYING, src.notifying.b2i())
|
||||
|
||||
cv.putOrNull(COL_NOTE, src.note)
|
||||
db.replace(table, null, cv)
|
||||
}
|
||||
|
@ -382,6 +399,8 @@ class UserRelation {
|
|||
dst.endorsed = cursor.getBoolean(COL_ENDORSED)
|
||||
dst.blocked_by = cursor.getBoolean(COL_BLOCKED_BY)
|
||||
dst.requested_by = cursor.getBoolean(COL_REQUESTED_BY)
|
||||
dst.notifying = cursor.getBoolean(COL_NOTIFYING)
|
||||
|
||||
dst.note = cursor.getStringOrNull(COL_NOTE)
|
||||
return dst
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ class PushSubscriptionHelper(
|
|||
account.notification_mention.booleanToInt(8) +
|
||||
(account.isMisskey && account.notification_reaction).booleanToInt(16) +
|
||||
account.notification_vote.booleanToInt(32) +
|
||||
account.notification_follow_request.booleanToInt(64)
|
||||
account.notification_follow_request.booleanToInt(64) +
|
||||
account.notification_post.booleanToInt(128)
|
||||
}
|
||||
|
||||
val log : String
|
||||
|
@ -224,7 +225,7 @@ class PushSubscriptionHelper(
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateSubscriptionMastodon(client : TootApiClient) : TootApiResult? {
|
||||
private fun updateSubscriptionMastodon(client : TootApiClient,force:Boolean) : TootApiResult? {
|
||||
// 現在の購読状態を取得
|
||||
// https://github.com/tootsuite/mastodon/pull/7471
|
||||
// https://github.com/tootsuite/mastodon/pull/7472
|
||||
|
@ -315,7 +316,7 @@ class PushSubscriptionHelper(
|
|||
val endpoint =
|
||||
"${PollingWorker.APP_SERVER}/webpushcallback/${device_id.encodePercent()}/${account.acct.ascii.encodePercent()}/$flags/$clientIdentifier"
|
||||
|
||||
if(oldSubscription?.endpoint == endpoint) {
|
||||
if(oldSubscription?.endpoint == endpoint && !force) {
|
||||
// 既に登録済みで、endpointも一致している
|
||||
subscribed = true
|
||||
if(verbose) addLog(context.getString(R.string.push_subscription_already_exists))
|
||||
|
@ -382,9 +383,7 @@ class PushSubscriptionHelper(
|
|||
} else {
|
||||
// 通知設定が空ではないので購読を行いたい
|
||||
|
||||
r = client.request(
|
||||
"/api/v1/push/subscription",
|
||||
JsonObject().apply {
|
||||
val params = JsonObject().apply {
|
||||
put("subscription", JsonObject().apply {
|
||||
put("endpoint", endpoint)
|
||||
put("keys", JsonObject().apply {
|
||||
|
@ -403,10 +402,14 @@ class PushSubscriptionHelper(
|
|||
put("mention", account.notification_mention)
|
||||
put("poll", account.notification_vote)
|
||||
put("follow_request", account.notification_follow_request)
|
||||
put("status",account.notification_post)
|
||||
})
|
||||
})
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
|
||||
r = client.request(
|
||||
"/api/v1/push/subscription",
|
||||
params.toPostRequestBuilder()
|
||||
) ?: return null
|
||||
|
||||
res = r.response ?: return r
|
||||
|
@ -444,7 +447,7 @@ class PushSubscriptionHelper(
|
|||
}
|
||||
}
|
||||
|
||||
fun updateSubscription(client : TootApiClient) : TootApiResult? =
|
||||
fun updateSubscription(client : TootApiClient,force:Boolean = false) : TootApiResult? =
|
||||
try {
|
||||
when {
|
||||
isRecentlyChecked() ->
|
||||
|
@ -457,7 +460,7 @@ class PushSubscriptionHelper(
|
|||
updateSubscriptionMisskey(client)
|
||||
|
||||
else ->
|
||||
updateSubscriptionMastodon(client)
|
||||
updateSubscriptionMastodon(client,force)
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
TootApiResult(ex.withCaption("error."))
|
||||
|
|
|
@ -592,6 +592,13 @@
|
|||
android:text="@string/vote_polls" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout style="@style/setting_row_form">
|
||||
<CheckBox
|
||||
android:id="@+id/cbNotificationPost"
|
||||
style="@style/setting_horizontal_stretch"
|
||||
android:text="@string/notification_type_post" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout style="@style/setting_row_form">
|
||||
|
||||
<Button
|
||||
|
|
|
@ -904,6 +904,19 @@
|
|||
android:visibility="gone"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnPostNotification"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/btn_bg_transparent_round6dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:minHeight="32dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnNickname"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -207,6 +207,7 @@
|
|||
<string name="display_name_follow_request_accepted_by">%1$sがあなたのフォローリクエストを承認しました</string>
|
||||
<string name="display_name_followed_by">%1$sにフォローされました</string>
|
||||
<string name="display_name_quoted_by">%1$sが引用しました</string>
|
||||
<string name="display_name_posted_by">%1$sが投稿しました</string>
|
||||
<string name="display_name_reaction_by">%1$sがリアクション</string>
|
||||
<string name="display_name_replied_by">%1$sからの返信</string>
|
||||
<string name="display_name_mentioned_by">%1$sからのメンション</string>
|
||||
|
@ -500,6 +501,7 @@
|
|||
<string name="notification_type_mention">返信</string>
|
||||
<string name="notification_type_reaction">リアクション</string>
|
||||
<string name="notification_type_vote">投票</string>
|
||||
<string name="notification_type_post">投稿</string>
|
||||
<string name="notifications">通知</string>
|
||||
<string name="nsfw">NSFW</string>
|
||||
<string name="ok">OK</string>
|
||||
|
@ -1045,4 +1047,6 @@
|
|||
<string name="gap_tail">ギャップの終端</string>
|
||||
<string name="ignore_text_in_shared_media">外部アプリから共有されたメディアに付属する余計なテキストを追加しない</string>
|
||||
<string name="input_sharp_itself">\'#\'だけを入力</string>
|
||||
<string name="notify_posts_from_this_user">このユーザの投稿を通知する</string>
|
||||
<string name="stop_notify_posts_from_this_user">このユーザの投稿の通知を解除</string>
|
||||
</resources>
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
<string name="display_name_follow_request_by">%1$s sent follow request</string>
|
||||
<string name="display_name_follow_request_accepted_by">%1$s accepted your follow request</string>
|
||||
<string name="display_name_quoted_by">%1$s quoted</string>
|
||||
<string name="display_name_posted_by">%1$s posted</string>
|
||||
<string name="display_name_reaction_by">%1$s reactioned</string>
|
||||
<string name="display_name_followed_by">%1$s is following you</string>
|
||||
<string name="display_name_unfollowed_by">%1$s unfollowed you</string>
|
||||
|
@ -632,6 +633,8 @@
|
|||
<string name="notification_type_favourite">fav.</string>
|
||||
<string name="notification_type_reaction">reaction</string>
|
||||
<string name="notification_type_vote">vote</string>
|
||||
<string name="notification_type_post">post</string>
|
||||
|
||||
<string name="dont_show_normal_toot">Don\'t show normal toot</string>
|
||||
<string name="dont_show_non_public_toot">Don\'t show non-public toot</string>
|
||||
<string name="set_focus_point">set focus point (Mastodon 2.3+)</string>
|
||||
|
@ -1053,4 +1056,6 @@
|
|||
<string name="gap_tail">Tail of gap</string>
|
||||
<string name="ignore_text_in_shared_media">Don\'t append extra text that come with shared media from external apps</string>
|
||||
<string name="input_sharp_itself">Input \'#\' itself</string>
|
||||
<string name="notify_posts_from_this_user">Notify posts from this user</string>
|
||||
<string name="stop_notify_posts_from_this_user">Stop notify posts from this user</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue