diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 01bc1f38ae..31b108e974 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -34,6 +34,7 @@ import androidx.lifecycle.ProcessLifecycleOwner; import org.conscrypt.Conscrypt; import org.session.libsession.avatars.AvatarHelper; import org.session.libsession.database.MessageDataProvider; +import org.session.libsession.database.StorageProtocol; import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2; @@ -56,7 +57,6 @@ import org.thoughtcrime.securesms.crypto.KeyPairUtilities; import org.thoughtcrime.securesms.database.EmojiSearchDatabase; import org.thoughtcrime.securesms.database.JobDatabase; import org.thoughtcrime.securesms.database.LokiAPIDatabase; -import org.thoughtcrime.securesms.database.Storage; import org.thoughtcrime.securesms.database.model.EmojiSearchData; import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.dependencies.DatabaseModule; @@ -143,7 +143,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO private PersistentLogger persistentLogger; @Inject LokiAPIDatabase lokiAPIDatabase; - @Inject Storage storage; + @Inject StorageProtocol storage; @Inject MessageDataProvider messageDataProvider; @Inject JobDatabase jobDatabase; @Inject TextSecurePreferences textSecurePreferences; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/settings/ConversationSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/settings/ConversationSettingsViewModel.kt index 90f16b67dc..083161c5eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/settings/ConversationSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/settings/ConversationSettingsViewModel.kt @@ -9,7 +9,6 @@ import kotlinx.coroutines.launch import org.session.libsession.database.StorageProtocol import org.session.libsession.utilities.Address import org.session.libsession.utilities.TextSecurePreferences -import org.thoughtcrime.securesms.database.Storage class ConversationSettingsViewModel( val threadId: Long, @@ -46,7 +45,7 @@ class ConversationSettingsViewModel( } class Factory @AssistedInject constructor( @Assisted private val threadId: Long, - private val storage: Storage, + private val storage: StorageProtocol, private val prefs: TextSecurePreferences ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index fb854466d4..620af8c904 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -51,6 +51,7 @@ import network.loki.messenger.R import network.loki.messenger.databinding.ActivityConversationV2Binding import network.loki.messenger.databinding.ViewVisibleMessageBinding import nl.komponents.kovenant.ui.successUi +import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.mentions.Mention @@ -125,7 +126,6 @@ import org.thoughtcrime.securesms.database.ReactionDatabase import org.thoughtcrime.securesms.database.RecipientDatabase import org.thoughtcrime.securesms.database.SessionContactDatabase import org.thoughtcrime.securesms.database.SmsDatabase -import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.MessageRecord @@ -191,7 +191,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe @Inject lateinit var smsDb: SmsDatabase @Inject lateinit var mmsDb: MmsDatabase @Inject lateinit var lokiMessageDb: LokiMessageDatabase - @Inject lateinit var storage: Storage + @Inject lateinit var storage: StorageProtocol @Inject lateinit var reactionDb: ReactionDatabase @Inject lateinit var viewModelFactory: ConversationViewModel.AssistedFactory diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index 8db66e0801..c995965056 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.open_groups.OpenGroupApi import org.session.libsession.messaging.utilities.SessionId @@ -17,7 +18,6 @@ import org.session.libsession.messaging.utilities.SodiumUtilities import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.repository.ConversationRepository import java.util.UUID @@ -26,7 +26,7 @@ class ConversationViewModel( val threadId: Long, val edKeyPair: KeyPair?, private val repository: ConversationRepository, - private val storage: Storage + private val storage: StorageProtocol ) : ViewModel() { private val _uiState = MutableStateFlow(ConversationUiState()) @@ -170,7 +170,7 @@ class ConversationViewModel( @Assisted private val threadId: Long, @Assisted private val edKeyPair: KeyPair?, private val repository: ConversationRepository, - private val storage: Storage + private val storage: StorageProtocol ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt index 27f75701d9..416c21328b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt @@ -5,6 +5,7 @@ import android.view.View import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import network.loki.messenger.databinding.ActivityMessageDetailBinding +import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.open_groups.OpenGroupApi import org.session.libsession.messaging.utilities.SessionId @@ -15,7 +16,6 @@ import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.IdPrefix import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.v2.utilities.ResendMessageUtilities -import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.DateUtils @@ -30,7 +30,7 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() { var messageRecord: MessageRecord? = null @Inject - lateinit var storage: Storage + lateinit var storage: StorageProtocol // region Settings companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt index 2395ad20b3..1799a6e87f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt @@ -9,45 +9,55 @@ import androidx.appcompat.app.AlertDialog import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import network.loki.messenger.databinding.DialogDownloadBinding +import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.contacts.Contact -import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.database.SessionContactDatabase -import org.thoughtcrime.securesms.util.createAndStartAttachmentDownload -import org.thoughtcrime.securesms.util.displaySize import javax.inject.Inject /** Shown when receiving media from a contact for the first time, to confirm that * they are to be trusted and files sent by them are to be downloaded. */ @AndroidEntryPoint -class DownloadDialog(private val recipient: Recipient, +class AutoDownloadDialog(private val threadRecipient: Recipient, private val databaseAttachment: DatabaseAttachment ) : BaseDialog() { + @Inject lateinit var storage: StorageProtocol @Inject lateinit var contactDB: SessionContactDatabase override fun setContentView(builder: AlertDialog.Builder) { val binding = DialogDownloadBinding.inflate(LayoutInflater.from(requireContext())) - val sessionID = recipient.address.toString() - val contact = contactDB.getContactWithSessionID(sessionID) - val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID - val title = resources.getString(R.string.dialog_download_title, name) + val threadId = storage.getThreadId(threadRecipient) ?: run { + dismiss() + return + } + + val displayName = when { + threadRecipient.isOpenGroupRecipient -> storage.getOpenGroup(threadId)?.name ?: "UNKNOWN" + threadRecipient.isClosedGroupRecipient -> storage.getGroup(threadRecipient.address.toGroupString())?.title ?: "UNKNOWN" + else -> storage.getContactWithSessionID(threadRecipient.address.serialize())?.displayName(Contact.ContactContext.REGULAR) ?: "UNKNOWN" + } + val title = resources.getString(R.string.dialog_auto_download_title) binding.downloadTitleTextView.text = title - val displaySize = databaseAttachment.displaySize() - val explanation = resources.getString(R.string.dialog_download_explanation, "$name ($displaySize)") + val explanation = resources.getString(R.string.dialog_auto_download_explanation, displayName) val spannable = SpannableStringBuilder(explanation) - val startIndex = explanation.indexOf(name) - spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + val startIndex = explanation.indexOf(displayName) + spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + displayName.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) binding.downloadExplanationTextView.text = spannable - binding.cancelButton.setOnClickListener { dismiss() } - binding.downloadButton.setOnClickListener { download() } + binding.no.setOnClickListener { + setAutoDownload(false) + dismiss() + } + binding.yes.setOnClickListener { + setAutoDownload(true) + dismiss() + } builder.setView(binding.root) } - private fun download() { - JobQueue.shared.createAndStartAttachmentDownload(databaseAttachment) - dismiss() + private fun setAutoDownload(shouldDownload: Boolean) { + storage.setAutoDownloadAttachments(threadRecipient, shouldDownload) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/PendingAttachmentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/PendingAttachmentView.kt index 0bdd3b6868..1dccfc0ac3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/PendingAttachmentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/PendingAttachmentView.kt @@ -5,14 +5,20 @@ import android.util.AttributeSet import android.widget.LinearLayout import androidx.annotation.ColorInt import androidx.core.content.ContextCompat +import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import network.loki.messenger.databinding.ViewPendingAttachmentBinding +import org.session.libsession.database.StorageProtocol +import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.conversation.v2.dialogs.DownloadDialog +import org.thoughtcrime.securesms.conversation.v2.dialogs.AutoDownloadDialog import org.thoughtcrime.securesms.util.ActivityDispatcher +import org.thoughtcrime.securesms.util.createAndStartAttachmentDownload import java.util.Locale +import javax.inject.Inject +@AndroidEntryPoint class PendingAttachmentView: LinearLayout { private val binding by lazy { ViewPendingAttachmentBinding.bind(this) } enum class AttachmentType { @@ -27,6 +33,7 @@ class PendingAttachmentView: LinearLayout { constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) // endregion + @Inject lateinit var storage: StorageProtocol // region Updating fun bind(attachmentType: AttachmentType, @ColorInt textColor: Int, attachment: DatabaseAttachment) { @@ -46,7 +53,11 @@ class PendingAttachmentView: LinearLayout { // region Interaction fun showDownloadDialog(threadRecipient: Recipient, attachment: DatabaseAttachment) { - ActivityDispatcher.get(context)?.showDialog(DownloadDialog(threadRecipient, attachment)) + JobQueue.shared.createAndStartAttachmentDownload(attachment) + if (!storage.hasAutoDownloadFlagBeenSet(threadRecipient)) { + // just download + ActivityDispatcher.get(context)?.showDialog(AutoDownloadDialog(threadRecipient, attachment)) + } } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index e80a619feb..f2fb35aabc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -644,6 +644,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, return if (recipientSettings.isPresent) { recipientSettings.get() } else null } + override fun hasAutoDownloadFlagBeenSet(recipient: Recipient): Boolean { + return DatabaseComponent.get(context).recipientDatabase().isAutoDownloadFlagSet(recipient) + } + override fun addContacts(contacts: List) { val recipientDatabase = DatabaseComponent.get(context).recipientDatabase() val threadDatabase = DatabaseComponent.get(context).threadDatabase() diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/CallModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/CallModule.kt index da15c2f6b4..8e0c735770 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/CallModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/CallModule.kt @@ -1,16 +1,12 @@ package org.thoughtcrime.securesms.dependencies import android.content.Context -import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn -import dagger.hilt.android.components.ServiceComponent import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.android.scopes.ServiceScoped import dagger.hilt.components.SingletonComponent -import org.session.libsession.database.CallDataProvider -import org.thoughtcrime.securesms.database.Storage +import org.session.libsession.database.StorageProtocol import org.thoughtcrime.securesms.webrtc.CallManager import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCompat import javax.inject.Singleton @@ -25,7 +21,7 @@ object CallModule { @Provides @Singleton - fun provideCallManager(@ApplicationContext context: Context, audioManagerCompat: AudioManagerCompat, storage: Storage) = + fun provideCallManager(@ApplicationContext context: Context, audioManagerCompat: AudioManagerCompat, storage: StorageProtocol) = CallManager(context, audioManagerCompat, storage) } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt index 648b9c43ec..6ea3b0fb9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt @@ -5,6 +5,7 @@ import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import org.session.libsession.database.MessageDataProvider +import org.session.libsession.database.StorageProtocol import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.* import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper @@ -42,7 +43,7 @@ interface DatabaseComponent { fun sessionContactDatabase(): SessionContactDatabase fun reactionDatabase(): ReactionDatabase fun emojiSearchDatabase(): EmojiSearchDatabase - fun storage(): Storage + fun storage(): StorageProtocol fun attachmentProvider(): MessageDataProvider fun blindedIdMappingDatabase(): BlindedIdMappingDatabase fun groupMemberDatabase(): GroupMemberDatabase diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt index 029daefbf1..1b59edeb9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt @@ -8,6 +8,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import net.sqlcipher.database.SQLiteDatabase import org.session.libsession.database.MessageDataProvider +import org.session.libsession.database.StorageProtocol import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider @@ -135,7 +136,7 @@ object DatabaseModule { @Provides @Singleton - fun provideStorage(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = Storage(context,openHelper) + fun provideStorage(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper): StorageProtocol = Storage(context,openHelper) @Provides @Singleton diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt index 9c0a436ebb..88819bcd9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt @@ -17,13 +17,13 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.launch import kotlinx.coroutines.plus import kotlinx.coroutines.withContext +import org.session.libsession.database.StorageProtocol import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.database.DatabaseContentProviders -import org.thoughtcrime.securesms.database.Storage import javax.inject.Inject @HiltViewModel -class BlockedContactsViewModel @Inject constructor(private val storage: Storage): ViewModel() { +class BlockedContactsViewModel @Inject constructor(private val storage: StorageProtocol): ViewModel() { private val executor = viewModelScope + SupervisorJob() diff --git a/app/src/main/res/layout/dialog_download.xml b/app/src/main/res/layout/dialog_download.xml index 78d82db516..53626a3e4d 100644 --- a/app/src/main/res/layout/dialog_download.xml +++ b/app/src/main/res/layout/dialog_download.xml @@ -12,7 +12,7 @@ android:id="@+id/downloadTitleTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/dialog_download_title" + android:text="@string/dialog_auto_download_title" android:textColor="?android:textColorPrimary" android:textStyle="bold" android:textSize="@dimen/large_font_size" /> @@ -22,7 +22,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/large_spacing" - android:text="@string/dialog_download_explanation" + android:text="@string/dialog_auto_download_explanation" android:paddingHorizontal="@dimen/medium_spacing" android:textColor="?android:textColorPrimary" android:textSize="@dimen/small_font_size" @@ -35,21 +35,21 @@ android:orientation="horizontal">