mirror of
https://github.com/pachli/pachli-android.git
synced 2025-02-02 18:37:00 +01:00
feat: Notify the user about severed relationships (#557)
This commit is contained in:
parent
a65e2bd937
commit
783d4e5cca
@ -707,7 +707,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="92"
|
||||
line="101"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@ -718,7 +718,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="279"
|
||||
line="288"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@ -729,7 +729,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="328"
|
||||
line="339"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@ -740,7 +740,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="447"
|
||||
line="458"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@ -751,7 +751,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="625"
|
||||
line="636"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@ -1301,7 +1301,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="94"
|
||||
line="103"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1312,7 +1312,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="102"
|
||||
line="111"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1323,7 +1323,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="136"
|
||||
line="145"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1334,7 +1334,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="195"
|
||||
line="204"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1345,7 +1345,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="216"
|
||||
line="225"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1356,7 +1356,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="217"
|
||||
line="226"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1367,7 +1367,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="240"
|
||||
line="249"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1378,7 +1378,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="269"
|
||||
line="278"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1389,7 +1389,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="338"
|
||||
line="349"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1400,7 +1400,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="378"
|
||||
line="389"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1411,7 +1411,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="414"
|
||||
line="425"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1422,7 +1422,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="417"
|
||||
line="428"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1433,7 +1433,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="418"
|
||||
line="429"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1444,7 +1444,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="419"
|
||||
line="430"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1455,7 +1455,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="420"
|
||||
line="431"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1466,7 +1466,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="421"
|
||||
line="432"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1477,7 +1477,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="485"
|
||||
line="496"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1488,7 +1488,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="486"
|
||||
line="497"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1499,7 +1499,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="497"
|
||||
line="508"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1510,7 +1510,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="498"
|
||||
line="509"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1521,7 +1521,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="499"
|
||||
line="510"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1532,7 +1532,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="501"
|
||||
line="512"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1543,7 +1543,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="541"
|
||||
line="552"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1554,7 +1554,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="582"
|
||||
line="593"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1565,7 +1565,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="588"
|
||||
line="599"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1576,7 +1576,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="617"
|
||||
line="628"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@ -1587,7 +1587,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/values/strings.xml"
|
||||
line="644"
|
||||
line="655"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
|
@ -51,6 +51,7 @@ import app.pachli.core.designsystem.R as DR
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.MainActivityIntent
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.model.RelationshipSeveranceEvent
|
||||
import app.pachli.core.network.parseAsMastodonHtml
|
||||
import app.pachli.receiver.SendStatusBroadcastReceiver
|
||||
import app.pachli.viewdata.buildDescription
|
||||
@ -93,6 +94,7 @@ private const val CHANNEL_SUBSCRIPTIONS = "CHANNEL_SUBSCRIPTIONS"
|
||||
private const val CHANNEL_SIGN_UP = "CHANNEL_SIGN_UP"
|
||||
private const val CHANNEL_UPDATES = "CHANNEL_UPDATES"
|
||||
private const val CHANNEL_REPORT = "CHANNEL_REPORT"
|
||||
private const val CHANNEL_SEVERED_RELATIONSHIPS = "CHANNEL_SEVERED_RELATIONSHIPS"
|
||||
private const val CHANNEL_BACKGROUND_TASKS = "CHANNEL_BACKGROUND_TASKS"
|
||||
|
||||
/** WorkManager Tag */
|
||||
@ -503,6 +505,7 @@ fun createNotificationChannelsForAccount(account: AccountEntity, context: Contex
|
||||
CHANNEL_SIGN_UP + account.identifier,
|
||||
CHANNEL_UPDATES + account.identifier,
|
||||
CHANNEL_REPORT + account.identifier,
|
||||
CHANNEL_SEVERED_RELATIONSHIPS + account.identifier,
|
||||
)
|
||||
val channelNames = intArrayOf(
|
||||
R.string.notification_mention_name,
|
||||
@ -515,6 +518,7 @@ fun createNotificationChannelsForAccount(account: AccountEntity, context: Contex
|
||||
R.string.notification_sign_up_name,
|
||||
R.string.notification_update_name,
|
||||
R.string.notification_report_name,
|
||||
R.string.notification_severed_relationships_name,
|
||||
)
|
||||
val channelDescriptions = intArrayOf(
|
||||
R.string.notification_mention_descriptions,
|
||||
@ -527,6 +531,7 @@ fun createNotificationChannelsForAccount(account: AccountEntity, context: Contex
|
||||
R.string.notification_sign_up_description,
|
||||
R.string.notification_update_description,
|
||||
R.string.notification_report_description,
|
||||
R.string.notification_severed_relationships_description,
|
||||
)
|
||||
val channels: MutableList<NotificationChannel> = ArrayList(6)
|
||||
val channelGroup = NotificationChannelGroup(account.identifier, account.fullName)
|
||||
@ -684,7 +689,8 @@ fun filterNotification(
|
||||
Notification.Type.SIGN_UP -> account.notificationsSignUps
|
||||
Notification.Type.UPDATE -> account.notificationsUpdates
|
||||
Notification.Type.REPORT -> account.notificationsReports
|
||||
else -> false
|
||||
Notification.Type.SEVERED_RELATIONSHIPS -> account.notificationsSeveredRelationships
|
||||
Notification.Type.UNKNOWN -> false
|
||||
}
|
||||
}
|
||||
|
||||
@ -704,7 +710,8 @@ private fun getChannelId(account: AccountEntity, type: Notification.Type): Strin
|
||||
Notification.Type.SIGN_UP -> CHANNEL_SIGN_UP + account.identifier
|
||||
Notification.Type.UPDATE -> CHANNEL_UPDATES + account.identifier
|
||||
Notification.Type.REPORT -> CHANNEL_REPORT + account.identifier
|
||||
else -> null
|
||||
Notification.Type.SEVERED_RELATIONSHIPS -> CHANNEL_SEVERED_RELATIONSHIPS + account.identifier
|
||||
Notification.Type.UNKNOWN -> null
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,6 +841,13 @@ private fun titleForType(
|
||||
return context.getString(R.string.notification_report_format, account.domain)
|
||||
}
|
||||
|
||||
Notification.Type.SEVERED_RELATIONSHIPS -> {
|
||||
return context.getString(
|
||||
R.string.notification_severed_relationships_format,
|
||||
notification.relationshipSeveranceEvent?.targetName,
|
||||
)
|
||||
}
|
||||
|
||||
Notification.Type.UNKNOWN -> return null
|
||||
}
|
||||
}
|
||||
@ -890,6 +904,15 @@ private fun bodyForType(
|
||||
report.targetAccount.name.unicodeWrap(),
|
||||
)
|
||||
}
|
||||
Notification.Type.SEVERED_RELATIONSHIPS -> {
|
||||
val resourceId = when (notification.relationshipSeveranceEvent!!.type) {
|
||||
RelationshipSeveranceEvent.Type.DOMAIN_BLOCK -> R.string.notification_severed_relationships_domain_block_body
|
||||
RelationshipSeveranceEvent.Type.USER_DOMAIN_BLOCK -> R.string.notification_severed_relationships_user_domain_block_body
|
||||
RelationshipSeveranceEvent.Type.ACCOUNT_SUSPENSION -> R.string.notification_severed_relationships_account_suspension_body
|
||||
RelationshipSeveranceEvent.Type.UNKNOWN -> R.string.notification_severed_relationships_unknown_body
|
||||
}
|
||||
return context.getString(resourceId)
|
||||
}
|
||||
|
||||
Notification.Type.UNKNOWN -> return null
|
||||
Notification.Type.UPDATE -> return null
|
||||
|
@ -727,4 +727,5 @@ fun Notification.Type.uiString(): Int = when (this) {
|
||||
Notification.Type.SIGN_UP -> R.string.notification_sign_up_name
|
||||
Notification.Type.UPDATE -> R.string.notification_update_name
|
||||
Notification.Type.REPORT -> R.string.notification_report_name
|
||||
Notification.Type.SEVERED_RELATIONSHIPS -> R.string.notification_severed_relationships_name
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import app.pachli.core.network.model.Status
|
||||
import app.pachli.databinding.ItemFollowBinding
|
||||
import app.pachli.databinding.ItemFollowRequestBinding
|
||||
import app.pachli.databinding.ItemReportNotificationBinding
|
||||
import app.pachli.databinding.ItemSeveredRelationshipsBinding
|
||||
import app.pachli.databinding.ItemStatusBinding
|
||||
import app.pachli.databinding.ItemStatusNotificationBinding
|
||||
import app.pachli.databinding.ItemStatusWrapperBinding
|
||||
@ -51,6 +52,9 @@ enum class NotificationViewKind {
|
||||
FOLLOW,
|
||||
FOLLOW_REQUEST,
|
||||
REPORT,
|
||||
|
||||
/** View details of the affected target, number of relationships affected, and the actor */
|
||||
SEVERED_RELATIONSHIPS,
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
@ -71,6 +75,7 @@ enum class NotificationViewKind {
|
||||
-> FOLLOW
|
||||
Notification.Type.FOLLOW_REQUEST -> FOLLOW_REQUEST
|
||||
Notification.Type.REPORT -> REPORT
|
||||
Notification.Type.SEVERED_RELATIONSHIPS -> SEVERED_RELATIONSHIPS
|
||||
null -> UNKNOWN
|
||||
}
|
||||
}
|
||||
@ -181,6 +186,11 @@ class NotificationsPagingAdapter(
|
||||
notificationActionListener,
|
||||
)
|
||||
}
|
||||
NotificationViewKind.SEVERED_RELATIONSHIPS -> {
|
||||
SeveredRelationshipsViewHolder(
|
||||
ItemSeveredRelationshipsBinding.inflate(inflater, parent, false),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
FallbackNotificationViewHolder(
|
||||
SimpleListItem1Binding.inflate(inflater, parent, false),
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2024 Pachli Association
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package app.pachli.components.notifications
|
||||
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import app.pachli.R
|
||||
import app.pachli.adapter.StatusBaseViewHolder
|
||||
import app.pachli.core.network.model.RelationshipSeveranceEvent
|
||||
import app.pachli.databinding.ItemSeveredRelationshipsBinding
|
||||
import app.pachli.util.StatusDisplayOptions
|
||||
import app.pachli.util.getRelativeTimeSpanString
|
||||
import app.pachli.viewdata.NotificationViewData
|
||||
import java.util.Date
|
||||
|
||||
class SeveredRelationshipsViewHolder(
|
||||
private val binding: ItemSeveredRelationshipsBinding,
|
||||
) : NotificationsPagingAdapter.ViewHolder, RecyclerView.ViewHolder(binding.root) {
|
||||
override fun bind(viewData: NotificationViewData, payloads: List<*>?, statusDisplayOptions: StatusDisplayOptions) {
|
||||
val event = viewData.relationshipSeveranceEvent!!
|
||||
if (payloads.isNullOrEmpty()) {
|
||||
binding.notificationTopText.text = HtmlCompat.fromHtml(
|
||||
itemView.context.getString(
|
||||
R.string.notification_severed_relationships_format,
|
||||
event.targetName,
|
||||
),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY,
|
||||
)
|
||||
|
||||
binding.datetime.text = getRelativeTimeSpanString(itemView.context, event.createdAt.time, Date().time)
|
||||
|
||||
binding.notificationSummary.text = itemView.context.resources.getQuantityString(
|
||||
R.plurals.notification_severed_relationships_summary_report_fmt,
|
||||
event.relationshipsCount,
|
||||
event.relationshipsCount,
|
||||
)
|
||||
|
||||
val resourceId = when (event.type) {
|
||||
RelationshipSeveranceEvent.Type.DOMAIN_BLOCK -> R.string.notification_severed_relationships_domain_block_body
|
||||
RelationshipSeveranceEvent.Type.USER_DOMAIN_BLOCK -> R.string.notification_severed_relationships_user_domain_block_body
|
||||
RelationshipSeveranceEvent.Type.ACCOUNT_SUSPENSION -> R.string.notification_severed_relationships_account_suspension_body
|
||||
RelationshipSeveranceEvent.Type.UNKNOWN -> R.string.notification_severed_relationships_unknown_body
|
||||
}
|
||||
binding.notificationCategory.text = itemView.context.getString(resourceId)
|
||||
} else {
|
||||
if (payloads.any { it == StatusBaseViewHolder.Key.KEY_CREATED }) {
|
||||
binding.datetime.text = getRelativeTimeSpanString(itemView.context, event.createdAt.time, Date().time)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import app.pachli.core.database.model.TranslatedStatusEntity
|
||||
import app.pachli.core.database.model.TranslationState
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.model.RelationshipSeveranceEvent
|
||||
import app.pachli.core.network.model.Report
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.model.TimelineAccount
|
||||
@ -40,6 +41,7 @@ data class NotificationViewData(
|
||||
val account: TimelineAccount,
|
||||
var statusViewData: StatusViewData?,
|
||||
val report: Report?,
|
||||
val relationshipSeveranceEvent: RelationshipSeveranceEvent?,
|
||||
) : IStatusViewData {
|
||||
companion object {
|
||||
fun from(
|
||||
@ -62,6 +64,7 @@ data class NotificationViewData(
|
||||
)
|
||||
},
|
||||
notification.report,
|
||||
notification.relationshipSeveranceEvent,
|
||||
)
|
||||
}
|
||||
|
||||
|
95
app/src/main/res/layout/item_severed_relationships.xml
Normal file
95
app/src/main/res/layout/item_severed_relationships.xml
Normal file
@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2024 Pachli Association
|
||||
~
|
||||
~ This file is a part of Pachli.
|
||||
~
|
||||
~ This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
~ GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
~ License, or (at your option) any later version.
|
||||
~
|
||||
~ Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
~ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
~ Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
~ see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/notification_report"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="14dp"
|
||||
android:paddingRight="14dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="28dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_flag_24dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notification_top_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="top"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toStartOf="@id/datetime"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Relationship with example.com severed"
|
||||
tools:ignore="SelectableText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/datetime"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/notification_top_text"
|
||||
tools:text="14h"
|
||||
tools:ignore="SelectableText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notification_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hyphenationFrequency="full"
|
||||
android:importantForAccessibility="no"
|
||||
android:lineSpacingMultiplier="1.1"
|
||||
android:textColor="?android:textColorTertiary"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
app:layout_constraintStart_toStartOf="@+id/notification_top_text"
|
||||
app:layout_constraintTop_toBottomOf="@+id/notification_top_text"
|
||||
tools:text="2 relationships"
|
||||
tools:ignore="SelectableText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notification_category"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hyphenationFrequency="full"
|
||||
android:importantForAccessibility="no"
|
||||
android:lineSpacingMultiplier="1.1"
|
||||
android:paddingBottom="10dp"
|
||||
android:textColor="?android:textColorTertiary"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
app:layout_constraintStart_toStartOf="@+id/notification_summary"
|
||||
app:layout_constraintTop_toBottomOf="@id/notification_summary"
|
||||
tools:text="@string/notification_severed_relationships_domain_block_body"
|
||||
tools:ignore="SelectableText" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -88,6 +88,15 @@
|
||||
<string name="notification_subscription_format">%s just posted</string>
|
||||
<string name="notification_update_format">%s edited their post</string>
|
||||
<string name="notification_report_format">New report on %s</string>
|
||||
<string name="notification_severed_relationships_format">Relationship with <b>%1$s</b> severed</string>
|
||||
<string name="notification_severed_relationships_domain_block_body">A moderator suspended the domain</string>
|
||||
<string name="notification_severed_relationships_user_domain_block_body">You blocked the domain</string>
|
||||
<string name="notification_severed_relationships_account_suspension_body">A moderator suspended the account</string>
|
||||
<string name="notification_severed_relationships_unknown_body">Unknown reason</string>
|
||||
<plurals name="notification_severed_relationships_summary_report_fmt">
|
||||
<item quantity="one">%1$d relationship severed</item>
|
||||
<item quantity="other">%1$d relationships severed</item>
|
||||
</plurals>
|
||||
<string name="notification_header_report_format">%s reported %s</string>
|
||||
<string name="notification_summary_report_format">%s · %d posts attached</string>
|
||||
<string name="report_username_format">Report @%s</string>
|
||||
@ -321,6 +330,8 @@
|
||||
<string name="notification_update_description">Notifications when posts you\'ve interacted with are edited</string>
|
||||
<string name="notification_report_name">Reports</string>
|
||||
<string name="notification_report_description">Notifications about moderation reports</string>
|
||||
<string name="notification_severed_relationships_name">Severed relationships</string>
|
||||
<string name="notification_severed_relationships_description">Notifications about severed relationships</string>
|
||||
<string name="notification_listenable_worker_name">Background activity</string>
|
||||
<string name="notification_listenable_worker_description">Notifications when Pachli is working in the background</string>
|
||||
<string name="notification_unknown_name">Unknown</string>
|
||||
|
1197
core/database/schemas/app.pachli.core.database.AppDatabase/5.json
Normal file
1197
core/database/schemas/app.pachli.core.database.AppDatabase/5.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -55,11 +55,12 @@ import app.pachli.core.database.model.TranslatedStatusEntity
|
||||
TranslatedStatusEntity::class,
|
||||
LogEntryEntity::class,
|
||||
],
|
||||
version = 4,
|
||||
version = 5,
|
||||
autoMigrations = [
|
||||
AutoMigration(from = 1, to = 2, spec = AppDatabase.MIGRATE_1_2::class),
|
||||
AutoMigration(from = 2, to = 3),
|
||||
AutoMigration(from = 3, to = 4),
|
||||
AutoMigration(from = 4, to = 5),
|
||||
],
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
@ -61,6 +61,8 @@ data class AccountEntity(
|
||||
var notificationsSignUps: Boolean = true,
|
||||
var notificationsUpdates: Boolean = true,
|
||||
var notificationsReports: Boolean = true,
|
||||
@ColumnInfo(defaultValue = "true")
|
||||
var notificationsSeveredRelationships: Boolean = true,
|
||||
var notificationSound: Boolean = true,
|
||||
var notificationVibration: Boolean = true,
|
||||
var notificationLight: Boolean = true,
|
||||
|
@ -31,6 +31,7 @@ data class Notification(
|
||||
val account: TimelineAccount,
|
||||
val status: Status?,
|
||||
val report: Report?,
|
||||
val relationshipSeveranceEvent: RelationshipSeveranceEvent? = null,
|
||||
) {
|
||||
|
||||
/** From https://docs.joinmastodon.org/entities/Notification/#type */
|
||||
@ -80,6 +81,10 @@ data class Notification(
|
||||
/** A new report has been filed */
|
||||
@Json(name = "admin.report")
|
||||
REPORT("admin.report"),
|
||||
|
||||
/** Some of your follow relationships have been severed as a result of a moderation or block event */
|
||||
@Json(name = "severed_relationships")
|
||||
SEVERED_RELATIONSHIPS("severed_relationships"),
|
||||
;
|
||||
|
||||
companion object {
|
||||
@ -87,7 +92,19 @@ data class Notification(
|
||||
fun byString(s: String) = entries.firstOrNull { s == it.presentation } ?: UNKNOWN
|
||||
|
||||
/** Notification types for UI display (omits UNKNOWN) */
|
||||
val visibleTypes = listOf(MENTION, REBLOG, FAVOURITE, FOLLOW, FOLLOW_REQUEST, POLL, STATUS, SIGN_UP, UPDATE, REPORT)
|
||||
val visibleTypes = listOf(
|
||||
MENTION,
|
||||
REBLOG,
|
||||
FAVOURITE,
|
||||
FOLLOW,
|
||||
FOLLOW_REQUEST,
|
||||
POLL,
|
||||
STATUS,
|
||||
SIGN_UP,
|
||||
UPDATE,
|
||||
REPORT,
|
||||
SEVERED_RELATIONSHIPS,
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2024 Pachli Association
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package app.pachli.core.network.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import java.util.Date
|
||||
|
||||
/**
|
||||
* Summary of a moderation or block event that caused follow relationships to be severed.
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RelationshipSeveranceEvent(
|
||||
/** The ID of the relationship severance event in the database. */
|
||||
val id: String,
|
||||
/** Type of event. */
|
||||
val type: Type = Type.UNKNOWN,
|
||||
/**
|
||||
* True if the list of severed relationships is unavailable because the underlying
|
||||
* issue has been purged.
|
||||
*/
|
||||
val purged: Boolean,
|
||||
/**
|
||||
* Name of the target of the moderation/block event. This is either a domain name or
|
||||
* a user handle, depending on the event type.
|
||||
*/
|
||||
@Json(name = "target_name")
|
||||
val targetName: String,
|
||||
/** Number of follow relationships (in either direction) that were severed. */
|
||||
@Json(name = "relationships_count")
|
||||
val relationshipsCount: Int = 0,
|
||||
/** When the event took place. */
|
||||
@Json(name = "created_at")
|
||||
val createdAt: Date,
|
||||
) {
|
||||
enum class Type {
|
||||
/** A moderator suspended a whole domain */
|
||||
@Json(name = "domain_block")
|
||||
DOMAIN_BLOCK,
|
||||
|
||||
/** The user blocked a whole domain */
|
||||
@Json(name = "user_domain_block")
|
||||
USER_DOMAIN_BLOCK,
|
||||
|
||||
/** A moderator suspended a specific account */
|
||||
@Json(name = "account_suspension")
|
||||
ACCOUNT_SUSPENSION,
|
||||
UNKNOWN,
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user