feat: update protos and add a way to do toasts from DI

This commit is contained in:
0x330a 2023-11-22 12:16:21 +11:00
parent d9b70d45ec
commit 896907dadb
9 changed files with 1010 additions and 757 deletions

View File

@ -98,6 +98,7 @@ import org.thoughtcrime.securesms.database.model.ReactionRecord
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.dependencies.PollerFactory
import org.thoughtcrime.securesms.dependencies.Toaster
import org.thoughtcrime.securesms.groups.ClosedGroupManager
import org.thoughtcrime.securesms.groups.GroupManager
import org.thoughtcrime.securesms.groups.OpenGroupManager
@ -112,7 +113,8 @@ open class Storage(
context: Context,
helper: SQLCipherOpenHelper,
private val configFactory: ConfigFactory,
private val pollerFactory: PollerFactory
private val pollerFactory: PollerFactory,
private val toaster: Toaster,
) : Database(context, helper), StorageProtocol,
ThreadDatabase.ConversationThreadUpdateListener {

View File

@ -1,14 +1,20 @@
package org.thoughtcrime.securesms.dependencies
import android.content.Context
import android.widget.Toast
import androidx.annotation.StringRes
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import org.session.libsession.utilities.AppTextSecurePreferences
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.repository.ConversationRepository
import org.thoughtcrime.securesms.repository.DefaultConversationRepository
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
@ -22,8 +28,23 @@ abstract class AppModule {
}
@Module
@InstallIn(SingletonComponent::class)
class ToasterModule {
@Provides
@Singleton
fun provideToaster(@ApplicationContext context: Context) = Toaster { stringRes, toastLength, parameters ->
val string = context.getString(stringRes, parameters)
Toast.makeText(context, string, toastLength).show()
}
}
@EntryPoint
@InstallIn(SingletonComponent::class)
interface AppComponent {
fun getPrefs(): TextSecurePreferences
}
fun interface Toaster {
fun toast(@StringRes stringRes: Int, toastLength: Int, vararg parameters: Any)
}

View File

@ -135,8 +135,9 @@ object DatabaseModule {
openHelper: SQLCipherOpenHelper,
configFactory: ConfigFactory,
threadDatabase: ThreadDatabase,
pollerFactory: PollerFactory): Storage {
val storage = Storage(context, openHelper, configFactory, pollerFactory)
pollerFactory: PollerFactory,
toaster: Toaster): Storage {
val storage = Storage(context, openHelper, configFactory, pollerFactory, toaster)
threadDatabase.setUpdateListener(storage)
return storage
}

View File

@ -34,7 +34,7 @@ class EditClosedGroupActivity: PassphraseRequiredActionBarActivity() {
navGraph = NavGraphs.editGroup,
dependenciesContainerBuilder = {
dependency(NavGraphs.editGroup) {
editFactory.create(intent.getStringExtra(groupIDKey)!!)
editFactory.create(intent.getStringExtra(groupIDKey)!!, contentResolver)
}
dependency(NavGraphs.editGroup) {
inviteFactory.create(intent.getStringExtra(groupIDKey)!!)

View File

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.groups.compose
import android.content.ContentResolver
import android.content.Context
import android.widget.Toast
import androidx.compose.foundation.clickable
@ -14,6 +15,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.rememberScaffoldState
@ -48,6 +50,8 @@ import network.loki.messenger.R
import network.loki.messenger.libsession_util.util.GroupMember
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.jobs.InviteContactsJob
import org.session.libsession.messaging.jobs.JobQueue
import org.thoughtcrime.securesms.groups.ContactList
import org.thoughtcrime.securesms.groups.destinations.EditClosedGroupInviteScreenDestination
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
@ -81,6 +85,9 @@ fun EditClosedGroupScreen(
onInvite = {
navigator.navigate(EditClosedGroupInviteScreenDestination)
},
onReinvite = { contact ->
eventSink(EditGroupEvent.ReInviteContact(contact))
},
viewState = viewState
)
}
@ -111,6 +118,7 @@ fun EditClosedGroupInviteScreen(
class EditGroupViewModel @AssistedInject constructor(
@Assisted private val groupSessionId: String,
@Assisted private val contentResolver: ContentResolver,
private val storage: StorageProtocol,
): ViewModel() {
@ -120,6 +128,10 @@ class EditGroupViewModel @AssistedInject constructor(
storage.getUserPublicKey()!!
}
// val closedGroupRecipient by contentResolver
// .observeQuery(DatabaseContentProviders.ConversationList.CONTENT_URI)
// .collectAsState(initial = null)
val closedGroupInfo = remember {
storage.getLibSessionClosedGroup(groupSessionId)!!
}
@ -163,13 +175,16 @@ class EditGroupViewModel @AssistedInject constructor(
Toast.LENGTH_LONG
).show()
}
is EditGroupEvent.ReInviteContact -> {
JobQueue.shared.add(InviteContactsJob(groupSessionId, arrayOf(event.contactSessionId)))
}
}
}
}
@AssistedFactory
interface Factory {
fun create(groupSessionId: String): EditGroupViewModel
fun create(groupSessionId: String, contentResolver: ContentResolver): EditGroupViewModel
}
}
@ -216,6 +231,7 @@ class EditGroupInviteViewModel @AssistedInject constructor(
fun EditGroupView(
onBack: ()->Unit,
onInvite: ()->Unit,
onReinvite: (String)->Unit,
viewState: EditGroupViewState,
) {
val scaffoldState = rememberScaffoldState()
@ -296,6 +312,14 @@ fun EditGroupView(
)
}
}
// Resend button
if (viewState.admin && member.memberState == MemberState.InviteFailed) {
OutlinedButton(onClick = {
onReinvite(member.memberSessionId)
},) {
Text("Re-send")
}
}
}
}
@ -332,10 +356,10 @@ enum class MemberState {
}
fun memberStateOf(member: GroupMember): MemberState = when {
member.invitePending -> MemberState.InviteSent
member.inviteFailed -> MemberState.InviteFailed
member.promotionPending -> MemberState.PromotionSent
member.invitePending -> MemberState.InviteSent
member.promotionFailed -> MemberState.PromotionFailed
member.promotionPending -> MemberState.PromotionSent
member.admin -> MemberState.Admin
else -> MemberState.Member
}
@ -350,6 +374,7 @@ data class EditGroupViewState(
sealed class EditGroupEvent {
data class InviteContacts(val context: Context,
val contacts: ContactList): EditGroupEvent()
data class ReInviteContact(val contactSessionId: String): EditGroupEvent()
}
data class EditGroupInviteViewState(
@ -367,11 +392,17 @@ fun PreviewList() {
MemberState.InviteSent,
false
)
val twoMember = MemberViewModel(
"Test User",
"05abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1235",
MemberState.InviteFailed,
false
)
val viewState = EditGroupViewState(
"Preview",
"This is a preview description",
listOf(oneMember),
listOf(oneMember, twoMember),
true
)
@ -379,6 +410,7 @@ fun PreviewList() {
EditGroupView(
onBack = {},
onInvite = {},
onReinvite = {},
viewState = viewState
)
}

View File

@ -66,6 +66,8 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array<
)
}
members.set(member.copy(invitePending = true, inviteFailed = false))
configs.saveGroupConfigs(keys, info, members)
val subAccount = keys.makeSubAccount(SessionId.from(memberSessionId))
val timestamp = SnodeAPI.nowWithOffset
@ -93,6 +95,7 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array<
sentTimestamp = timestamp
}
try {
//throw Exception("Just for testing")
MessageSender.send(update, Destination.Contact(memberSessionId), false)
.get()
InviteResult.success(memberSessionId)
@ -119,6 +122,10 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array<
members.set(toSet)
}
}
configs.saveGroupConfigs(keys, info, members)
keys.free()
info.free()
members.free()
}
}

View File

@ -170,7 +170,6 @@ class JobQueue : JobDelegate {
}
companion object {
@JvmStatic
val shared: JobQueue by lazy { JobQueue() }
}

View File

@ -140,18 +140,14 @@ message DataMessage {
required string name = 2;
// @required
required bytes memberAuthData = 3;
optional bytes profileKey = 4;
optional LokiProfile profile = 5;
// @required
required bytes adminSignature = 6;
required bytes adminSignature = 4;
}
message GroupUpdateDeleteMessage {
repeated string memberSessionIds = 1;
// @required
required string groupSessionId = 1; // The `groupIdentityPublicKey` with a `03` prefix
// @required
// signature of "DELETE" || sessionId || timestamp
// sessionId is the sessionId of the person being removed
// signature of "DELETE" || timestamp || sessionId[0] || ... || sessionId[n]
required bytes adminSignature = 2;
}
@ -171,6 +167,9 @@ message DataMessage {
required Type type = 1;
optional string updatedName = 2;
optional uint32 updatedExpiration = 3;
// @required
// "INFO_CHANGE" || type || timestamp
required bytes adminSignature = 4;
}
message GroupUpdateMemberChangeMessage {
@ -182,7 +181,10 @@ message DataMessage {
// @required
required Type type = 1;
repeated bytes memberPublicKeys = 2;
repeated string memberSessionIds = 2;
// @required
// "MEMBER_CHANGE" || type || timestamp
required bytes adminSignature = 3;
}
message GroupUpdateMemberLeftMessage {
@ -195,9 +197,10 @@ message DataMessage {
}
message GroupUpdateDeleteMemberContentMessage {
repeated bytes memberPublicKeys = 1;
repeated string memberSessionIds = 1;
repeated string messageHashes = 2;
// @required
required bytes adminSignature = 2;
optional bytes adminSignature = 3;
}