Show the follower's bio/note in a "followed you" notification (#3281)

This makes the notification view for a follow request contain more info about the new follower, and makes the layout (of their name / username) consistent with other notifications that show names/usernames.
This commit is contained in:
Nik Clayton 2023-04-24 12:09:34 +02:00 committed by GitHub
parent af2727b633
commit f1b3faf85f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 35 additions and 7 deletions

View file

@ -64,6 +64,7 @@ data class ConversationAccountEntity(
localUsername = localUsername, localUsername = localUsername,
username = username, username = username,
displayName = displayName, displayName = displayName,
note = "",
url = "", url = "",
avatar = avatar, avatar = avatar,
emojis = emojis emojis = emojis

View file

@ -25,6 +25,7 @@ import com.keylesspalace.tusky.entity.TimelineAccount
import com.keylesspalace.tusky.util.StatusDisplayOptions import com.keylesspalace.tusky.util.StatusDisplayOptions
import com.keylesspalace.tusky.util.emojify import com.keylesspalace.tusky.util.emojify
import com.keylesspalace.tusky.util.loadAvatar import com.keylesspalace.tusky.util.loadAvatar
import com.keylesspalace.tusky.util.parseAsMastodonHtml
import com.keylesspalace.tusky.util.unicodeWrap import com.keylesspalace.tusky.util.unicodeWrap
import com.keylesspalace.tusky.viewdata.NotificationViewData import com.keylesspalace.tusky.viewdata.NotificationViewData
@ -92,6 +93,12 @@ class FollowViewHolder(
avatarRadius42dp, avatarRadius42dp,
animateAvatars animateAvatars
) )
binding.notificationAccountNote.text = account.note.parseAsMastodonHtml().emojify(
account.emojis,
binding.notificationAccountNote,
animateEmojis
)
} }
private fun setupButtons(listener: NotificationActionListener, accountId: String) { private fun setupButtons(listener: NotificationActionListener, accountId: String) {

View file

@ -63,6 +63,7 @@ fun TimelineAccountEntity.toAccount(gson: Gson): TimelineAccount {
localUsername = localUsername, localUsername = localUsername,
username = username, username = username,
displayName = displayName, displayName = displayName,
note = "",
url = url, url = url,
avatar = avatar, avatar = avatar,
bot = bot, bot = bot,

View file

@ -28,6 +28,7 @@ data class TimelineAccount(
@SerializedName("display_name") val displayName: String?, // should never be null per Api definition, but some servers break the contract @SerializedName("display_name") val displayName: String?, // should never be null per Api definition, but some servers break the contract
val url: String, val url: String,
val avatar: String, val avatar: String,
val note: String,
val bot: Boolean = false, val bot: Boolean = false,
val emojis: List<Emoji>? = emptyList() // nullable for backward compatibility val emojis: List<Emoji>? = emptyList() // nullable for backward compatibility
) { ) {

View file

@ -47,12 +47,14 @@
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:paddingEnd="@dimen/status_display_name_padding_end"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textSize="?attr/status_text_medium" android:textSize="?attr/status_text_medium"
android:textStyle="normal|bold" android:textStyle="normal|bold"
app:layout_constraintStart_toEndOf="@id/notification_avatar" app:layout_constraintStart_toEndOf="@id/notification_avatar"
app:layout_constraintTop_toBottomOf="@+id/notification_text" app:layout_constraintTop_toBottomOf="@+id/notification_text"
tools:text="Test User" /> tools:text="Test User"
tools:ignore="RtlSymmetry" />
<TextView <TextView
android:id="@+id/notification_username" android:id="@+id/notification_username"
@ -62,8 +64,22 @@
android:maxLines="1" android:maxLines="1"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:textSize="?attr/status_text_medium" android:textSize="?attr/status_text_medium"
app:layout_constraintStart_toStartOf="@+id/notification_display_name" app:layout_constraintStart_toEndOf="@+id/notification_display_name"
app:layout_constraintTop_toBottomOf="@id/notification_display_name" app:layout_constraintTop_toTopOf="@+id/notification_display_name"
tools:text="\@testuser" /> tools:text="\@testuser" />
<TextView
android:id="@+id/notification_account_note"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:hyphenationFrequency="full"
android:textSize="?attr/status_text_medium"
android:textIsSelectable="true"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/notification_display_name"
app:layout_constraintTop_toBottomOf="@+id/notification_display_name"
tools:text="Account note" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -56,6 +56,7 @@ class BottomSheetActivityTest {
localUsername = "admin", localUsername = "admin",
username = "admin", username = "admin",
displayName = "Ad Min", displayName = "Ad Min",
note = "This is their bio",
url = "http://mastodon.foo.bar/@User", url = "http://mastodon.foo.bar/@User",
avatar = "" avatar = ""
) )

View file

@ -100,6 +100,7 @@ class MainActivityTest {
localUsername = "connyduck", localUsername = "connyduck",
username = "connyduck@mastodon.example", username = "connyduck@mastodon.example",
displayName = "Conny Duck", displayName = "Conny Duck",
note = "This is their bio",
url = "https://mastodon.example/@ConnyDuck", url = "https://mastodon.example/@ConnyDuck",
avatar = "https://mastodon.example/system/accounts/avatars/000/150/486/original/ab27d7ddd18a10ea.jpg" avatar = "https://mastodon.example/system/accounts/avatars/000/150/486/original/ab27d7ddd18a10ea.jpg"
), ),

View file

@ -33,8 +33,8 @@ class StatusComparisonTest {
} }
@Test @Test
fun `accounts with different notes in json - should be equal because notes are not relevant for timelines`() { fun `accounts with different notes in json - should not be equal`() {
assertEquals(createStatus(note = "Test"), createStatus(note = "Test 123456")) assertNotEquals(createStatus(note = "Test"), createStatus(note = "Test 123456"))
} }
private val gson = Gson() private val gson = Gson()

View file

@ -5,7 +5,6 @@ import com.keylesspalace.tusky.db.TimelineStatusWithAccount
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.entity.TimelineAccount import com.keylesspalace.tusky.entity.TimelineAccount
import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.StatusViewData
import java.util.ArrayList
import java.util.Date import java.util.Date
private val fixedDate = Date(1638889052000) private val fixedDate = Date(1638889052000)
@ -26,6 +25,7 @@ fun mockStatus(
localUsername = "connyduck", localUsername = "connyduck",
username = "connyduck@mastodon.example", username = "connyduck@mastodon.example",
displayName = "Conny Duck", displayName = "Conny Duck",
note = "This is their bio",
url = "https://mastodon.example/@ConnyDuck", url = "https://mastodon.example/@ConnyDuck",
avatar = "https://mastodon.example/system/accounts/avatars/000/150/486/original/ab27d7ddd18a10ea.jpg" avatar = "https://mastodon.example/system/accounts/avatars/000/150/486/original/ab27d7ddd18a10ea.jpg"
), ),