feat: update protos and add a way to do toasts from DI
This commit is contained in:
parent
d9b70d45ec
commit
896907dadb
|
@ -98,6 +98,7 @@ import org.thoughtcrime.securesms.database.model.ReactionRecord
|
||||||
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||||
import org.thoughtcrime.securesms.dependencies.PollerFactory
|
import org.thoughtcrime.securesms.dependencies.PollerFactory
|
||||||
|
import org.thoughtcrime.securesms.dependencies.Toaster
|
||||||
import org.thoughtcrime.securesms.groups.ClosedGroupManager
|
import org.thoughtcrime.securesms.groups.ClosedGroupManager
|
||||||
import org.thoughtcrime.securesms.groups.GroupManager
|
import org.thoughtcrime.securesms.groups.GroupManager
|
||||||
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
||||||
|
@ -112,7 +113,8 @@ open class Storage(
|
||||||
context: Context,
|
context: Context,
|
||||||
helper: SQLCipherOpenHelper,
|
helper: SQLCipherOpenHelper,
|
||||||
private val configFactory: ConfigFactory,
|
private val configFactory: ConfigFactory,
|
||||||
private val pollerFactory: PollerFactory
|
private val pollerFactory: PollerFactory,
|
||||||
|
private val toaster: Toaster,
|
||||||
) : Database(context, helper), StorageProtocol,
|
) : Database(context, helper), StorageProtocol,
|
||||||
ThreadDatabase.ConversationThreadUpdateListener {
|
ThreadDatabase.ConversationThreadUpdateListener {
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
package org.thoughtcrime.securesms.dependencies
|
package org.thoughtcrime.securesms.dependencies
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
import dagger.hilt.EntryPoint
|
import dagger.hilt.EntryPoint
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import org.session.libsession.utilities.AppTextSecurePreferences
|
import org.session.libsession.utilities.AppTextSecurePreferences
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
import org.thoughtcrime.securesms.repository.ConversationRepository
|
import org.thoughtcrime.securesms.repository.ConversationRepository
|
||||||
import org.thoughtcrime.securesms.repository.DefaultConversationRepository
|
import org.thoughtcrime.securesms.repository.DefaultConversationRepository
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@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
|
@EntryPoint
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
interface AppComponent {
|
interface AppComponent {
|
||||||
fun getPrefs(): TextSecurePreferences
|
fun getPrefs(): TextSecurePreferences
|
||||||
|
}
|
||||||
|
|
||||||
|
fun interface Toaster {
|
||||||
|
fun toast(@StringRes stringRes: Int, toastLength: Int, vararg parameters: Any)
|
||||||
}
|
}
|
|
@ -135,8 +135,9 @@ object DatabaseModule {
|
||||||
openHelper: SQLCipherOpenHelper,
|
openHelper: SQLCipherOpenHelper,
|
||||||
configFactory: ConfigFactory,
|
configFactory: ConfigFactory,
|
||||||
threadDatabase: ThreadDatabase,
|
threadDatabase: ThreadDatabase,
|
||||||
pollerFactory: PollerFactory): Storage {
|
pollerFactory: PollerFactory,
|
||||||
val storage = Storage(context, openHelper, configFactory, pollerFactory)
|
toaster: Toaster): Storage {
|
||||||
|
val storage = Storage(context, openHelper, configFactory, pollerFactory, toaster)
|
||||||
threadDatabase.setUpdateListener(storage)
|
threadDatabase.setUpdateListener(storage)
|
||||||
return storage
|
return storage
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ class EditClosedGroupActivity: PassphraseRequiredActionBarActivity() {
|
||||||
navGraph = NavGraphs.editGroup,
|
navGraph = NavGraphs.editGroup,
|
||||||
dependenciesContainerBuilder = {
|
dependenciesContainerBuilder = {
|
||||||
dependency(NavGraphs.editGroup) {
|
dependency(NavGraphs.editGroup) {
|
||||||
editFactory.create(intent.getStringExtra(groupIDKey)!!)
|
editFactory.create(intent.getStringExtra(groupIDKey)!!, contentResolver)
|
||||||
}
|
}
|
||||||
dependency(NavGraphs.editGroup) {
|
dependency(NavGraphs.editGroup) {
|
||||||
inviteFactory.create(intent.getStringExtra(groupIDKey)!!)
|
inviteFactory.create(intent.getStringExtra(groupIDKey)!!)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.groups.compose
|
package org.thoughtcrime.securesms.groups.compose
|
||||||
|
|
||||||
|
import android.content.ContentResolver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
@ -14,6 +15,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.OutlinedButton
|
||||||
import androidx.compose.material.Scaffold
|
import androidx.compose.material.Scaffold
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.rememberScaffoldState
|
import androidx.compose.material.rememberScaffoldState
|
||||||
|
@ -48,6 +50,8 @@ import network.loki.messenger.R
|
||||||
import network.loki.messenger.libsession_util.util.GroupMember
|
import network.loki.messenger.libsession_util.util.GroupMember
|
||||||
import org.session.libsession.database.StorageProtocol
|
import org.session.libsession.database.StorageProtocol
|
||||||
import org.session.libsession.messaging.contacts.Contact
|
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.ContactList
|
||||||
import org.thoughtcrime.securesms.groups.destinations.EditClosedGroupInviteScreenDestination
|
import org.thoughtcrime.securesms.groups.destinations.EditClosedGroupInviteScreenDestination
|
||||||
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
||||||
|
@ -81,6 +85,9 @@ fun EditClosedGroupScreen(
|
||||||
onInvite = {
|
onInvite = {
|
||||||
navigator.navigate(EditClosedGroupInviteScreenDestination)
|
navigator.navigate(EditClosedGroupInviteScreenDestination)
|
||||||
},
|
},
|
||||||
|
onReinvite = { contact ->
|
||||||
|
eventSink(EditGroupEvent.ReInviteContact(contact))
|
||||||
|
},
|
||||||
viewState = viewState
|
viewState = viewState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -111,6 +118,7 @@ fun EditClosedGroupInviteScreen(
|
||||||
|
|
||||||
class EditGroupViewModel @AssistedInject constructor(
|
class EditGroupViewModel @AssistedInject constructor(
|
||||||
@Assisted private val groupSessionId: String,
|
@Assisted private val groupSessionId: String,
|
||||||
|
@Assisted private val contentResolver: ContentResolver,
|
||||||
private val storage: StorageProtocol,
|
private val storage: StorageProtocol,
|
||||||
): ViewModel() {
|
): ViewModel() {
|
||||||
|
|
||||||
|
@ -120,6 +128,10 @@ class EditGroupViewModel @AssistedInject constructor(
|
||||||
storage.getUserPublicKey()!!
|
storage.getUserPublicKey()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// val closedGroupRecipient by contentResolver
|
||||||
|
// .observeQuery(DatabaseContentProviders.ConversationList.CONTENT_URI)
|
||||||
|
// .collectAsState(initial = null)
|
||||||
|
|
||||||
val closedGroupInfo = remember {
|
val closedGroupInfo = remember {
|
||||||
storage.getLibSessionClosedGroup(groupSessionId)!!
|
storage.getLibSessionClosedGroup(groupSessionId)!!
|
||||||
}
|
}
|
||||||
|
@ -163,13 +175,16 @@ class EditGroupViewModel @AssistedInject constructor(
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
|
is EditGroupEvent.ReInviteContact -> {
|
||||||
|
JobQueue.shared.add(InviteContactsJob(groupSessionId, arrayOf(event.contactSessionId)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(groupSessionId: String): EditGroupViewModel
|
fun create(groupSessionId: String, contentResolver: ContentResolver): EditGroupViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -216,6 +231,7 @@ class EditGroupInviteViewModel @AssistedInject constructor(
|
||||||
fun EditGroupView(
|
fun EditGroupView(
|
||||||
onBack: ()->Unit,
|
onBack: ()->Unit,
|
||||||
onInvite: ()->Unit,
|
onInvite: ()->Unit,
|
||||||
|
onReinvite: (String)->Unit,
|
||||||
viewState: EditGroupViewState,
|
viewState: EditGroupViewState,
|
||||||
) {
|
) {
|
||||||
val scaffoldState = rememberScaffoldState()
|
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 {
|
fun memberStateOf(member: GroupMember): MemberState = when {
|
||||||
member.invitePending -> MemberState.InviteSent
|
|
||||||
member.inviteFailed -> MemberState.InviteFailed
|
member.inviteFailed -> MemberState.InviteFailed
|
||||||
member.promotionPending -> MemberState.PromotionSent
|
member.invitePending -> MemberState.InviteSent
|
||||||
member.promotionFailed -> MemberState.PromotionFailed
|
member.promotionFailed -> MemberState.PromotionFailed
|
||||||
|
member.promotionPending -> MemberState.PromotionSent
|
||||||
member.admin -> MemberState.Admin
|
member.admin -> MemberState.Admin
|
||||||
else -> MemberState.Member
|
else -> MemberState.Member
|
||||||
}
|
}
|
||||||
|
@ -350,6 +374,7 @@ data class EditGroupViewState(
|
||||||
sealed class EditGroupEvent {
|
sealed class EditGroupEvent {
|
||||||
data class InviteContacts(val context: Context,
|
data class InviteContacts(val context: Context,
|
||||||
val contacts: ContactList): EditGroupEvent()
|
val contacts: ContactList): EditGroupEvent()
|
||||||
|
data class ReInviteContact(val contactSessionId: String): EditGroupEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class EditGroupInviteViewState(
|
data class EditGroupInviteViewState(
|
||||||
|
@ -367,11 +392,17 @@ fun PreviewList() {
|
||||||
MemberState.InviteSent,
|
MemberState.InviteSent,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
val twoMember = MemberViewModel(
|
||||||
|
"Test User",
|
||||||
|
"05abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1235",
|
||||||
|
MemberState.InviteFailed,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
val viewState = EditGroupViewState(
|
val viewState = EditGroupViewState(
|
||||||
"Preview",
|
"Preview",
|
||||||
"This is a preview description",
|
"This is a preview description",
|
||||||
listOf(oneMember),
|
listOf(oneMember, twoMember),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -379,6 +410,7 @@ fun PreviewList() {
|
||||||
EditGroupView(
|
EditGroupView(
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onInvite = {},
|
onInvite = {},
|
||||||
|
onReinvite = {},
|
||||||
viewState = viewState
|
viewState = viewState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,8 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array<
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
members.set(member.copy(invitePending = true, inviteFailed = false))
|
members.set(member.copy(invitePending = true, inviteFailed = false))
|
||||||
|
configs.saveGroupConfigs(keys, info, members)
|
||||||
|
|
||||||
val subAccount = keys.makeSubAccount(SessionId.from(memberSessionId))
|
val subAccount = keys.makeSubAccount(SessionId.from(memberSessionId))
|
||||||
|
|
||||||
val timestamp = SnodeAPI.nowWithOffset
|
val timestamp = SnodeAPI.nowWithOffset
|
||||||
|
@ -93,6 +95,7 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array<
|
||||||
sentTimestamp = timestamp
|
sentTimestamp = timestamp
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
//throw Exception("Just for testing")
|
||||||
MessageSender.send(update, Destination.Contact(memberSessionId), false)
|
MessageSender.send(update, Destination.Contact(memberSessionId), false)
|
||||||
.get()
|
.get()
|
||||||
InviteResult.success(memberSessionId)
|
InviteResult.success(memberSessionId)
|
||||||
|
@ -119,6 +122,10 @@ class InviteContactsJob(val groupSessionId: String, val memberSessionIds: Array<
|
||||||
members.set(toSet)
|
members.set(toSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
configs.saveGroupConfigs(keys, info, members)
|
||||||
|
keys.free()
|
||||||
|
info.free()
|
||||||
|
members.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,6 @@ class JobQueue : JobDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val shared: JobQueue by lazy { JobQueue() }
|
val shared: JobQueue by lazy { JobQueue() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,18 +140,14 @@ message DataMessage {
|
||||||
required string name = 2;
|
required string name = 2;
|
||||||
// @required
|
// @required
|
||||||
required bytes memberAuthData = 3;
|
required bytes memberAuthData = 3;
|
||||||
optional bytes profileKey = 4;
|
|
||||||
optional LokiProfile profile = 5;
|
|
||||||
// @required
|
// @required
|
||||||
required bytes adminSignature = 6;
|
required bytes adminSignature = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GroupUpdateDeleteMessage {
|
message GroupUpdateDeleteMessage {
|
||||||
|
repeated string memberSessionIds = 1;
|
||||||
// @required
|
// @required
|
||||||
required string groupSessionId = 1; // The `groupIdentityPublicKey` with a `03` prefix
|
// signature of "DELETE" || timestamp || sessionId[0] || ... || sessionId[n]
|
||||||
// @required
|
|
||||||
// signature of "DELETE" || sessionId || timestamp
|
|
||||||
// sessionId is the sessionId of the person being removed
|
|
||||||
required bytes adminSignature = 2;
|
required bytes adminSignature = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +167,9 @@ message DataMessage {
|
||||||
required Type type = 1;
|
required Type type = 1;
|
||||||
optional string updatedName = 2;
|
optional string updatedName = 2;
|
||||||
optional uint32 updatedExpiration = 3;
|
optional uint32 updatedExpiration = 3;
|
||||||
|
// @required
|
||||||
|
// "INFO_CHANGE" || type || timestamp
|
||||||
|
required bytes adminSignature = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GroupUpdateMemberChangeMessage {
|
message GroupUpdateMemberChangeMessage {
|
||||||
|
@ -182,7 +181,10 @@ message DataMessage {
|
||||||
|
|
||||||
// @required
|
// @required
|
||||||
required Type type = 1;
|
required Type type = 1;
|
||||||
repeated bytes memberPublicKeys = 2;
|
repeated string memberSessionIds = 2;
|
||||||
|
// @required
|
||||||
|
// "MEMBER_CHANGE" || type || timestamp
|
||||||
|
required bytes adminSignature = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GroupUpdateMemberLeftMessage {
|
message GroupUpdateMemberLeftMessage {
|
||||||
|
@ -195,9 +197,10 @@ message DataMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GroupUpdateDeleteMemberContentMessage {
|
message GroupUpdateDeleteMemberContentMessage {
|
||||||
repeated bytes memberPublicKeys = 1;
|
repeated string memberSessionIds = 1;
|
||||||
|
repeated string messageHashes = 2;
|
||||||
// @required
|
// @required
|
||||||
required bytes adminSignature = 2;
|
optional bytes adminSignature = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue