This commit is contained in:
nielsandriesse
2020-05-11 16:19:26 +10:00
parent 410bb9df43
commit ed2ab2d78a
134 changed files with 653 additions and 671 deletions

View File

@@ -6,10 +6,10 @@ import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.redesign.utilities.get
import org.thoughtcrime.securesms.loki.redesign.utilities.getInt
import org.thoughtcrime.securesms.loki.redesign.utilities.getString
import org.thoughtcrime.securesms.loki.redesign.utilities.insertOrUpdate
import org.thoughtcrime.securesms.loki.utilities.get
import org.thoughtcrime.securesms.loki.utilities.getInt
import org.thoughtcrime.securesms.loki.utilities.getString
import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate
import org.whispersystems.signalservice.loki.database.LokiMessageDatabaseProtocol
import org.whispersystems.signalservice.loki.protocol.todo.LokiMessageFriendRequestStatus

View File

@@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.DatabaseContentProviders
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.groups.GroupManager
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPublicChatPoller
import org.thoughtcrime.securesms.loki.api.LokiPublicChatPoller
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.Util
import org.whispersystems.signalservice.loki.api.opengroups.LokiPublicChat

View File

@@ -7,7 +7,7 @@ import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.redesign.utilities.*
import org.thoughtcrime.securesms.loki.utilities.*
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.loki.LokiSessionResetStatus

View File

@@ -58,7 +58,7 @@ class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters)
}
if (openGroups.size > 0) {
messageSender.sendMessage(0, SignalServiceSyncMessage.forOpenGroups(openGroups),
messageSender.sendMessage(SignalServiceSyncMessage.forOpenGroups(openGroups),
UnidentifiedAccessUtil.getAccessForSync(context))
} else {
Log.d("Loki", "No open groups to sync.")

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.os.Bundle
import network.loki.messenger.R

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Intent
import android.graphics.Bitmap

View File

@@ -1,10 +1,10 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.loki.redesign.views.UserView
import org.thoughtcrime.securesms.loki.views.UserView
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.recipients.Recipient

View File

@@ -1,7 +1,7 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Context
import org.thoughtcrime.securesms.loki.redesign.utilities.ContactUtilities
import org.thoughtcrime.securesms.loki.utilities.ContactUtilities
import org.thoughtcrime.securesms.util.AsyncLoader
class CreateClosedGroupLoader(context: Context) : AsyncLoader<List<String>>(context) {

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.ClipData
import android.content.ClipboardManager
@@ -19,8 +19,8 @@ import org.thoughtcrime.securesms.conversation.ConversationActivity
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Intent
import android.os.Bundle
@@ -10,8 +10,8 @@ import android.widget.Toast
import kotlinx.android.synthetic.main.activity_display_name.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.utilities.push
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.crypto.ProfileCipher

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.annotation.SuppressLint
import android.app.AlertDialog
@@ -32,12 +32,12 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.loki.getColorWithID
import org.thoughtcrime.securesms.loki.redesign.dialogs.PNModeBottomSheet
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.redesign.utilities.show
import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
import org.thoughtcrime.securesms.loki.redesign.views.NewConversationButtonSetViewDelegate
import org.thoughtcrime.securesms.loki.redesign.views.SeedReminderViewDelegate
import org.thoughtcrime.securesms.loki.dialogs.PNModeBottomSheet
import org.thoughtcrime.securesms.loki.utilities.push
import org.thoughtcrime.securesms.loki.utilities.show
import org.thoughtcrime.securesms.loki.views.ConversationView
import org.thoughtcrime.securesms.loki.views.NewConversationButtonSetViewDelegate
import org.thoughtcrime.securesms.loki.views.SeedReminderViewDelegate
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.notifications.MessageNotifier
@@ -269,7 +269,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
val dialog = AlertDialog.Builder(activity)
dialog.setMessage(dialogMessage)
dialog.setPositiveButton(R.string.yes) { _, _ ->
val isClosedGroup = recipient.address.isSignalGroup
val isClosedGroup = recipient.address.isClosedGroup
// Send a leave group message if this is an active closed group
if (isClosedGroup && DatabaseFactory.getGroupDatabase(activity).isActive(recipient.address.toGroupString())) {
if (!GroupUtil.leaveGroup(activity, recipient)) {

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Context
import android.database.Cursor
@@ -7,7 +7,7 @@ import android.view.ViewGroup
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
import org.thoughtcrime.securesms.loki.views.ConversationView
import org.thoughtcrime.securesms.mms.GlideRequests
class HomeAdapter(context: Context, cursor: Cursor) : CursorRecyclerViewAdapter<HomeAdapter.ViewHolder>(context, cursor) {

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Context
import android.database.Cursor

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
@@ -18,9 +18,9 @@ import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.successUi
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.redesign.utilities.OpenGroupUtilities
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities
import org.thoughtcrime.securesms.sms.MessageSender
class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Intent
import android.os.AsyncTask
@@ -13,12 +13,12 @@ import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.IdentityDatabase
import org.thoughtcrime.securesms.logging.Log
import org.thoughtcrime.securesms.loki.redesign.dialogs.LinkDeviceSlaveModeDialog
import org.thoughtcrime.securesms.loki.redesign.dialogs.LinkDeviceSlaveModeDialogDelegate
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.redesign.utilities.show
import org.thoughtcrime.securesms.loki.dialogs.LinkDeviceSlaveModeDialog
import org.thoughtcrime.securesms.loki.dialogs.LinkDeviceSlaveModeDialogDelegate
import org.thoughtcrime.securesms.loki.sendDeviceLinkMessage
import org.thoughtcrime.securesms.loki.utilities.push
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.utilities.show
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.Hex
import org.thoughtcrime.securesms.util.TextSecurePreferences
@@ -40,7 +40,7 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega
registerButton.setOnClickListener { register() }
restoreButton.setOnClickListener { restore() }
linkButton.setOnClickListener { linkDevice() }
if (TextSecurePreferences.databaseResetFromUnpair(this)) {
if (TextSecurePreferences.setNeedsDatabaseResetFromUnlink(this)) {
Toast.makeText(this, "Your device was unlinked successfully", Toast.LENGTH_LONG).show()
}
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Intent
import android.os.Bundle
@@ -13,8 +13,8 @@ import kotlinx.android.synthetic.main.activity_link_device.*
import kotlinx.android.synthetic.main.fragment_enter_session_id.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
class LinkDeviceActivity : BaseActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.os.AsyncTask
import android.os.Bundle
@@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.redesign.dialogs.*
import org.thoughtcrime.securesms.loki.dialogs.*
import org.thoughtcrime.securesms.loki.signAndSendDeviceLinkMessage
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.util.TextSecurePreferences

View File

@@ -1,10 +1,10 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.redesign.views.DeviceView
import org.thoughtcrime.securesms.loki.views.DeviceView
class LinkedDevicesAdapter(private val context: Context) : RecyclerView.Adapter<LinkedDevicesAdapter.ViewHolder>() {
var devices = listOf<Device>()

View File

@@ -1,9 +1,9 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Context
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
import org.thoughtcrime.securesms.util.AsyncLoader
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.protocol.multidevice.LokiDeviceLinkUtilities

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.os.Bundle
import network.loki.messenger.R

View File

@@ -1,24 +1,20 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.app.AlertDialog
import android.content.Intent
import android.graphics.drawable.TransitionDrawable
import android.os.Bundle
import android.os.Handler
import android.support.annotation.DrawableRes
import android.view.View
import android.widget.LinearLayout
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_display_name.registerButton
import kotlinx.android.synthetic.main.activity_home.*
import kotlinx.android.synthetic.main.activity_pn_mode.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.redesign.utilities.show
import org.thoughtcrime.securesms.util.GroupUtil
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.utilities.show
import org.thoughtcrime.securesms.util.TextSecurePreferences
class PNModeActivity : BaseActionBarActivity() {

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.os.Bundle
import network.loki.messenger.R

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.Manifest
import android.content.Intent
@@ -20,9 +20,9 @@ import org.thoughtcrime.securesms.conversation.ConversationActivity
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.redesign.utilities.QRCodeUtilities
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.utilities.QRCodeUtilities
import org.thoughtcrime.securesms.loki.toPx
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.FileProviderUtil

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.ClipData
import android.content.ClipboardManager
@@ -22,8 +22,8 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.IdentityDatabase
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.utilities.push
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.Hex
import org.thoughtcrime.securesms.util.TextSecurePreferences

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.Intent
import android.graphics.Typeface
@@ -18,8 +18,8 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.IdentityDatabase
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.loki.utilities.push
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.Hex
import org.thoughtcrime.securesms.util.TextSecurePreferences

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.content.ClipData
import android.content.ClipboardManager

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.activities
package org.thoughtcrime.securesms.loki.activities
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
@@ -29,9 +29,9 @@ import org.thoughtcrime.securesms.avatar.AvatarSelection
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.redesign.dialogs.ClearAllDataDialog
import org.thoughtcrime.securesms.loki.redesign.dialogs.SeedDialog
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.dialogs.ClearAllDataDialog
import org.thoughtcrime.securesms.loki.dialogs.SeedDialog
import org.thoughtcrime.securesms.loki.utilities.push
import org.thoughtcrime.securesms.loki.toPx
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
@@ -169,7 +169,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
val (_, url) = storageAPI.uploadProfilePicture(storageAPI.server, profileKey, stream) {
TextSecurePreferences.setLastProfilePictureUpload(this@SettingsActivity, Date().time)
}
TextSecurePreferences.setProfileAvatarUrl(this, url)
TextSecurePreferences.setProfilePictureURL(this, url)
deferred.resolve(Unit)
}
promises.add(deferred.promise)

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.api
import android.content.Context
import android.content.Intent

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.api
import android.content.Context
import android.content.Intent

View File

@@ -1,10 +1,9 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.api
import android.content.Context
import android.os.Handler
import android.util.Log
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.functional.bind
import nl.komponents.kovenant.then
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.api
import android.content.Context
import org.thoughtcrime.securesms.database.DatabaseFactory
@@ -6,10 +6,10 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager
object LokiAPIUtilities {
object MentionManagerUtilities {
fun populateUserHexEncodedPublicKeyCacheIfNeeded(threadID: Long, context: Context) {
if (MentionsManager.userHexEncodedPublicKeyCache[threadID] != null) { return }
if (MentionsManager.shared.userHexEncodedPublicKeyCache[threadID] != null) { return }
val result = mutableSetOf<String>()
val messageDatabase = DatabaseFactory.getMmsSmsDatabase(context)
val reader = messageDatabase.readerFor(messageDatabase.getConversation(threadID))
@@ -24,6 +24,6 @@ object LokiAPIUtilities {
}
reader.close()
result.add(TextSecurePreferences.getLocalNumber(context))
MentionsManager.userHexEncodedPublicKeyCache[threadID] = result
MentionsManager.shared.userHexEncodedPublicKeyCache[threadID] = result
}
}

View File

@@ -1,18 +1,16 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.database
import android.content.ContentValues
import android.content.Context
import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.redesign.utilities.*
import org.thoughtcrime.securesms.loki.utilities.*
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.database.LokiAPIDatabaseProtocol
import org.whispersystems.signalservice.loki.api.LokiAPITarget
import org.whispersystems.signalservice.loki.database.LokiAPIDatabaseProtocol
import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLink
// TODO: Clean this up a bit
class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiAPIDatabaseProtocol {
private val userPublicKey get() = TextSecurePreferences.getLocalNumber(context)
@@ -71,9 +69,9 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
val components = targetAsString.split("-")
val address = components[0]
val port = components.getOrNull(1)?.toIntOrNull() ?: return@mapNotNull null
val idKey = components.getOrNull(2) ?: return@mapNotNull null
val encryptionKey = components.getOrNull(3)?: return@mapNotNull null
LokiAPITarget(address, port, LokiAPITarget.KeySet(idKey, encryptionKey))
val ed25519Key = components.getOrNull(2) ?: return@mapNotNull null
val x25519Key = components.getOrNull(3)?: return@mapNotNull null
LokiAPITarget(address, port, LokiAPITarget.KeySet(ed25519Key, x25519Key))
}
}?.toSet()
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.database
import android.content.ContentValues
import android.content.Context
@@ -9,10 +9,10 @@ import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.logging.Log
import org.thoughtcrime.securesms.loki.redesign.utilities.get
import org.thoughtcrime.securesms.loki.redesign.utilities.getBase64EncodedData
import org.thoughtcrime.securesms.loki.redesign.utilities.getInt
import org.thoughtcrime.securesms.loki.redesign.utilities.insertOrUpdate
import org.thoughtcrime.securesms.loki.utilities.get
import org.thoughtcrime.securesms.loki.utilities.getBase64EncodedData
import org.thoughtcrime.securesms.loki.utilities.getInt
import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate
import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.IdentityKey

View File

@@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.database
import android.content.ContentValues
import android.content.Context
import org.thoughtcrime.securesms.crypto.PreKeyUtil
import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.redesign.utilities.get
import org.thoughtcrime.securesms.loki.redesign.utilities.getInt
import org.thoughtcrime.securesms.loki.redesign.utilities.insertOrUpdate
import org.thoughtcrime.securesms.loki.utilities.get
import org.thoughtcrime.securesms.loki.utilities.getInt
import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate
import org.whispersystems.libsignal.state.PreKeyRecord
import org.whispersystems.signalservice.loki.database.LokiPreKeyRecordDatabaseProtocol

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.messaging
package org.thoughtcrime.securesms.loki.database
import android.content.ContentValues
import android.content.Context
@@ -7,8 +7,8 @@ import android.util.Log
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.redesign.utilities.get
import org.thoughtcrime.securesms.loki.redesign.utilities.insertOrUpdate
import org.thoughtcrime.securesms.loki.utilities.get
import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.database.LokiUserDatabaseProtocol
@@ -71,7 +71,7 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
override fun getProfilePictureURL(hexEncodedPublicKey: String): String? {
return if (hexEncodedPublicKey == TextSecurePreferences.getLocalNumber(context)) {
TextSecurePreferences.getProfileAvatarUrl(context)
TextSecurePreferences.getProfilePictureURL(context)
} else {
Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).resolve().profileAvatar
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.app.Dialog
import android.graphics.Color

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.os.Bundle
import android.support.design.widget.BottomSheetDialogFragment

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.app.Dialog
import android.graphics.Color

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.app.Dialog
import android.graphics.Color
@@ -12,15 +12,15 @@ import android.widget.LinearLayout
import kotlinx.android.synthetic.main.dialog_link_device_master_mode.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities
import org.thoughtcrime.securesms.loki.redesign.utilities.QRCodeUtilities
import org.thoughtcrime.securesms.loki.toPx
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
import org.thoughtcrime.securesms.loki.utilities.QRCodeUtilities
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.Util
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLink
import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLinkingSession
import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLinkingSessionListener
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListener {
private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) }

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.app.Dialog
import android.graphics.Color
@@ -12,7 +12,7 @@ import android.view.View
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.dialog_link_device_slave_mode.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.Util
import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLink

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.os.Bundle
import android.support.design.widget.BottomSheetDialogFragment

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.app.AlertDialog
import android.content.DialogInterface

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.dialogs
package org.thoughtcrime.securesms.loki.dialogs
import android.app.Dialog
import android.content.ClipData

View File

@@ -0,0 +1,85 @@
package org.thoughtcrime.securesms.loki.fragments
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.contact_selection_list_divider.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.views.UserView
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.recipients.Recipient
class ContactSelectionListAdapter(private val context: Context, private val multiSelect: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
lateinit var glide: GlideRequests
val selectedContacts = mutableSetOf<Recipient>()
var items = listOf<ContactSelectionListItem>()
set(value) { field = value; notifyDataSetChanged() }
var contactClickListener: ContactClickListener? = null
private object ViewType {
const val Contact = 0
const val Divider = 1
}
class UserViewHolder(val view: UserView) : RecyclerView.ViewHolder(view)
class DividerViewHolder(val view: View) : RecyclerView.ViewHolder(view)
override fun getItemCount(): Int {
return items.size
}
override fun getItemViewType(position: Int): Int {
return when (items[position]) {
is ContactSelectionListItem.Header -> ViewType.Divider
else -> ViewType.Contact
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == ViewType.Contact) {
UserViewHolder(UserView(context))
} else {
val view = LayoutInflater.from(context).inflate(R.layout.contact_selection_list_divider, parent, false)
DividerViewHolder(view)
}
}
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
val item = items[position]
if (viewHolder is UserViewHolder) {
item as ContactSelectionListItem.Contact
viewHolder.view.setOnClickListener { contactClickListener?.onContactClick(item.recipient) }
val isSelected = selectedContacts.contains(item.recipient)
viewHolder.view.bind(item.recipient, isSelected, glide)
viewHolder.view.setCheckBoxVisible(multiSelect)
} else if (viewHolder is DividerViewHolder) {
item as ContactSelectionListItem.Header
viewHolder.view.label.text = item.name
}
}
fun onContactClick(recipient: Recipient) {
if (selectedContacts.contains(recipient)) {
selectedContacts.remove(recipient)
contactClickListener?.onContactDeselected(recipient)
} else if (multiSelect || selectedContacts.isEmpty()) {
selectedContacts.add(recipient)
contactClickListener?.onContactSelected(recipient)
}
val index = items.indexOfFirst {
when (it) {
is ContactSelectionListItem.Header -> false
is ContactSelectionListItem.Contact -> it.recipient == recipient
}
}
notifyItemChanged(index)
}
}
interface ContactClickListener {
fun onContactClick(contact: Recipient)
fun onContactSelected(contact: Recipient)
fun onContactDeselected(contact: Recipient)
}

View File

@@ -0,0 +1,112 @@
package org.thoughtcrime.securesms.loki.fragments
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.contact_selection_list_fragment.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.recipients.Recipient
class ContactSelectionListFragment : Fragment(), LoaderManager.LoaderCallbacks<List<ContactSelectionListItem>>, ContactClickListener {
private var cursorFilter: String? = null
var onContactSelectedListener: OnContactSelectedListener? = null
val selectedContacts: List<String>
get() = listAdapter.selectedContacts.map { it.address.serialize() }
private val multiSelect: Boolean by lazy {
activity!!.intent.getBooleanExtra(MULTI_SELECT, false)
}
private val listAdapter by lazy {
val result = ContactSelectionListAdapter(activity!!, multiSelect)
result.glide = GlideApp.with(this)
result.contactClickListener = this
result
}
companion object {
@JvmField val DISPLAY_MODE = "display_mode"
@JvmField val MULTI_SELECT = "multi_select"
@JvmField val REFRESHABLE = "refreshable"
}
interface OnContactSelectedListener {
fun onContactSelected(number: String?)
fun onContactDeselected(number: String?)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
recyclerView.layoutManager = LinearLayoutManager(activity)
recyclerView.adapter = listAdapter
swipeRefreshLayout.isEnabled = activity!!.intent.getBooleanExtra(REFRESHABLE, true)
}
override fun onStart() {
super.onStart()
LoaderManager.getInstance(this).initLoader(0, null, this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.contact_selection_list_fragment, container, false)
}
fun setQueryFilter(filter: String?) {
cursorFilter = filter
LoaderManager.getInstance(this).restartLoader(0, null, this)
}
fun resetQueryFilter() {
setQueryFilter(null)
swipeRefreshLayout.isRefreshing = false
}
fun setRefreshing(refreshing: Boolean) {
swipeRefreshLayout.isRefreshing = refreshing
}
fun setOnRefreshListener(onRefreshListener: OnRefreshListener?) {
swipeRefreshLayout.setOnRefreshListener(onRefreshListener)
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ContactSelectionListItem>> {
return ContactSelectionListLoader(activity!!,
activity!!.intent.getIntExtra(DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_ALL),
cursorFilter)
}
override fun onLoadFinished(loader: Loader<List<ContactSelectionListItem>>, items: List<ContactSelectionListItem>) {
update(items)
}
override fun onLoaderReset(loader: Loader<List<ContactSelectionListItem>>) {
update(listOf())
}
private fun update(items: List<ContactSelectionListItem>) {
listAdapter.items = items
mainContentContainer.visibility = if (items.isEmpty()) View.GONE else View.VISIBLE
emptyStateContainer.visibility = if (items.isEmpty()) View.VISIBLE else View.GONE
}
override fun onContactClick(contact: Recipient) {
listAdapter.onContactClick(contact)
}
override fun onContactSelected(contact: Recipient) {
onContactSelectedListener?.onContactSelected(contact.address.serialize())
}
override fun onContactDeselected(contact: Recipient) {
onContactSelectedListener?.onContactDeselected(contact.address.serialize())
}
}

View File

@@ -0,0 +1,74 @@
package org.thoughtcrime.securesms.loki.fragments
import android.content.Context
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.utilities.Contact
import org.thoughtcrime.securesms.loki.utilities.ContactUtilities
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.AsyncLoader
sealed class ContactSelectionListItem {
class Header(val name: String) : ContactSelectionListItem()
class Contact(val recipient: Recipient) : ContactSelectionListItem()
}
class ContactSelectionListLoader(context: Context, val mode: Int, val filter: String?) : AsyncLoader<List<ContactSelectionListItem>>(context) {
object DisplayMode {
const val FLAG_FRIENDS = 1
const val FLAG_CLOSED_GROUPS = 1 shl 1
const val FLAG_OPEN_GROUPS = 1 shl 2
const val FLAG_ALL = FLAG_FRIENDS or FLAG_CLOSED_GROUPS or FLAG_OPEN_GROUPS
}
private fun isFlagSet(flag: Int): Boolean {
return mode and flag > 0
}
override fun loadInBackground(): List<ContactSelectionListItem> {
val contacts = ContactUtilities.getAllContacts(context).filter {
if (filter.isNullOrEmpty()) return@filter true
it.recipient.toShortString().contains(filter.trim(), true) || it.recipient.address.serialize().contains(filter.trim(), true)
}.sortedBy {
it.recipient.toShortString()
}
val list = mutableListOf<ContactSelectionListItem>()
if (isFlagSet(DisplayMode.FLAG_CLOSED_GROUPS)) {
list.addAll(getClosedGroups(contacts))
}
if (isFlagSet(DisplayMode.FLAG_OPEN_GROUPS)) {
list.addAll(getOpenGroups(contacts))
}
if (isFlagSet(DisplayMode.FLAG_FRIENDS)) {
list.addAll(getFriends(contacts))
}
return list
}
private fun getFriends(contacts: List<Contact>): List<ContactSelectionListItem> {
return getItems(contacts, context.getString(R.string.fragment_contact_selection_contacts_title)) {
!it.recipient.isGroupRecipient && it.isFriend && !it.isOurDevice && !it.isSlave
}
}
private fun getClosedGroups(contacts: List<Contact>): List<ContactSelectionListItem> {
return getItems(contacts, context.getString(R.string.fragment_contact_selection_closed_groups_title)) {
it.recipient.address.isClosedGroup
}
}
private fun getOpenGroups(contacts: List<Contact>): List<ContactSelectionListItem> {
return getItems(contacts, context.getString(R.string.fragment_contact_selection_open_groups_title)) {
it.recipient.address.isOpenGroup
}
}
private fun getItems(contacts: List<Contact>, title: String, contactFilter: (Contact) -> Boolean): List<ContactSelectionListItem> {
val items = contacts.filter(contactFilter).map {
ContactSelectionListItem.Contact(it.recipient)
}
if (items.isEmpty()) return listOf()
val header = ContactSelectionListItem.Header(title)
return listOf(header) + items
}
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.fragments
package org.thoughtcrime.securesms.loki.fragments
import android.content.res.Configuration
import android.os.Bundle

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.fragments
package org.thoughtcrime.securesms.loki.fragments
import android.os.Bundle
import android.support.v4.app.Fragment

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.fragments
package org.thoughtcrime.securesms.loki.fragments
import android.Manifest
import android.content.pm.PackageManager

View File

@@ -0,0 +1,28 @@
package org.thoughtcrime.securesms.loki.protocol
import android.content.Context
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.util.GroupUtil
import org.thoughtcrime.securesms.util.TextSecurePreferences
object ClosedGroupsProtocol {
fun leaveGroup(context: Context, recipient: Recipient): Boolean {
if (!recipient.address.isClosedGroup) { return true }
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
val message = GroupUtil.createGroupLeaveMessage(context, recipient)
if (threadID < 0 || !message.isPresent) { return false }
MessageSender.send(context, message.get(), threadID, false, null)
// Remove the *master* device from the group
val masterHexPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
val userPublicKey = masterHexPublicKey ?: TextSecurePreferences.getLocalNumber(context)
val groupDatabase = DatabaseFactory.getGroupDatabase(context)
val groupID = recipient.address.toGroupString()
groupDatabase.setActive(groupID, false)
groupDatabase.remove(groupID, Address.fromSerialized(userPublicKey))
return true
}
}

View File

@@ -1,85 +0,0 @@
package org.thoughtcrime.securesms.loki.redesign.fragments.contactselection
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.contact_selection_list_divider.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.redesign.views.UserView
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.recipients.Recipient
class ContactSelectionListAdapter(private val context: Context, private val multiSelect: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
lateinit var glide: GlideRequests
val selectedContacts = mutableSetOf<Recipient>()
var items = listOf<ContactSelectionListItem>()
set(value) { field = value; notifyDataSetChanged() }
var contactClickListener: ContactClickListener? = null
private object ViewType {
const val Contact = 0
const val Divider = 1
}
class UserViewHolder(val view: UserView) : RecyclerView.ViewHolder(view)
class DividerViewHolder(val view: View) : RecyclerView.ViewHolder(view)
override fun getItemCount(): Int {
return items.size
}
override fun getItemViewType(position: Int): Int {
return when (items[position]) {
is ContactSelectionListItem.Header -> ViewType.Divider
else -> ViewType.Contact
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == ViewType.Contact) {
UserViewHolder(UserView(context))
} else {
val view = LayoutInflater.from(context).inflate(R.layout.contact_selection_list_divider, parent, false)
DividerViewHolder(view)
}
}
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
val item = items[position]
if (viewHolder is UserViewHolder) {
item as ContactSelectionListItem.Contact
viewHolder.view.setOnClickListener { contactClickListener?.onContactClick(item.recipient) }
val isSelected = selectedContacts.contains(item.recipient)
viewHolder.view.bind(item.recipient, isSelected, glide)
viewHolder.view.setCheckBoxVisible(multiSelect)
} else if (viewHolder is DividerViewHolder) {
item as ContactSelectionListItem.Header
viewHolder.view.label.text = item.name
}
}
fun onContactClick(recipient: Recipient) {
if (selectedContacts.contains(recipient)) {
selectedContacts.remove(recipient)
contactClickListener?.onContactDeselected(recipient)
} else if (multiSelect || selectedContacts.isEmpty()) {
selectedContacts.add(recipient)
contactClickListener?.onContactSelected(recipient)
}
val index = items.indexOfFirst {
when (it) {
is ContactSelectionListItem.Header -> false
is ContactSelectionListItem.Contact -> it.recipient == recipient
}
}
notifyItemChanged(index)
}
}
interface ContactClickListener {
fun onContactClick(contact: Recipient)
fun onContactSelected(contact: Recipient)
fun onContactDeselected(contact: Recipient)
}

View File

@@ -1,112 +0,0 @@
package org.thoughtcrime.securesms.loki.redesign.fragments.contactselection
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.contact_selection_list_fragment.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.recipients.Recipient
class ContactSelectionListFragment : Fragment(), LoaderManager.LoaderCallbacks<List<ContactSelectionListItem>>, ContactClickListener {
private var cursorFilter: String? = null
var onContactSelectedListener: OnContactSelectedListener? = null
val selectedContacts: List<String>
get() = listAdapter.selectedContacts.map { it.address.serialize() }
private val multiSelect: Boolean by lazy {
activity!!.intent.getBooleanExtra(MULTI_SELECT, false)
}
private val listAdapter by lazy {
val result = ContactSelectionListAdapter(activity!!, multiSelect)
result.glide = GlideApp.with(this)
result.contactClickListener = this
result
}
companion object {
@JvmField val DISPLAY_MODE = "display_mode"
@JvmField val MULTI_SELECT = "multi_select"
@JvmField val REFRESHABLE = "refreshable"
}
interface OnContactSelectedListener {
fun onContactSelected(number: String?)
fun onContactDeselected(number: String?)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
recyclerView.layoutManager = LinearLayoutManager(activity)
recyclerView.adapter = listAdapter
swipeRefreshLayout.isEnabled = activity!!.intent.getBooleanExtra(REFRESHABLE, true)
}
override fun onStart() {
super.onStart()
LoaderManager.getInstance(this).initLoader(0, null, this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.contact_selection_list_fragment, container, false)
}
fun setQueryFilter(filter: String?) {
cursorFilter = filter
LoaderManager.getInstance(this).restartLoader(0, null, this)
}
fun resetQueryFilter() {
setQueryFilter(null)
swipeRefreshLayout.isRefreshing = false
}
fun setRefreshing(refreshing: Boolean) {
swipeRefreshLayout.isRefreshing = refreshing
}
fun setOnRefreshListener(onRefreshListener: OnRefreshListener?) {
swipeRefreshLayout.setOnRefreshListener(onRefreshListener)
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ContactSelectionListItem>> {
return ContactSelectionListLoader(activity!!,
activity!!.intent.getIntExtra(DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_ALL),
cursorFilter)
}
override fun onLoadFinished(loader: Loader<List<ContactSelectionListItem>>, items: List<ContactSelectionListItem>) {
update(items)
}
override fun onLoaderReset(loader: Loader<List<ContactSelectionListItem>>) {
update(listOf())
}
private fun update(items: List<ContactSelectionListItem>) {
listAdapter.items = items
mainContentContainer.visibility = if (items.isEmpty()) View.GONE else View.VISIBLE
emptyStateContainer.visibility = if (items.isEmpty()) View.VISIBLE else View.GONE
}
override fun onContactClick(contact: Recipient) {
listAdapter.onContactClick(contact)
}
override fun onContactSelected(contact: Recipient) {
onContactSelectedListener?.onContactSelected(contact.address.serialize())
}
override fun onContactDeselected(contact: Recipient) {
onContactSelectedListener?.onContactDeselected(contact.address.serialize())
}
}

View File

@@ -1,83 +0,0 @@
package org.thoughtcrime.securesms.loki.redesign.fragments.contactselection
import android.content.Context
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.redesign.utilities.Contact
import org.thoughtcrime.securesms.loki.redesign.utilities.ContactUtilities
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.AsyncLoader
sealed class ContactSelectionListItem {
class Header(val name: String) : ContactSelectionListItem()
class Contact(val recipient: Recipient) : ContactSelectionListItem()
}
class ContactSelectionListLoader(context: Context, val mode: Int, val filter: String?) : AsyncLoader<List<ContactSelectionListItem>>(context) {
object DisplayMode {
const val FLAG_FRIENDS = 1
const val FLAG_CLOSED_GROUPS = 1 shl 1
const val FLAG_OPEN_GROUPS = 1 shl 2
const val FLAG_ALL = FLAG_FRIENDS or FLAG_CLOSED_GROUPS or FLAG_OPEN_GROUPS
}
private fun isFlagSet(flag: Int): Boolean {
return mode and flag > 0
}
override fun loadInBackground(): List<ContactSelectionListItem> {
val contacts = ContactUtilities.getAllContacts(context).filter {
if (filter.isNullOrEmpty()) return@filter true
it.recipient.toShortString().contains(filter.trim(), true) || it.recipient.address.serialize().contains(filter.trim(), true)
}.sortedBy {
it.recipient.toShortString()
}
val list = mutableListOf<ContactSelectionListItem>()
if (isFlagSet(DisplayMode.FLAG_CLOSED_GROUPS)) {
list.addAll(getClosedGroups(contacts))
}
if (isFlagSet(DisplayMode.FLAG_OPEN_GROUPS)) {
list.addAll(getOpenGroups(contacts))
}
if (isFlagSet(DisplayMode.FLAG_FRIENDS)) {
list.addAll(getFriends(contacts))
}
return list
}
private fun getFriends(contacts: List<Contact>): List<ContactSelectionListItem> {
return getItems(contacts, context.getString(R.string.fragment_contact_selection_contacts_title)) {
!it.recipient.isGroupRecipient && it.isFriend && !it.isOurDevice && !it.isSlave
}
}
private fun getClosedGroups(contacts: List<Contact>): List<ContactSelectionListItem> {
return getItems(contacts, context.getString(R.string.fragment_contact_selection_closed_groups_title)) {
it.recipient.address.isSignalGroup
}
}
private fun getOpenGroups(contacts: List<Contact>): List<ContactSelectionListItem> {
return getItems(contacts, context.getString(R.string.fragment_contact_selection_open_groups_title)) {
it.recipient.address.isPublicChat
}
}
private fun getItems(contacts: List<Contact>, title: String, contactFilter: (Contact) -> Boolean): List<ContactSelectionListItem> {
val items = contacts.filter(contactFilter).map {
ContactSelectionListItem.Contact(it.recipient)
}
if (items.isEmpty()) return listOf()
val header = ContactSelectionListItem.Header(title)
return listOf(header) + items
}
}

View File

@@ -1,60 +0,0 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
import android.content.Context
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.protocol.todo.LokiThreadFriendRequestStatus
data class Contact(
val recipient: Recipient,
val isFriend: Boolean,
val isSlave: Boolean,
val isOurDevice: Boolean
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Contact
return recipient == other.recipient
}
override fun hashCode(): Int {
return recipient.hashCode()
}
}
object ContactUtilities {
@JvmStatic
fun getAllContacts(context: Context): Set<Contact> {
val threadDatabase = DatabaseFactory.getThreadDatabase(context)
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context)
val ourDeviceLinks = lokiAPIDatabase.getDeviceLinks(userHexEncodedPublicKey)
val ourDevices = ourDeviceLinks.flatMap {
listOf( it.masterHexEncodedPublicKey.toLowerCase(), it.slaveHexEncodedPublicKey.toLowerCase() )
}.toMutableSet()
ourDevices.add(userHexEncodedPublicKey.toLowerCase())
val cursor = threadDatabase.conversationList
val result = mutableSetOf<Contact>()
threadDatabase.readerFor(cursor).use { reader ->
while (reader.next != null) {
val thread = reader.current
val recipient = thread.recipient
val address = recipient.address.serialize()
val isOurDevice = ourDevices.contains(address)
val isFriend = lokiThreadDatabase.getFriendRequestStatus(thread.threadId) == LokiThreadFriendRequestStatus.FRIENDS
var isSlave = false
if (!recipient.isGroupRecipient) {
val deviceLinks = lokiAPIDatabase.getDeviceLinks(address)
isSlave = deviceLinks.find { it.slaveHexEncodedPublicKey == address } != null
}
result.add(Contact(recipient, isFriend, isSlave, isOurDevice))
}
}
return result
}
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.shelved
package org.thoughtcrime.securesms.loki.shelved
import android.content.Context
import android.os.Handler

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.content.Intent
import android.support.v7.app.ActionBar

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.content.Context
import android.content.Intent

View File

@@ -0,0 +1,57 @@
package org.thoughtcrime.securesms.loki.utilities
import android.content.Context
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol
import org.whispersystems.signalservice.loki.protocol.todo.LokiThreadFriendRequestStatus
data class Contact(
val recipient: Recipient,
val isFriend: Boolean,
val isSlave: Boolean,
val isOurDevice: Boolean
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Contact
return recipient == other.recipient
}
override fun hashCode(): Int {
return recipient.hashCode()
}
}
object ContactUtilities {
@JvmStatic
fun getAllContacts(context: Context): Set<Contact> {
val threadDatabase = DatabaseFactory.getThreadDatabase(context)
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context)
val userDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userHexEncodedPublicKey)
val cursor = threadDatabase.conversationList
val result = mutableSetOf<Contact>()
threadDatabase.readerFor(cursor).use { reader ->
while (reader.next != null) {
val thread = reader.current
val recipient = thread.recipient
val publicKey = recipient.address.serialize()
val isUserDevice = userDevices.contains(publicKey)
val isFriend = lokiThreadDatabase.getFriendRequestStatus(thread.threadId) == LokiThreadFriendRequestStatus.FRIENDS
var isSlave = false
if (!recipient.isGroupRecipient) {
val deviceLinks = lokiAPIDatabase.getDeviceLinks(publicKey)
isSlave = deviceLinks.find { it.slaveHexEncodedPublicKey == publicKey } != null
}
result.add(Contact(recipient, isFriend, isSlave, isUserDevice))
}
}
return result
}
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.content.ContentValues
import net.sqlcipher.Cursor

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.content.Context
import android.graphics.Typeface

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.content.Context
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.content.Context
import nl.komponents.kovenant.Promise
@@ -29,7 +29,7 @@ object OpenGroupUtilities {
lokiPublicChatAPI.setDisplayName(displayName, url)
lokiPublicChatAPI.join(channel, url)
val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(context)
val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(context)
val profileUrl: String? = TextSecurePreferences.getProfilePictureURL(context)
lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl)
group
}

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.graphics.PointF
import android.view.View

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.graphics.Bitmap
import android.graphics.Color

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.view.ViewGroup

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.utilities
package org.thoughtcrime.securesms.loki.utilities
import android.graphics.PointF
import android.graphics.Rect

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.graphics.Typeface
@@ -9,8 +9,8 @@ import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_conversation.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities.populateUserHexEncodedPublicKeyCacheIfNeeded
import org.thoughtcrime.securesms.loki.redesign.utilities.MentionUtilities.highlightMentions
import org.thoughtcrime.securesms.loki.api.MentionManagerUtilities.populateUserHexEncodedPublicKeyCacheIfNeeded
import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.util.DateUtils
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager
@@ -53,7 +53,7 @@ class ConversationView : LinearLayout {
profilePictureView.hexEncodedPublicKey = ""
profilePictureView.isRSSFeed = true
} else {
val users = MentionsManager.userHexEncodedPublicKeyCache[thread.threadId]?.toList() ?: listOf()
val users = MentionsManager.shared.userHexEncodedPublicKeyCache[thread.threadId]?.toList() ?: listOf()
val randomUsers = users.sorted() // Sort to provide a level of stability
profilePictureView.hexEncodedPublicKey = randomUsers.getOrNull(0) ?: ""
profilePictureView.additionalHexEncodedPublicKey = randomUsers.getOrNull(1) ?: ""

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.util.AttributeSet

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.content.Context.LAYOUT_INFLATER_SERVICE

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.os.Build

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.graphics.Canvas

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.util.AttributeSet

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.util.AttributeSet

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.animation.ArgbEvaluator
import android.animation.FloatEvaluator
@@ -22,8 +22,8 @@ import android.widget.ImageView
import android.widget.RelativeLayout
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.getColorWithID
import org.thoughtcrime.securesms.loki.redesign.utilities.*
import org.thoughtcrime.securesms.loki.toPx
import org.thoughtcrime.securesms.loki.utilities.*
class NewConversationButtonSetView : RelativeLayout {
private var expandedButton: Button? = null

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.support.annotation.DimenRes

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.os.Build

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.util.AttributeSet

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki.redesign.views
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.util.AttributeSet
@@ -53,7 +53,7 @@ class UserView : LinearLayout {
profilePictureView.isRSSFeed = true
} else {
val threadID = GroupManager.getThreadIdFromGroupId(address, context)
val users = MentionsManager.userHexEncodedPublicKeyCache[threadID]?.toList() ?: listOf()
val users = MentionsManager.shared.userHexEncodedPublicKeyCache[threadID]?.toList() ?: listOf()
val randomUsers = users.sorted() // Sort to provide a level of stability
profilePictureView.hexEncodedPublicKey = randomUsers.getOrNull(0) ?: ""
profilePictureView.additionalHexEncodedPublicKey = randomUsers.getOrNull(1) ?: ""