fix crash when there are reblogs in notification statuses (#4638)
```
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:961)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:89)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:101)
at com.keylesspalace.tusky.db.dao.TimelineStatusDao_Impl$insert$2.call(TimelineStatusDao_Impl.kt:345)
at com.keylesspalace.tusky.db.dao.TimelineStatusDao_Impl$insert$2.call(TimelineStatusDao_Impl.kt:340)
at androidx.room.CoroutinesRoom$Companion.execute(CoroutinesRoom.kt:56)
at com.keylesspalace.tusky.db.dao.TimelineStatusDao_Impl.insert(TimelineStatusDao_Impl.kt:340)
at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator.replaceNotificationRange(NotificationsRemoteMediator.kt:169)
at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator.access$replaceNotificationRange(NotificationsRemoteMediator.kt:36)
at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator$load$3.invokeSuspend(NotificationsRemoteMediator.kt:109)
at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator$load$3.invoke(Unknown Source:8)
at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator$load$3.invoke(Unknown Source:2)
at androidx.room.RoomDatabaseKt$withTransaction$transactionBlock$1.invokeSuspend(RoomDatabaseExt.kt:62)
at androidx.room.RoomDatabaseKt$withTransaction$transactionBlock$1.invoke(Unknown Source:8)
at androidx.room.RoomDatabaseKt$withTransaction$transactionBlock$1.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at androidx.room.RoomDatabaseKt$startTransactionCoroutine$2$1$1.invokeSuspend(RoomDatabaseExt.kt:103)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:95)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:69)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
at androidx.room.RoomDatabaseKt$startTransactionCoroutine$2$1.run(RoomDatabaseExt.kt:99)
at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.kt:36)
at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0)
at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at java.lang.Thread.run(Thread.java:1012)
```
It looks kinda weird because "x just posted" has a different user than
the actual post, but it works for groups I guess? And definitely better
than crashing.
<img
src="https://github.com/user-attachments/assets/8110ff17-674d-4f36-8df0-453a666856a6"
width="320"/>
closes #4563
This commit is contained in:
parent
4d73a3c2e3
commit
24f227fd4f
5 changed files with 29 additions and 10 deletions
|
|
@ -47,7 +47,7 @@ fun Notification.toEntity(
|
|||
type = type,
|
||||
id = id,
|
||||
accountId = account.id,
|
||||
statusId = status?.id,
|
||||
statusId = status?.reblog?.id ?: status?.id,
|
||||
reportId = report?.id,
|
||||
loading = false
|
||||
)
|
||||
|
|
|
|||
|
|
@ -164,10 +164,10 @@ class NotificationsRemoteMediator(
|
|||
val contentShowing = oldStatus?.contentShowing ?: (activeAccount.alwaysShowSensitiveMedia || !status.sensitive)
|
||||
val contentCollapsed = oldStatus?.contentCollapsed ?: true
|
||||
|
||||
accountDao.insert(status.account.toEntity(activeAccount.id))
|
||||
|
||||
val statusToInsert = status.reblog ?: status
|
||||
accountDao.insert(statusToInsert.account.toEntity(activeAccount.id))
|
||||
statusDao.insert(
|
||||
status.toEntity(
|
||||
statusToInsert.toEntity(
|
||||
tuskyAccountId = activeAccount.id,
|
||||
expanded = expanded,
|
||||
contentShowing = contentShowing,
|
||||
|
|
|
|||
|
|
@ -345,10 +345,11 @@ class NotificationsViewModel @Inject constructor(
|
|||
notificationsDao.insertReport(report.toEntity(account.id))
|
||||
}
|
||||
notification.status?.let { status ->
|
||||
accountDao.insert(status.account.toEntity(account.id))
|
||||
val statusToInsert = status.reblog ?: status
|
||||
accountDao.insert(statusToInsert.account.toEntity(account.id))
|
||||
|
||||
statusDao.insert(
|
||||
status.toEntity(
|
||||
statusToInsert.toEntity(
|
||||
tuskyAccountId = account.id,
|
||||
expanded = account.alwaysOpenSpoiler,
|
||||
contentShowing = account.alwaysShowSensitiveMedia || !status.sensitive,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.room.Room
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.keylesspalace.tusky.components.timeline.Placeholder
|
||||
import com.keylesspalace.tusky.components.timeline.fakeStatus
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.db.AppDatabase
|
||||
import com.keylesspalace.tusky.db.Converters
|
||||
|
|
@ -215,7 +216,17 @@ class NotificationsRemoteMediatorTest {
|
|||
api = mock {
|
||||
onBlocking { notifications(limit = 20, excludes = emptySet()) } doReturn Response.success(
|
||||
listOf(
|
||||
fakeNotification(id = "8"),
|
||||
// testing for https://github.com/tuskyapp/Tusky/issues/4563
|
||||
fakeNotification(
|
||||
id = "8",
|
||||
status = fakeStatus(
|
||||
id = "r1",
|
||||
reblog = fakeStatus(
|
||||
id = "8",
|
||||
authorServerId = "r1"
|
||||
)
|
||||
)
|
||||
),
|
||||
fakeNotification(id = "7"),
|
||||
fakeNotification(id = "5")
|
||||
)
|
||||
|
|
@ -249,7 +260,13 @@ class NotificationsRemoteMediatorTest {
|
|||
|
||||
db.assertNotifications(
|
||||
listOf(
|
||||
fakeNotification(id = "8").toNotificationDataEntity(1),
|
||||
fakeNotification(
|
||||
id = "8",
|
||||
status = fakeStatus(
|
||||
id = "8",
|
||||
authorServerId = "r1"
|
||||
)
|
||||
).toNotificationDataEntity(1),
|
||||
fakeNotification(id = "7").toNotificationDataEntity(1),
|
||||
fakeNotification(id = "5").toNotificationDataEntity(1),
|
||||
fakeNotification(id = "3").toNotificationDataEntity(1),
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ fun fakeStatus(
|
|||
reblogged: Boolean = false,
|
||||
favourited: Boolean = true,
|
||||
bookmarked: Boolean = true,
|
||||
domain: String = "mastodon.example"
|
||||
domain: String = "mastodon.example",
|
||||
reblog: Status? = null
|
||||
) = Status(
|
||||
id = id,
|
||||
url = "https://$domain/@ConnyDuck/$id",
|
||||
|
|
@ -45,7 +46,7 @@ fun fakeStatus(
|
|||
),
|
||||
inReplyToId = inReplyToId,
|
||||
inReplyToAccountId = inReplyToAccountId,
|
||||
reblog = null,
|
||||
reblog = reblog,
|
||||
content = "Test",
|
||||
createdAt = fixedDate,
|
||||
editedAt = null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue