Merge branch 'dev' of https://github.com/oxen-io/session-android into fix-open-group-spam

This commit is contained in:
ryanzhao
2021-05-24 14:49:56 +10:00
88 changed files with 997 additions and 1772 deletions

View File

@@ -2,6 +2,7 @@ package org.session.libsession.database
import android.content.Context
import android.net.Uri
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.jobs.AttachmentUploadJob
import org.session.libsession.messaging.jobs.Job
import org.session.libsession.messaging.jobs.MessageReceiveJob
@@ -32,11 +33,7 @@ interface StorageProtocol {
fun getUserDisplayName(): String?
fun getUserProfileKey(): ByteArray?
fun getUserProfilePictureURL(): String?
fun setUserProfilePictureURL(newValue: String)
fun getProfileKeyForRecipient(recipientPublicKey: String): ByteArray?
fun getDisplayNameForRecipient(recipientPublicKey: String): String?
fun setProfileKeyForRecipient(recipientPublicKey: String, profileKey: ByteArray)
fun setUserProfilePictureURL(newProfilePicture: String)
// Signal
fun getOrGenerateRegistrationID(): Int
@@ -135,9 +132,9 @@ interface StorageProtocol {
fun getLastUpdated(threadID: Long): Long
// Contacts
fun getDisplayName(publicKey: String): String?
fun setDisplayName(publicKey: String, newName: String)
fun getProfilePictureURL(publicKey: String): String?
fun getContactWithSessionID(sessionID: String): Contact?
fun getAllContacts(): Set<Contact>
fun setContact(contact: Contact)
fun getRecipientSettings(address: Address): RecipientSettings?
fun addContacts(contacts: List<ConfigurationMessage.Contact>)

View File

@@ -0,0 +1,87 @@
package org.session.libsession.messaging.contacts
import org.session.libsession.utilities.recipients.Recipient
class Contact(val sessionID: String) {
/**
* The URL from which to fetch the contact's profile picture.
*/
var profilePictureURL: String? = null
/**
* The file name of the contact's profile picture on local storage.
*/
var profilePictureFileName: String? = null
/**
* The key with which the profile picture is encrypted.
*/
var profilePictureEncryptionKey: ByteArray? = null
/**
* The ID of the thread associated with this contact.
*/
var threadID: Long? = null
/**
* This flag is used to determine whether we should auto-download files sent by this contact.
*/
var isTrusted = false
// region Name
/**
* The name of the contact. Use this whenever you need the "real", underlying name of a user (e.g. when sending a message).
*/
var name: String? = null
/**
* The contact's nickname, if the user set one.
*/
var nickname: String? = null
/**
* The name to display in the UI. For local use only.
*/
fun displayName(context: ContactContext): String? {
nickname?.let { return it }
return when (context) {
ContactContext.REGULAR -> name
ContactContext.OPEN_GROUP -> {
// In open groups, where it's more likely that multiple users have the same name,
// we display a bit of the Session ID after a user's display name for added context.
name?.let {
return "$name (...${sessionID.takeLast(8)})"
}
return null
}
}
}
// endregion
enum class ContactContext {
REGULAR, OPEN_GROUP
}
fun isValid(): Boolean {
if (profilePictureURL != null) { return profilePictureEncryptionKey != null }
if (profilePictureEncryptionKey != null) { return profilePictureURL != null}
return true
}
override fun equals(other: Any?): Boolean {
return this.sessionID == (other as? Contact)?.sessionID
}
override fun hashCode(): Int {
return sessionID.hashCode()
}
override fun toString(): String {
return nickname ?: name ?: sessionID
}
companion object {
fun contextForRecipient(recipient: Recipient): ContactContext {
return if (recipient.isOpenGroupRecipient) {
ContactContext.OPEN_GROUP
} else {
ContactContext.REGULAR
}
}
}
}

View File

@@ -1,22 +1,11 @@
package org.session.libsession.messaging.mentions
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.contacts.Contact
import org.session.libsignal.database.LokiUserDatabaseProtocol
class MentionsManager(private val userPublicKey: String, private val userDatabase: LokiUserDatabaseProtocol) {
object MentionsManager {
var userPublicKeyCache = mutableMapOf<Long, Set<String>>() // Thread ID to set of user hex encoded public keys
companion object {
public lateinit var shared: MentionsManager
public fun configureIfNeeded(userPublicKey: String, userDatabase: LokiUserDatabaseProtocol) {
if (::shared.isInitialized) { return; }
shared = MentionsManager(userPublicKey, userDatabase)
}
}
fun cache(publicKey: String, threadID: Long) {
val cache = userPublicKeyCache[threadID]
if (cache != null) {
@@ -26,14 +15,16 @@ class MentionsManager(private val userPublicKey: String, private val userDatabas
}
}
fun getMentionCandidates(query: String, threadID: Long): List<Mention> {
// Prepare
fun getMentionCandidates(query: String, threadID: Long, isOpenGroup: Boolean): List<Mention> {
val cache = userPublicKeyCache[threadID] ?: return listOf()
// Prepare
val context = if (isOpenGroup) Contact.ContactContext.OPEN_GROUP else Contact.ContactContext.REGULAR
val storage = MessagingModuleConfiguration.shared.storage
val userPublicKey = storage.getUserPublicKey()
// Gather candidates
var candidates: List<Mention> = cache.mapNotNull { publicKey ->
val displayName = userDatabase.getDisplayName(publicKey)
if (displayName == null) { return@mapNotNull null }
if (displayName.startsWith("Anonymous")) { return@mapNotNull null }
val contact = storage.getContactWithSessionID(publicKey)
val displayName = contact?.displayName(context) ?: return@mapNotNull null
Mention(publicKey, displayName)
}
candidates = candidates.filter { it.publicKey != userPublicKey }

View File

@@ -13,8 +13,10 @@ import okhttp3.HttpUrl
import okhttp3.MediaType
import okhttp3.RequestBody
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPollerV2
import org.session.libsession.snode.OnionRequestAPI
import org.session.libsession.utilities.AESGCM
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.HTTP
import org.session.libsignal.utilities.HTTP.Verb.*
import org.session.libsignal.utilities.removing05PrefixIfNeeded
@@ -30,6 +32,15 @@ object OpenGroupAPIV2 {
private val moderators: HashMap<String, Set<String>> = hashMapOf() // Server URL to (channel ID to set of moderator IDs)
private val curve = Curve25519.getInstance(Curve25519.BEST)
val defaultRooms = MutableSharedFlow<List<DefaultGroup>>(replay = 1)
private val hasPerformedInitialPoll = mutableMapOf<String, Boolean>()
private var hasUpdatedLastOpenDate = false
private val timeSinceLastOpen by lazy {
val context = MessagingModuleConfiguration.shared.context
val lastOpenDate = TextSecurePreferences.getLastOpenTimeDate(context)
val now = System.currentTimeMillis()
now - lastOpenDate
}
private const val defaultServerPublicKey = "a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238"
const val defaultServer = "http://116.203.70.33"
@@ -65,14 +76,14 @@ object OpenGroupAPIV2 {
}
data class Request(
val verb: HTTP.Verb,
val room: String?,
val server: String,
val endpoint: String,
val queryParameters: Map<String, String> = mapOf(),
val parameters: Any? = null,
val headers: Map<String, String> = mapOf(),
val isAuthRequired: Boolean = true,
val verb: HTTP.Verb,
val room: String?,
val server: String,
val endpoint: String,
val queryParameters: Map<String, String> = mapOf(),
val parameters: Any? = null,
val headers: Map<String, String> = mapOf(),
val isAuthRequired: Boolean = true,
/**
* Always `true` under normal circumstances. You might want to disable
* this when running over Lokinet.
@@ -349,6 +360,15 @@ object OpenGroupAPIV2 {
fun compactPoll(rooms: List<String>, server: String): Promise<Map<String, CompactPollResult>, Exception> {
val authTokenRequests = rooms.associateWith { room -> getAuthToken(room, server) }
val storage = MessagingModuleConfiguration.shared.storage
val context = MessagingModuleConfiguration.shared.context
val timeSinceLastOpen = this.timeSinceLastOpen
val useMessageLimit = (hasPerformedInitialPoll[server] != true
&& timeSinceLastOpen > OpenGroupPollerV2.maxInactivityPeriod)
hasPerformedInitialPoll[server] = true
if (!hasUpdatedLastOpenDate) {
hasUpdatedLastOpenDate = true
TextSecurePreferences.setLastOpenDate(context)
}
val requests = rooms.mapNotNull { room ->
val authToken = try {
authTokenRequests[room]?.get()
@@ -359,8 +379,8 @@ object OpenGroupAPIV2 {
CompactPollRequest(
roomID = room,
authToken = authToken,
fromDeletionServerID = storage.getLastDeletionServerID(room, server),
fromMessageServerID = storage.getLastMessageServerID(room, server)
fromDeletionServerID = if (useMessageLimit) null else storage.getLastDeletionServerID(room, server),
fromMessageServerID = if (useMessageLimit) null else storage.getLastMessageServerID(room, server)
)
}
val request = Request(verb = POST, room = null, server = server, endpoint = "compact_poll", isAuthRequired = false, parameters = mapOf( "requests" to requests ))

View File

@@ -128,16 +128,20 @@ private fun handleConfigurationMessage(message: ConfigurationMessage) {
if (allV2OpenGroups.contains(openGroup)) continue
storage.addOpenGroup(openGroup)
}
val profileManager = SSKEnvironment.shared.profileManager
val recipient = Recipient.from(context, Address.fromSerialized(userPublicKey), false)
if (message.displayName.isNotEmpty()) {
TextSecurePreferences.setProfileName(context, message.displayName)
storage.setDisplayName(userPublicKey, message.displayName)
profileManager.setName(context, recipient, message.displayName)
}
if (message.profileKey.isNotEmpty() && !message.profilePicture.isNullOrEmpty()
&& TextSecurePreferences.getProfilePictureURL(context) != message.profilePicture) {
val profileKey = Base64.encodeBytes(message.profileKey)
ProfileKeyUtil.setEncodedProfileKey(context, profileKey)
storage.setProfileKeyForRecipient(userPublicKey, message.profileKey)
storage.setUserProfilePictureURL(message.profilePicture!!)
profileManager.setProfileKey(context, recipient, message.profileKey)
if (!message.profilePicture.isNullOrEmpty() && TextSecurePreferences.getProfilePictureURL(context) != message.profilePicture) {
storage.setUserProfilePictureURL(message.profilePicture!!)
}
}
storage.addContacts(message.contacts)
}
@@ -162,9 +166,9 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS
if (profile != null && userPublicKey != message.sender) {
val profileManager = SSKEnvironment.shared.profileManager
val recipient = Recipient.from(context, Address.fromSerialized(message.sender!!), false)
val displayName = profile.displayName!!
if (displayName.isNotEmpty()) {
profileManager.setDisplayName(context, recipient, displayName)
val name = profile.displayName!!
if (name.isNotEmpty()) {
profileManager.setName(context, recipient, name)
}
if (profile.profileKey?.isNotEmpty() == true && profile.profilePictureURL?.isNotEmpty() == true
&& (recipient.profileKey == null || !MessageDigest.isEqual(recipient.profileKey, profile.profileKey))) {

View File

@@ -24,6 +24,7 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
companion object {
private val pollInterval: Long = 4 * 1000
const val maxInactivityPeriod = 14 * 24 * 60 * 60 * 1000
}
fun startIfNeeded() {

View File

@@ -3,6 +3,7 @@ package org.session.libsession.messaging.utilities
import android.content.Context
import org.session.libsession.R
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage
import org.session.libsession.utilities.ExpirationUtil
@@ -12,8 +13,9 @@ object UpdateMessageBuilder {
var message = ""
val updateData = updateMessageData.kind ?: return message
if (!isOutgoing && sender == null) return message
val storage = MessagingModuleConfiguration.shared.storage
val senderName: String = if (!isOutgoing) {
MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender
storage.getContactWithSessionID(sender!!)?.displayName(Contact.ContactContext.REGULAR) ?: sender
} else { context.getString(R.string.MessageRecord_you) }
when (updateData) {
@@ -33,7 +35,7 @@ object UpdateMessageBuilder {
}
is UpdateMessageData.Kind.GroupMemberAdded -> {
val members = updateData.updatedMembers.joinToString(", ") {
MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(it) ?: it
storage.getContactWithSessionID(it)?.displayName(Contact.ContactContext.REGULAR) ?: it
}
message = if (isOutgoing) {
context.getString(R.string.MessageRecord_you_added_s_to_the_group, members)
@@ -54,7 +56,7 @@ object UpdateMessageBuilder {
} else {
// 2nd case: you are not part of the removed members
val members = updateData.updatedMembers.joinToString(", ") {
storage.getDisplayNameForRecipient(it) ?: it
storage.getContactWithSessionID(it)?.displayName(Contact.ContactContext.REGULAR) ?: it
}
if (isOutgoing) {
context.getString(R.string.MessageRecord_you_removed_s_from_the_group, members)
@@ -76,8 +78,9 @@ object UpdateMessageBuilder {
fun buildExpirationTimerMessage(context: Context, duration: Long, sender: String? = null, isOutgoing: Boolean = false): String {
if (!isOutgoing && sender == null) return ""
val storage = MessagingModuleConfiguration.shared.storage
val senderName: String? = if (!isOutgoing) {
MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender
storage.getContactWithSessionID(sender!!)?.displayName(Contact.ContactContext.REGULAR) ?: sender
} else { context.getString(R.string.MessageRecord_you) }
return if (duration <= 0) {
if (isOutgoing) context.getString(R.string.MessageRecord_you_disabled_disappearing_messages)
@@ -90,7 +93,8 @@ object UpdateMessageBuilder {
}
fun buildDataExtractionMessage(context: Context, kind: DataExtractionNotificationInfoMessage.Kind, sender: String? = null): String {
val senderName = MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender
val storage = MessagingModuleConfiguration.shared.storage
val senderName = storage.getContactWithSessionID(sender!!)?.displayName(Contact.ContactContext.REGULAR) ?: sender!!
return when (kind) {
DataExtractionNotificationInfoMessage.Kind.SCREENSHOT ->
context.getString(R.string.MessageRecord_s_took_a_screenshot, senderName)

View File

@@ -29,7 +29,8 @@ class SSKEnvironment(
const val NAME_PADDED_LENGTH = 26
}
fun setDisplayName(context: Context, recipient: Recipient, displayName: String)
fun setNickname(context: Context, recipient: Recipient, nickname: String?)
fun setName(context: Context, recipient: Recipient, name: String)
fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String)
fun setProfileKey(context: Context, recipient: Recipient, profileKey: ByteArray)
fun setUnidentifiedAccessMode(context: Context, recipient: Recipient, unidentifiedAccessMode: Recipient.UnidentifiedAccessMode)

View File

@@ -99,16 +99,16 @@ object TextSecurePreferences {
private const val GIF_GRID_LAYOUT = "pref_gif_grid_layout"
// region FCM
const val IS_USING_FCM = "pref_is_using_fcm"
private const val FCM_TOKEN = "pref_fcm_token"
private const val LAST_FCM_TOKEN_UPLOAD_TIME = "pref_last_fcm_token_upload_time_2"
// region Multi Device
private const val LAST_CONFIGURATION_SYNC_TIME = "pref_last_configuration_sync_time"
const val CONFIGURATION_SYNCED = "pref_configuration_synced"
private const val LAST_PROFILE_UPDATE_TIME = "pref_last_profile_update_time"
private const val LAST_OPEN_DATE = "pref_last_open_date"
@JvmStatic
fun getLastConfigurationSyncTime(context: Context): Long {
return getLongPreference(context, LAST_CONFIGURATION_SYNC_TIME, 0)
@@ -764,12 +764,19 @@ object TextSecurePreferences {
fun shouldUpdateProfile(context: Context, profileUpdateTime: Long) =
profileUpdateTime > getLongPreference(context, LAST_PROFILE_UPDATE_TIME, 0)
fun hasSeenFileServerInstabilityNotification(context: Context): Boolean {
return getBooleanPreference(context, "has_seen_file_server_instability_notification", false)
fun hasPerformedContactMigration(context: Context): Boolean {
return getBooleanPreference(context, "has_performed_contact_migration", false)
}
fun setHasSeenFileServerInstabilityNotification(context: Context) {
setBooleanPreference(context, "has_seen_file_server_instability_notification", true)
fun setPerformedContactMigration(context: Context) {
setBooleanPreference(context, "has_performed_contact_migration", true)
}
fun getLastOpenTimeDate(context: Context): Long {
return getLongPreference(context, LAST_OPEN_DATE, 0)
}
fun setLastOpenDate(context: Context) {
setLongPreference(context, LAST_OPEN_DATE, System.currentTimeMillis())
}
// endregion
}

View File

@@ -26,10 +26,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.function.Consumer;
import com.esotericsoftware.kryo.util.Null;
import org.greenrobot.eventbus.EventBus;
import org.session.libsession.database.StorageProtocol;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsession.avatars.TransparentContactPhoto;
import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.recipients.RecipientProvider.RecipientDetails;
@@ -286,20 +289,23 @@ public class Recipient implements RecipientModifiedListener {
}
public synchronized @Nullable String getName() {
String displayName = MessagingModuleConfiguration.shared.getStorage().getDisplayName(this.address.toString());
if (displayName != null) { return displayName; }
if (this.name == null && isGroupRecipient()) {
List<String> names = new LinkedList<>();
for (Recipient recipient : participants) {
names.add(recipient.toShortString());
StorageProtocol storage = MessagingModuleConfiguration.shared.getStorage();
String sessionID = this.address.toString();
if (isGroupRecipient()) {
if (this.name == null) {
List<String> names = new LinkedList<>();
for (Recipient recipient : participants) {
names.add(recipient.toShortString());
}
return Util.join(names, ", ");
} else {
return this.name;
}
return Util.join(names, ", ");
} else {
Contact contact = storage.getContactWithSessionID(sessionID);
if (contact == null) { return sessionID; }
return contact.displayName(Contact.ContactContext.REGULAR);
}
return this.name;
}
public void setName(@Nullable String name) {

View File

@@ -1,441 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Session -->
<style name="Widget.Session.ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="android:background">?colorPrimary</item>
<item name="elevation">1dp</item>
<item name="titleTextStyle">@style/TextAppearance.Session.DarkActionBar.TitleTextStyle</item>
</style>
<style name="Widget.Session.ActionBar.Flat">
<item name="android:elevation">0dp</item>
<item name="elevation">0dp</item>
</style>
<style name="TextAppearance.Session.DarkActionBar.TitleTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:textSize">@dimen/very_large_font_size</item>
</style>
<style name="Widget.Session.SearchView" parent="@style/Widget.AppCompat.SearchView">
<item name="closeIcon">@drawable/ic_clear</item>
</style>
<style name="ThemeOverlay.Session.AlertDialog" parent="ThemeOverlay.AppCompat.Dialog.Alert">
<item name="buttonBarNegativeButtonStyle">@style/Widget.Session.AlertDialog.NegativeButtonStyle</item>
<item name="buttonBarPositiveButtonStyle">@style/Widget.Session.AlertDialog.PositiveButtonStyle</item>
</style>
<style name="Widget.Session.BottomSheetDialog" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/default_bottom_sheet_background</item>
</style>
<style name="Widget.Session.AlertDialog.NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">@color/accent</item>
</style>
<style name="Widget.Session.AlertDialog.PositiveButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">@color/accent</item>
</style>
<style name="Widget.Session.AppBarLayout" parent="@style/Widget.Design.AppBarLayout">
</style>
<style name="Widget.Session.TabBar" parent="Widget.AppCompat.ActionBar.TabBar">
<item name="elevation">1dp</item>
</style>
<style name="Widget.Session.TabLayout" parent="Widget.Design.TabLayout">
<item name="elevation">1dp</item>
<item name="tabIndicatorColor">?colorAccent</item>
<item name="tabSelectedTextColor">?colorAccent</item>>
<item name="tabIndicatorHeight">@dimen/accent_line_thickness</item>
<item name="tabRippleColor">@color/cell_selected</item>
<item name="tabTextAppearance">@style/TextAppearance.Session.Tab</item>
</style>
<style name="TextAppearance.Session.Tab" parent="TextAppearance.Design.Tab">
<item name="android:textSize">@dimen/medium_font_size</item>
<item name="textAllCaps">false</item>
</style>
<!-- TODO These button styles require proper background selectors for up/down visual state. -->
<style name="Widget.Session.Button.Common" parent="">
<item name="android:textAllCaps">false</item>
<item name="android:textSize">@dimen/medium_font_size</item>
<item name="android:fontFamily">sans-serif-medium</item>
<!-- Helps to get rid of nasty elevation. We want a flat style here. -->
<!-- https://stackoverflow.com/a/31003693/3802890 -->
<item name ="android:stateListAnimator">@null</item>
</style>
<style name="Widget.Session.Button.Common.ProminentFilled">
<item name="android:background">@drawable/prominent_filled_button_medium_background</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:drawableTint" tools:ignore="NewApi">?android:textColorPrimary</item>
</style>
<style name="Widget.Session.Button.Common.ProminentOutline">
<item name="android:background">@drawable/prominent_outline_button_medium_background</item>
<item name="android:textColor">@color/accent</item>
<item name="android:drawableTint" tools:ignore="NewApi">@color/accent</item>
</style>
<style name="Widget.Session.Button.Common.UnimportantFilled">
<item name="android:background">@drawable/unimportant_filled_button_medium_background</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:drawableTint" tools:ignore="NewApi">?android:textColorPrimary</item>
</style>
<style name="Widget.Session.Button.Common.UnimportantOutline">
<item name="android:background">@drawable/unimportant_outline_button_medium_background</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:drawableTint" tools:ignore="NewApi">?android:textColorPrimary</item>
</style>
<style name="Widget.Session.Button.Dialog" parent="">
<item name="android:textAllCaps">false</item>
<item name="android:textSize">@dimen/small_font_size</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
<style name="Widget.Session.Button.Dialog.Unimportant">
<item name="android:background">@drawable/unimportant_dialog_button_background</item>
</style>
<style name="Widget.Session.Button.Dialog.Prominent">
<item name="android:background">@drawable/prominent_dialog_button_background</item>
<item name="android:textColor">#222</item>
</style>
<style name="Widget.Session.Button.Dialog.Destructive">
<item name="android:background">@drawable/destructive_dialog_button_background</item>
<item name="android:textColor">@android:color/white</item>
</style>
<style name="Widget.Session.EditText.Compose" parent="@style/Signal.Text.Body">
<item name="android:padding">2dp</item>
<item name="android:background">@null</item>
<item name="android:maxLines">4</item>
<item name="android:maxLength">65536</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:capitalize">sentences</item>
<item name="android:autoText">true</item>
<item name="android:gravity">center_vertical</item>
<item name="android:imeOptions">flagNoEnterAction</item>
<item name="android:inputType">textAutoCorrect|textCapSentences|textMultiLine</item>
<item name="android:contentDescription">@string/conversation_activity__compose_description</item>
<item name="android:textColorHint">?android:textColorHint</item>
<item name="android:textSize">@dimen/small_font_size</item>
<item name="android:textCursorDrawable">@drawable/session_edit_text_cursor</item>
<item name="android:textAlignment">viewStart</item>
</style>
<style name="ThemeOverlay.Session.Settings" parent="PreferenceThemeOverlay.v14.Material" >
<item name="android:textColor">@color/text</item>
<item name="android:textColorSecondary">#99FFFFFF</item>
<item name="android:textSize">@dimen/medium_font_size</item>
</style>
<style name="SessionIDTextView">
<item name="android:background">@drawable/session_id_text_view_background</item>
<item name="android:padding">@dimen/medium_spacing</item>
<item name="android:textSize">@dimen/large_font_size</item>
<item name="android:textColor">@color/text</item>
<item name="android:fontFamily">@font/space_mono_regular</item>
<item name="android:textAlignment">viewStart</item>
</style>
<style name="SessionEditText">
<item name="android:background">@drawable/session_id_text_view_background</item>
<item name="android:paddingLeft">@dimen/medium_spacing</item>
<item name="android:paddingTop">30dp</item>
<item name="android:paddingRight">@dimen/medium_spacing</item>
<item name="android:paddingBottom">30dp</item>
<item name="android:textSize">@dimen/small_font_size</item>
<item name="android:textColor">@color/text</item>
<item name="android:textCursorDrawable">@drawable/session_edit_text_cursor</item>
<item name="android:textAlignment">viewStart</item>
<item name="android:maxLines">1</item>
</style>
<style name="SmallSessionEditText">
<item name="android:background">@drawable/session_id_text_view_background</item>
<item name="android:paddingLeft">@dimen/medium_spacing</item>
<item name="android:paddingTop">@dimen/medium_spacing</item>
<item name="android:paddingRight">@dimen/medium_spacing</item>
<item name="android:paddingBottom">@dimen/medium_spacing</item>
<item name="android:textSize">@dimen/small_font_size</item>
<item name="android:textColor">@color/text</item>
<item name="android:textCursorDrawable">@drawable/session_edit_text_cursor</item>
<item name="android:textAlignment">viewStart</item>
<item name="android:maxLines">1</item>
</style>
<style name="FakeChatViewMessageBubble">
<item name="android:paddingLeft">@dimen/medium_spacing</item>
<item name="android:paddingTop">12dp</item>
<item name="android:paddingRight">@dimen/medium_spacing</item>
<item name="android:paddingBottom">12dp</item>
<item name="android:textSize">15sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:elevation">0dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
<style name="FakeChatViewMessageBubble.Incoming">
<item name="android:background">@drawable/fake_chat_view_incoming_message_background</item>
<item name="android:elevation">10dp</item>
</style>
<style name="FakeChatViewMessageBubble.Outgoing">
<item name="android:background">@drawable/fake_chat_view_outgoing_message_background</item>
<item name="android:elevation">10dp</item>
</style>
<!-- Session -->
<style name="NoAnimation.Theme.BlackScreen" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@android:color/black</item>
</style>
<style name="NoAnimation.Theme.AppCompat.Light.DarkActionBar" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowAnimationStyle">@null</item>
</style>
<style name="TextSecure.DialogActivity" parent="Theme.AppCompat.Light">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
<style name="AppCompatAlertDialogStyleLight" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="colorAccent">@color/signal_primary_dark</item>
</style>
<style name="AppCompatAlertDialogStyleDark" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorAccent">@color/signal_primary</item>
<item name="android:textColor">@null</item>
</style>
<style name="AppCompatDialogStyleLight" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">@color/signal_primary_dark</item>
<item name="android:windowBackground">@drawable/dialog_background</item>
</style>
<style name="AppCompatDialogStyleDark" parent="Theme.AppCompat.Dialog">
<item name="colorAccent">@color/signal_primary</item>
<item name="android:windowBackground">@drawable/dialog_background</item>
<item name="android:textColor">@null</item>
</style>
<!-- ActionBar styles -->
<style name="TextSecure.DarkActionBar"
parent="@style/Widget.AppCompat.ActionBar">
<item name="background">@color/core_grey_90</item>
<item name="android:popupTheme" tools:ignore="NewApi">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="elevation">1dp</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="titleTextStyle">@style/TextSecure.TitleTextStyle</item>
<item name="subtitleTextStyle">@style/TextSecure.SubtitleTextStyle</item>
<item name="android:textColorSecondary">@color/white</item>
</style>
<style name="TextSecure.LightActionBar"
parent="@style/Widget.AppCompat.ActionBar">
<item name="background">@color/textsecure_primary</item>
<item name="elevation">1dp</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="titleTextStyle">@style/TextSecure.TitleTextStyle</item>
<item name="subtitleTextStyle">@style/TextSecure.SubtitleTextStyle</item>
<item name="android:textColorPrimary">@color/white</item>
<item name="android:textColorSecondary">@color/white</item>
</style>
<style name="TextSecure.LightActionBar.DarkText"
parent="TextSecure.LightActionBar">
<item name="android:textColorPrimary">@color/black</item>
<item name="android:textColorSecondary">@color/black</item>
</style>
<style name="TextSecure.FlatLightActionBar"
parent="@style/TextSecure.LightActionBar">
<item name="elevation">0dp</item>
</style>
<style name="TextSecure.DarkActionBar.TabBar"
parent="@style/Widget.AppCompat.ActionBar.TabBar">
<item name="background">@color/gray95</item>
<item name="android:background">@color/gray95</item>
<item name="elevation">4dp</item>
</style>
<style name="TextSecure.LightActionBar.TabBar"
parent="@style/Widget.AppCompat.ActionBar.TabBar">
<item name="android:background">@color/textsecure_primary</item>
<item name="background">@color/textsecure_primary</item>
<item name="android:textColorPrimary">@color/white</item>
<item name="android:textColorSecondary">#BFffffff</item>
<item name="elevation">4dp</item>
</style>
<style name="TextSecure.TitleTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">@color/white</item>
<item name="android:textColorHint">#BFffffff</item>
</style>
<style name="TextSecure.SubtitleTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Subtitle">
<item name="android:textColor">#BFffffff</item>
</style>
<style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent">
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title">
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textStyle">bold</item>
</style>
<style name="Registration.Description" parent="@android:style/TextAppearance">
<item name="android:textSize">16.0sp</item>
<item name="android:typeface">sans</item>
<item name="android:textStyle">normal</item>
<item name="android:gravity">left</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:shadowColor">#ffffff</item>
<item name="android:shadowDx">1.0</item>
<item name="android:shadowDy">1.0</item>
<item name="android:shadowRadius">0.0</item>
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
<style name="Registration.Label" parent="@android:style/TextAppearance">
<item name="android:textSize">12.0sp</item>
<item name="android:typeface">sans</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">#ff808080</item>
<item name="android:gravity">left</item>
<item name="android:layout_gravity">left</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:shadowColor">#ffffff</item>
<item name="android:shadowDx">1.0</item>
<item name="android:shadowDy">1.0</item>
<item name="android:shadowRadius">0.0</item>
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
<style name="Registration.BigLabel" parent="@style/Registration.Label">
<item name="android:textSize">20sp</item>
</style>
<style name="Registration.Constant" parent="@android:style/TextAppearance">
<item name="android:typeface">sans</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">#ff808080</item>
<item name="android:shadowColor">#ffffff</item>
<item name="android:shadowDx">1.0</item>
<item name="android:shadowDy">1.0</item>
<item name="android:shadowRadius">0.0</item>
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
<!-- For Holo Light Dialog Activity Styling Emulation -->
<style name="Widget.ProgressBar.Horizontal" parent="@android:style/Widget.Holo.ProgressBar.Horizontal">
</style>
<style name="MaterialButton">
<item name="android:elevation" tools:ignore="NewApi">1dp</item>
<item name="android:translationZ" tools:ignore="NewApi">1dp</item>
<item name="android:textColor">@color/white</item>
<item name="android:textSize">12sp</item>
</style>
<style name="InfoButton" parent="@style/MaterialButton">
<item name="android:background">@drawable/info_round</item>
</style>
<style name="ErrorButton" parent="@style/MaterialButton">
<item name="android:background">@drawable/error_round</item>
</style>
<style name="AttachmentTypeLabel">
<item name="android:textColor">?android:textColorTertiary</item>
<item name="android:textSize">@dimen/small_font_size</item>
</style>
<style name="Button.Primary" parent="Base.Widget.AppCompat.Button.Colored">
<item name="colorAccent">@color/signal_primary</item>
<item name="android:textColor">@color/white</item>
</style>
<style name="Button.Borderless" parent="Base.Widget.AppCompat.Button.Borderless">
<item name="android:textColor">@color/signal_primary</item>
</style>
<style name="Button.Borderless.Registration" parent="Base.Widget.AppCompat.Button.Borderless">
<item name="android:textColor">@color/core_grey_60</item>
</style>
<!-- RedPhone -->
<!-- Buttons in the main "button row" of the in-call onscreen touch UI. -->
<!-- "Compound button" variation of InCallButton.
These buttons have the concept of two states: checked and unchecked.
(This style is just like "InCallButton" except that we also
clear out android:textOn and android:textOff, to avoid the default
text label behavior of the ToggleButton class.) -->
<style name="WebRtcCallCompoundButton">
<item name="android:layout_height">31dp</item>
<item name="android:layout_width">31dp</item>
<item name="android:textOn">@null</item>
<item name="android:textOff">@null</item>
</style>
<style name="IdentityKey">
<item name="android:fontFamily">monospace</item>
<item name="android:typeface">monospace</item>
<item name="android:textSize">17sp</item>
<item name="android:clickable">false</item>
<item name="android:focusable">false</item>
</style>
<style name="BackupPassphrase">
<item name="android:fontFamily">monospace</item>
<item name="android:typeface">monospace</item>
<item name="android:textSize">15sp</item>
<item name="android:clickable">false</item>
<item name="android:focusable">false</item>
</style>
<style name="PreferenceThemeOverlay.Fix" parent="PreferenceThemeOverlay.v14.Material">
</style>
<style name="Color1SwitchStyle">
<item name="colorControlActivated">@color/white</item>
</style>
<style name="BottomSheetActionItem">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/action_item_height</item>
<item name="android:textSize">@dimen/medium_font_size</item>
<item name="android:drawablePadding">@dimen/drawable_padding</item>
<item name="android:padding">@dimen/normal_padding</item>
<item name="android:gravity">center_vertical</item>
<item name="android:selectable">true</item>
<item name="android:foreground">?attr/selectableItemBackground</item>
</style>
<style name="StickerPopupAnimation" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/fade_in</item>
<item name="android:windowExitAnimation">@anim/fade_out</item>
</style>
</resources>

View File

@@ -1,294 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Session -->
<!-- Due to historical reasons the base theme is dark and the light one
is implemented using "notnight" type of resources. -->
<style name="Base.Theme.Session" parent="@style/Theme.AppCompat.DayNight.DarkActionBar">
<item name="colorPrimary">@color/action_bar_background</item>
<item name="colorPrimaryDark">@color/action_bar_background</item>
<item name="colorAccent">@color/accent</item>
<item name="colorControlNormal">?android:textColorPrimary</item>
<item name="colorControlActivated">?colorAccent</item>
<item name="colorControlHighlight">?colorAccent</item>
<item name="android:textColorPrimary">@color/text</item>
<item name="android:textColorSecondary">?android:textColorPrimary</item>
<item name="android:textColorTertiary">@color/unimportant</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:textColorHint">@color/gray27</item>
<item name="android:windowBackground">@drawable/default_session_background</item>
<item name="android:colorBackground">@color/default_background_start</item>
<item name="android:navigationBarColor">@color/compose_view_background</item>
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/ThemeOverlay.AppCompat.DayNight.ActionBar</item>
<item name="actionBarStyle">@style/Widget.Session.ActionBar</item>
<item name="alertDialogTheme">@style/ThemeOverlay.Session.AlertDialog</item>
<item name="bottomSheetDialogTheme">@style/Theme.Session.BottomSheet</item>
<item name="preferenceTheme">@style/ThemeOverlay.Session.Settings</item>
<item name="appBarLayoutStyle">@style/Widget.Session.AppBarLayout</item>
<item name="actionBarTabBarStyle">@style/Widget.Session.TabBar</item>
<item name="statusBarBackground">@color/accent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionModeCloseDrawable">@drawable/ic_baseline_clear_24</item>
<item name="actionModeBackground">@color/compose_view_background</item>
<item name="dividerVertical">@color/separator</item>
<item name="dividerHorizontal">?dividerVertical</item>
<item name="searchViewStyle">@style/Widget.Session.SearchView</item>
<!-- App specific attributes -->
<item name="ic_visibility_on">@drawable/ic_baseline_visibility_24</item>
<item name="ic_visibility_off">@drawable/ic_baseline_visibility_off_24</item>
<item name="ic_arrow_forward">@drawable/ic_baseline_arrow_forward_24</item>
<item name="dialog_background_color">@color/dialog_background</item>
<item name="media_overview_toolbar_background">@color/transparent</item>
<item name="media_overview_header_foreground">@color/text</item>
<item name="media_keyboard_button_color">@color/core_grey_25</item>\
<item name="attachment_type_selector_background">?android:windowBackground</item>
<item name="attachment_type_selector_hide_button_background">@color/gray50</item>
<item name="attachment_document_icon_small">@drawable/ic_document_small_dark</item>
<item name="attachment_document_icon_large">@drawable/ic_document_large_dark</item>
<item name="attachment_document_extension_text_color">#222</item>
<item name="home_gradient_start">#00000000</item>
<item name="home_gradient_end">#FF000000</item>
<item name="message_received_background_color">#222325</item>
<item name="message_sent_background_color">#3F4146</item>
<item name="menu_accept_icon">@drawable/ic_baseline_done_24</item>
<item name="menu_trash_icon">@drawable/ic_baseline_delete_24</item>
<item name="menu_block_icon">@drawable/ic_baseline_block_24</item>
<item name="menu_forward_icon">@drawable/ic_baseline_forward_24</item>
<item name="menu_save_icon">@drawable/ic_baseline_save_24</item>
<item name="menu_photo_library_icon">@drawable/ic_baseline_photo_library_24</item>
<item name="menu_delete_icon">@drawable/ic_baseline_delete_24</item>
<item name="menu_copy_icon">@drawable/ic_baseline_file_copy_24</item>
<item name="menu_reply_icon">@drawable/ic_baseline_reply_24</item>
<item name="menu_selectall_icon">@drawable/ic_baseline_select_all_24</item>
<item name="menu_split_icon">@drawable/ic_baseline_call_split_24</item>
<item name="menu_popup_expand">@drawable/ic_baseline_launch_24</item>
<item name="menu_info_icon">@drawable/ic_baseline_info_24</item>
<item name="conversation_emoji_toggle">@drawable/ic_emoji_filled_keyboard_24</item>
<item name="conversation_sticker_toggle">@drawable/ic_sticker_filled_keyboard_24</item>
<item name="conversation_keyboard_toggle">@drawable/ic_baseline_keyboard_24</item>
<item name="conversation_input_background">@drawable/compose_background_dark</item>
<item name="quick_camera_icon">@drawable/ic_baseline_photo_camera_24</item>
<item name="quick_mic_icon">@drawable/ic_baseline_mic_24</item>
<item name="conversation_item_audio_seek_bar_color_incoming">@color/accent</item>
<item name="conversation_item_audio_seek_bar_color_outgoing">@color/accent</item>
<item name="conversation_item_audio_seek_bar_background_color">@color/text</item>
</style>
<!-- This should be the default theme for the application. -->
<style name="Theme.Session.DayNight" parent="Base.Theme.Session">
<!-- leave empty to allow overriding -->
</style>
<style name="Theme.Session.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="Theme.Session.DayNight.FlatActionBar">
<item name="actionBarStyle">@style/Widget.Session.ActionBar.Flat</item>
</style>
<!--
This is a temporary theme that is used by any activity
which doesn't have support for light theme
(like some old Signal screens or third-party libs with white only icons)
-->
<!-- TODO Refactor this to use color resources -->
<style name="Base.Theme.Session.ForceDark" parent="Theme.Session.DayNight">
<item name="colorPrimary">#171717</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:textColorSecondary">#DFFFFFFF</item>
<item name="android:textColorTertiary">#90FFFFFF</item>
<item name="colorControlNormal">?android:textColorPrimary</item>
<item name="android:colorBackground">#121212</item>
<item name="android:windowBackground">?android:colorBackground</item>
<item name="android:navigationBarColor">?android:colorBackground</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<item name="actionBarStyle">@style/Widget.AppCompat.ActionBar</item>
<item name="conversation_emoji_toggle">@drawable/ic_emoji_filled_keyboard_24</item>
<item name="conversation_sticker_toggle">@drawable/ic_sticker_filled_keyboard_24</item>
<item name="conversation_keyboard_toggle">@drawable/ic_baseline_keyboard_24</item>
<item name="conversation_input_background">@drawable/compose_background_dark</item>
</style>
<style name="Theme.Session.ForceDark" parent="Base.Theme.Session.ForceDark">
<!-- leave empty to allow overriding -->
</style>
<style name="Theme.Session.ForceDark.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="Theme.Session.BottomSheet" parent="@style/Theme.AppCompat.DayNight.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowAnimationStyle">@style/Animation.MaterialComponents.BottomSheetDialog</item>
<item name="bottomSheetStyle">@style/Widget.Session.BottomSheetDialog</item>
</style>
<!-- Session -->
<!-- Original Signal dark theme -->
<style name="Base.Theme.TextSecure" parent="@style/Theme.Session.DayNight">
<item name="windowActionModeOverlay">true</item>
<item name="colorPrimary">@color/action_bar_background</item>
<item name="colorPrimaryDark">@color/action_bar_background</item>
<item name="media_overview_toolbar_background">@color/transparent</item>
<item name="media_overview_header_foreground">@color/text</item>
<item name="theme_type">dark</item>
<item name="android:navigationBarColor">@color/compose_view_background</item>
<item name="attachment_document_icon_small">@drawable/ic_document_small_dark</item>
<item name="attachment_document_icon_large">@drawable/ic_document_large_dark</item>
<item name="conversation_list_item_background">@drawable/conversation_list_item_background_dark</item>
<item name="conversation_list_item_contact_color">#ffdddddd</item>
<item name="conversation_list_item_subject_color">#ffdddddd</item>
<item name="conversation_list_item_delivery_icon_color">@color/core_grey_25</item>
<item name="conversation_list_item_date_color">#ffdddddd</item>
<item name="conversation_list_item_unread_color">@color/core_white</item>
<item name="conversation_list_item_unread_background">@drawable/unread_count_background_dark</item>
<item name="conversation_list_item_divider">@drawable/conversation_list_divider_shape_dark</item>
<item name="conversation_list_toolbar_background">@color/action_bar_background</item>
<item name="conversation_list_typing_tint">@color/core_white</item>
<item name="conversation_group_member_name">#99ffffff</item>
<item name="conversation_item_bubble_background">?message_sent_background_color</item>
<item name="conversation_item_sent_text_primary_color">@color/core_grey_05</item>
<item name="conversation_item_sent_text_secondary_color">@color/core_grey_25</item>
<item name="conversation_item_sent_icon_color">@color/core_grey_25</item>
<item name="conversation_item_sent_text_indicator_tab_color">#99ffffff</item>
<item name="conversation_item_received_text_primary_color">@color/text</item>
<item name="conversation_item_received_text_secondary_color">@color/text</item>
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape_dark</item>
<item name="conversation_item_sticky_date_background">@drawable/sticky_date_header_background_dark</item>
<item name="conversation_item_sticky_date_text_color">@color/core_grey_45</item>
<item name="conversation_item_image_outline_color">@color/transparent_white_30</item>
<item name="verification_background">@color/core_grey_95</item>
<item name="dialog_info_icon">@drawable/ic_info_outline_dark</item>
<item name="dialog_alert_icon">@drawable/ic_warning_dark</item>
<item name="device_link_item_card_background">@color/device_link_item_background_dark</item>
<item name="fab_color">@color/textsecure_primary_dark</item>
<item name="lower_right_divet">@drawable/divet_lower_right_light</item>
<item name="conversation_background">@color/loki_darkest_gray</item>
<item name="conversation_editor_background">#22ffffff</item>
<item name="conversation_editor_text_color">#ffeeeeee</item>
<item name="conversation_input_inline_attach_icon_tint">@color/core_grey_05</item>
<item name="conversation_transport_sms_indicator">@drawable/ic_arrow_up_circle_24</item>
<item name="conversation_transport_push_indicator">@drawable/ic_arrow_up_circle_24</item>
<item name="conversation_transport_popup_background">@color/black</item>
<item name="conversation_attach_camera">@drawable/ic_photo_camera_dark</item>
<item name="conversation_attach_image">@drawable/ic_image_dark</item>
<item name="conversation_attach_video">@drawable/ic_movie_creation_dark</item>
<item name="conversation_attach_sound">@drawable/ic_volume_up_dark</item>
<item name="conversation_attach_contact_info">@drawable/ic_account_box_dark</item>
<item name="conversation_attach">@drawable/ic_attach_white_24dp</item>
<item name="conversation_number_picker_text_color_normal">@color/gray13</item>
<item name="conversation_number_picker_text_color_selected">@color/white</item>
<item name="conversation_sticker_footer_text_color">@color/core_grey_25</item>
<item name="conversation_sticker_footer_icon_color">@color/core_grey_25</item>
<item name="conversation_sticker_author_color">@color/core_grey_05</item>
<item name="emoji_tab_strip_background">@color/compose_view_background</item>
<item name="emoji_tab_indicator">@color/accent</item>
<item name="emoji_tab_underline">@color/gray78</item>
<item name="emoji_tab_seperator">@color/gray70</item>
<item name="emoji_drawer_background">@color/compose_text_view_background</item>
<item name="emoji_text_color">@color/white</item>
<item name="emoji_category_recent">@drawable/ic_recent_dark_20</item>
<item name="emoji_category_people">@drawable/ic_emoji_people_dark_20</item>
<item name="emoji_category_nature">@drawable/ic_emoji_animal_dark_20</item>
<item name="emoji_category_foods">@drawable/ic_emoji_food_dark_20</item>
<item name="emoji_category_activity">@drawable/ic_emoji_activity_dark_20</item>
<item name="emoji_category_places">@drawable/ic_emoji_travel_dark_20</item>
<item name="emoji_category_objects">@drawable/ic_emoji_object_dark_20</item>
<item name="emoji_category_symbol">@drawable/ic_emoji_symbol_dark_20</item>
<item name="emoji_category_flags">@drawable/ic_emoji_flag_dark_20</item>
<item name="emoji_category_emoticons">@drawable/ic_emoji_emoticon_dark_20</item>
<item name="emoji_variation_selector_background">@drawable/emoji_variation_selector_background_dark</item>
<item name="linkpreview_background_color">@color/black</item>
<item name="linkpreview_primary_text_color">@color/text</item>
<item name="linkpreview_secondary_text_color">@color/text</item>
<item name="linkpreview_divider_color">@color/transparent</item>
<item name="conversation_icon_attach_audio">@drawable/ic_audio_dark</item>
<item name="conversation_icon_attach_video">@drawable/ic_video_dark</item>
<item name="sticker_management_icon">@drawable/sticker_button_dark</item>
<item name="sticker_management_divider_color">@color/core_grey_75</item>
<item name="sticker_management_empty_background_color">@color/core_grey_85</item>
<item name="sticker_management_action_button_color">@color/core_grey_25</item>
<item name="sticker_popup_background">@color/transparent_black_90</item>
<item name="sticker_preview_toolbar_background">@color/core_grey_95</item>
<item name="sticker_preview_status_bar_color">@color/core_grey_85</item>
<item name="sticker_view_missing_background">@drawable/sticker_missing_background_dark</item>
<item name="tooltip_default_color">@color/core_grey_75</item>
<item name="pref_icon_tint">#FFFFFF</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.Fix</item>
<item name="shared_contact_details_header_background">@color/grey_800</item>
<item name="shared_contact_details_titlebar">@color/grey_900</item>
<item name="shared_contact_item_button_color">@color/core_grey_85</item>
</style>
<style name="Theme.TextSecure.DayNight" parent="Base.Theme.TextSecure">
<!-- leave empty to allow overriding -->
</style>
<style name="Theme.TextSecure.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="Theme.TextSecure.Dialog.Rationale" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<item name="android:windowBackground">@drawable/default_dialog_background</item>
</style>
<style name="Theme.TextSecure.Dialog.MediaSendProgress" parent="@android:style/Theme.Dialog">
<item name="android:background">@drawable/default_dialog_background</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>