mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 04:25:18 +00:00
Merge branch 'dev' of https://github.com/loki-project/session-android into external-file-access-fix
This commit is contained in:
commit
5acf505994
69
build.gradle
69
build.gradle
@ -1,16 +1,15 @@
|
|||||||
import java.security.MessageDigest
|
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = "1.3.31"
|
ext.kotlin_version = "1.4.0"
|
||||||
ext.kovenant_version = "3.3.0"
|
ext.kovenant_version = "3.3.0"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.android.tools.build:gradle:3.4.1"
|
classpath "com.android.tools.build:gradle:4.0.1"
|
||||||
classpath files('libs/gradle-witness.jar')
|
classpath files('libs/gradle-witness.jar')
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath "com.google.gms:google-services:4.3.3"
|
classpath "com.google.gms:google-services:4.3.3"
|
||||||
@ -18,8 +17,8 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
apply plugin: 'witness'
|
apply plugin: 'witness'
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
@ -73,14 +72,15 @@ configurations.all {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||||
implementation 'com.google.android.material:material:1.2.0'
|
implementation 'com.google.android.material:material:1.2.1'
|
||||||
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
|
||||||
implementation 'androidx.cardview:cardview:1.0.0'
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
|
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
|
||||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||||
implementation 'androidx.exifinterface:exifinterface:1.2.0'
|
implementation 'androidx.exifinterface:exifinterface:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||||
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
|
||||||
|
|
||||||
@ -89,7 +89,6 @@ dependencies {
|
|||||||
exclude group: 'com.google.firebase', module: 'firebase-analytics'
|
exclude group: 'com.google.firebase', module: 'firebase-analytics'
|
||||||
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1'
|
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
|
implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
|
||||||
implementation 'org.conscrypt:conscrypt-android:2.0.0'
|
implementation 'org.conscrypt:conscrypt-android:2.0.0'
|
||||||
@ -141,28 +140,6 @@ dependencies {
|
|||||||
exclude group: 'com.fasterxml.jackson.core'
|
exclude group: 'com.fasterxml.jackson.core'
|
||||||
exclude group: 'org.freemarker'
|
exclude group: 'org.freemarker'
|
||||||
}
|
}
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
|
||||||
testImplementation 'org.assertj:assertj-core:3.11.1'
|
|
||||||
testImplementation 'org.mockito:mockito-core:1.9.5'
|
|
||||||
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
|
|
||||||
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
|
|
||||||
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
|
|
||||||
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
|
|
||||||
|
|
||||||
testImplementation 'androidx.test:core:1.3.0-rc03'
|
|
||||||
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
|
|
||||||
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
|
|
||||||
androidTestImplementation ('org.assertj:assertj-core:1.7.1') {
|
|
||||||
exclude group: 'org.hamcrest', module: 'hamcrest-core'
|
|
||||||
}
|
|
||||||
androidTestImplementation ('com.squareup.assertj:assertj-android:1.1.1') {
|
|
||||||
exclude group: 'org.hamcrest', module: 'hamcrest-core'
|
|
||||||
exclude group: 'com.android.support', module: 'support-annotations'
|
|
||||||
}
|
|
||||||
testImplementation 'org.robolectric:robolectric:4.2'
|
|
||||||
testImplementation 'org.robolectric:shadows-multidex:4.2'
|
|
||||||
|
|
||||||
// Loki
|
// Loki
|
||||||
// Local:
|
// Local:
|
||||||
implementation "org.whispersystems:signal-service-android:2.13.2" // Run ./gradlew install from session-android-service to install
|
implementation "org.whispersystems:signal-service-android:2.13.2" // Run ./gradlew install from session-android-service to install
|
||||||
@ -180,10 +157,32 @@ dependencies {
|
|||||||
implementation "com.github.tbruyelle:rxpermissions:0.10.2"
|
implementation "com.github.tbruyelle:rxpermissions:0.10.2"
|
||||||
implementation "com.github.ybq:Android-SpinKit:1.4.0"
|
implementation "com.github.ybq:Android-SpinKit:1.4.0"
|
||||||
implementation "com.opencsv:opencsv:4.6"
|
implementation "com.opencsv:opencsv:4.6"
|
||||||
|
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
testImplementation 'org.assertj:assertj-core:3.11.1'
|
||||||
|
testImplementation 'org.mockito:mockito-core:1.9.5'
|
||||||
|
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
|
||||||
|
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
|
||||||
|
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
|
||||||
|
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
|
||||||
|
testImplementation 'androidx.test:core:1.3.0'
|
||||||
|
androidTestImplementation 'androidx.multidex:multidex:2.0.1'
|
||||||
|
androidTestImplementation 'androidx.multidex:multidex-instrumentation:2.0.0'
|
||||||
|
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
|
||||||
|
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
|
||||||
|
androidTestImplementation ('org.assertj:assertj-core:1.7.1') {
|
||||||
|
exclude group: 'org.hamcrest', module: 'hamcrest-core'
|
||||||
|
}
|
||||||
|
androidTestImplementation ('com.squareup.assertj:assertj-android:1.1.1') {
|
||||||
|
exclude group: 'org.hamcrest', module: 'hamcrest-core'
|
||||||
|
exclude group: 'com.android.support', module: 'support-annotations'
|
||||||
|
}
|
||||||
|
testImplementation 'org.robolectric:robolectric:4.2'
|
||||||
|
testImplementation 'org.robolectric:shadows-multidex:4.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
def canonicalVersionCode = 84
|
def canonicalVersionCode = 93
|
||||||
def canonicalVersionName = "1.5.0"
|
def canonicalVersionName = "1.5.2"
|
||||||
|
|
||||||
def postFixSize = 10
|
def postFixSize = 10
|
||||||
def abiPostFix = ['armeabi-v7a' : 1,
|
def abiPostFix = ['armeabi-v7a' : 1,
|
||||||
@ -208,9 +207,10 @@ android {
|
|||||||
|
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
|
multiDexEnabled true // Even though we're running API 21+, this is still needed for release builds
|
||||||
|
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
project.ext.set("archivesBaseName", "Signal")
|
project.ext.set("archivesBaseName", "session")
|
||||||
|
|
||||||
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
|
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
|
||||||
buildConfigField "String", "SIGNAL_URL", "\"\""
|
buildConfigField "String", "SIGNAL_URL", "\"\""
|
||||||
@ -349,6 +349,7 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
def assembleWebsiteDescriptor = { variant, file ->
|
def assembleWebsiteDescriptor = { variant, file ->
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-256")
|
MessageDigest md = MessageDigest.getInstance("SHA-256")
|
||||||
@ -372,7 +373,7 @@ def assembleWebsiteDescriptor = { variant, file ->
|
|||||||
descriptorFile.write(descriptor)
|
descriptorFile.write(descriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
def signProductionRelease = { variant ->
|
def signProductionRelease = { variant ->
|
||||||
variant.outputs.collect { output ->
|
variant.outputs.collect { output ->
|
||||||
String apkName = output.outputFile.name
|
String apkName = output.outputFile.name
|
||||||
|
@ -5,5 +5,5 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.android.tools.build:apksig:3.3.2'
|
implementation 'com.android.tools.build:apksig:4.0.1'
|
||||||
}
|
}
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/Widget.Session.Button.Common.ProminentFilled"
|
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
||||||
android:id="@+id/joinPublicChatButton"
|
android:id="@+id/joinPublicChatButton"
|
||||||
android:layout_width="196dp"
|
android:layout_width="196dp"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
@ -90,7 +90,7 @@
|
|||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/Widget.Session.Button.Common.ProminentFilled"
|
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
||||||
android:id="@+id/createPrivateChatButton"
|
android:id="@+id/createPrivateChatButton"
|
||||||
android:layout_width="196dp"
|
android:layout_width="196dp"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
android:textSize="@dimen/medium_font_size" />
|
android:textSize="@dimen/medium_font_size" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
style="@style/SessionIDTextView"
|
||||||
android:id="@+id/seedTextView"
|
android:id="@+id/seedTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/large_spacing"
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:padding="@dimen/small_spacing"
|
||||||
android:text="habitat kiwi amply iceberg dog nerves spiderman soft match partial awakened maximum degrees"
|
android:text="habitat kiwi amply iceberg dog nerves spiderman soft match partial awakened maximum degrees"
|
||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:textSize="@dimen/small_font_size"
|
android:textSize="@dimen/small_font_size"
|
||||||
@ -70,9 +72,9 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/large_spacing"
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
android:text="@string/dialog_seed_disclaimer"
|
android:text="@string/dialog_seed_disclaimer"
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:textSize="@dimen/very_small_font_size"
|
android:alpha="0.6"
|
||||||
|
android:textSize="10sp"
|
||||||
android:textAlignment="center" />
|
android:textAlignment="center" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -90,53 +90,53 @@
|
|||||||
android:paddingStart="10dp"
|
android:paddingStart="10dp"
|
||||||
android:paddingEnd="40dp"/>
|
android:paddingEnd="40dp"/>
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.AnimatingToggle
|
<!-- <org.thoughtcrime.securesms.components.AnimatingToggle-->
|
||||||
android:id="@+id/button_toggle"
|
<!-- android:id="@+id/button_toggle"-->
|
||||||
android:layout_width="wrap_content"
|
<!-- android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!-- android:layout_height="wrap_content"-->
|
||||||
android:layout_alignRight="@+id/passphrase_edit"
|
<!-- android:layout_alignRight="@+id/passphrase_edit"-->
|
||||||
android:layout_centerVertical="true"
|
<!-- android:layout_centerVertical="true"-->
|
||||||
android:layout_gravity="center"
|
<!-- android:layout_gravity="center"-->
|
||||||
android:gravity="center">
|
<!-- android:gravity="center">-->
|
||||||
|
|
||||||
<ImageButton android:id="@+id/passphrase_visibility"
|
<!-- <ImageButton android:id="@+id/passphrase_visibility"-->
|
||||||
android:src="?ic_visibility"
|
<!-- android:src="?ic_visibility"-->
|
||||||
android:background="@drawable/touch_highlight_background"
|
<!-- android:background="@drawable/touch_highlight_background"-->
|
||||||
android:layout_width="wrap_content"
|
<!-- android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!-- android:layout_height="wrap_content"-->
|
||||||
android:paddingStart="8dp"
|
<!-- android:paddingStart="8dp"-->
|
||||||
android:paddingEnd="8dp"
|
<!-- android:paddingEnd="8dp"-->
|
||||||
android:paddingTop="3dp"
|
<!-- android:paddingTop="3dp"-->
|
||||||
android:paddingBottom="3dp"
|
<!-- android:paddingBottom="3dp"-->
|
||||||
android:layout_centerVertical="true" />
|
<!-- android:layout_centerVertical="true" />-->
|
||||||
|
|
||||||
<ImageButton android:id="@+id/passphrase_visibility_off"
|
<!-- <ImageButton android:id="@+id/passphrase_visibility_off"-->
|
||||||
android:src="?ic_visibility_off"
|
<!-- android:src="?ic_visibility_off"-->
|
||||||
android:background="@drawable/touch_highlight_background"
|
<!-- android:background="@drawable/touch_highlight_background"-->
|
||||||
android:layout_width="wrap_content"
|
<!-- android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!-- android:layout_height="wrap_content"-->
|
||||||
android:paddingStart="8dp"
|
<!-- android:paddingStart="8dp"-->
|
||||||
android:paddingEnd="8dp"
|
<!-- android:paddingEnd="8dp"-->
|
||||||
android:paddingTop="3dp"
|
<!-- android:paddingTop="3dp"-->
|
||||||
android:paddingBottom="3dp"
|
<!-- android:paddingBottom="3dp"-->
|
||||||
android:layout_centerVertical="true" />
|
<!-- android:layout_centerVertical="true" />-->
|
||||||
|
|
||||||
</org.thoughtcrime.securesms.components.AnimatingToggle>
|
<!-- </org.thoughtcrime.securesms.components.AnimatingToggle>-->
|
||||||
|
|
||||||
<ImageButton android:id="@+id/ok_button"
|
<!-- <ImageButton android:id="@+id/ok_button"-->
|
||||||
android:src="?ic_arrow_forward"
|
<!-- android:src="?ic_arrow_forward"-->
|
||||||
android:contentDescription="@string/PassphrasePromptActivity_ok_button_content_description"
|
<!-- android:contentDescription="@string/PassphrasePromptActivity_ok_button_content_description"-->
|
||||||
android:background="@null"
|
<!-- android:background="@null"-->
|
||||||
android:text="@string/prompt_passphrase_activity__unlock"
|
<!-- android:text="@string/prompt_passphrase_activity__unlock"-->
|
||||||
android:layout_width="wrap_content"
|
<!-- android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!-- android:layout_height="wrap_content"-->
|
||||||
android:layout_alignParentEnd="true"
|
<!-- android:layout_alignParentEnd="true"-->
|
||||||
android:layout_centerVertical="true"
|
<!-- android:layout_centerVertical="true"-->
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
<!-- android:textAppearance="?android:attr/textAppearanceMedium"-->
|
||||||
android:paddingStart="5dp"
|
<!-- android:paddingStart="5dp"-->
|
||||||
android:paddingTop="5dp"
|
<!-- android:paddingTop="5dp"-->
|
||||||
android:paddingEnd="10dp"
|
<!-- android:paddingEnd="10dp"-->
|
||||||
android:paddingBottom="5dp"/>
|
<!-- android:paddingBottom="5dp"/>-->
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<dimen name="small_font_size">13sp</dimen>
|
<dimen name="small_font_size">13sp</dimen>
|
||||||
<dimen name="medium_font_size">15sp</dimen>
|
<dimen name="medium_font_size">15sp</dimen>
|
||||||
<dimen name="large_font_size">20sp</dimen>
|
<dimen name="large_font_size">20sp</dimen>
|
||||||
<dimen name="very_large_font_size">25sp</dimen>
|
<dimen name="very_large_font_size">24sp</dimen>
|
||||||
<dimen name="massive_font_size">50sp</dimen>
|
<dimen name="massive_font_size">50sp</dimen>
|
||||||
|
|
||||||
<!-- Session -->
|
<!-- Session -->
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<dimen name="small_font_size">15sp</dimen>
|
<dimen name="small_font_size">15sp</dimen>
|
||||||
<dimen name="medium_font_size">17sp</dimen>
|
<dimen name="medium_font_size">17sp</dimen>
|
||||||
<dimen name="large_font_size">22sp</dimen>
|
<dimen name="large_font_size">22sp</dimen>
|
||||||
<dimen name="very_large_font_size">27sp</dimen>
|
<dimen name="very_large_font_size">26sp</dimen>
|
||||||
<dimen name="massive_font_size">50sp</dimen>
|
<dimen name="massive_font_size">50sp</dimen>
|
||||||
|
|
||||||
<!-- Element Sizes -->
|
<!-- Element Sizes -->
|
||||||
|
@ -1851,7 +1851,7 @@
|
|||||||
|
|
||||||
<string name="activity_select_contacts_title">Select Contacts</string>
|
<string name="activity_select_contacts_title">Select Contacts</string>
|
||||||
|
|
||||||
<string name="dialog_seed_disclaimer">*Please note that it is not possible to use the same Session ID on multiple devices simultaneously</string>
|
<string name="dialog_seed_disclaimer">It is not possible to use the same Session ID on multiple devices simultaneously</string>
|
||||||
|
|
||||||
<string name="view_reset_secure_session_done_message">Secure session reset done</string>
|
<string name="view_reset_secure_session_done_message">Secure session reset done</string>
|
||||||
|
|
||||||
|
@ -16,18 +16,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms;
|
package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
import android.app.Application;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.multidex.MultiDexApplication;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
|
||||||
|
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
import com.google.firebase.iid.FirebaseInstanceId;
|
||||||
|
|
||||||
@ -116,10 +115,10 @@ import org.whispersystems.signalservice.loki.protocol.closedgroups.SharedSenderK
|
|||||||
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager;
|
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager;
|
||||||
import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol;
|
import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol;
|
||||||
import org.whispersystems.signalservice.loki.protocol.meta.TTLUtilities;
|
import org.whispersystems.signalservice.loki.protocol.meta.TTLUtilities;
|
||||||
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocol;
|
|
||||||
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocolDelegate;
|
|
||||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.DeviceLink;
|
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.DeviceLink;
|
||||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol;
|
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol;
|
||||||
|
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocol;
|
||||||
|
import org.whispersystems.signalservice.loki.protocol.sessionmanagement.SessionManagementProtocolDelegate;
|
||||||
import org.whispersystems.signalservice.loki.protocol.shelved.syncmessages.SyncMessagesProtocol;
|
import org.whispersystems.signalservice.loki.protocol.shelved.syncmessages.SyncMessagesProtocol;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -145,10 +144,11 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant;
|
|||||||
*
|
*
|
||||||
* @author Moxie Marlinspike
|
* @author Moxie Marlinspike
|
||||||
*/
|
*/
|
||||||
public class ApplicationContext extends Application implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate,
|
public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate,
|
||||||
SessionManagementProtocolDelegate, SharedSenderKeysImplementationDelegate {
|
SessionManagementProtocolDelegate, SharedSenderKeysImplementationDelegate {
|
||||||
|
|
||||||
private static final String TAG = ApplicationContext.class.getSimpleName();
|
private static final String TAG = ApplicationContext.class.getSimpleName();
|
||||||
|
private final static int OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||||
|
|
||||||
private ExpiringMessageManager expiringMessageManager;
|
private ExpiringMessageManager expiringMessageManager;
|
||||||
private TypingStatusRepository typingStatusRepository;
|
private TypingStatusRepository typingStatusRepository;
|
||||||
|
@ -76,8 +76,8 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
|||||||
private Button lockScreenButton;
|
private Button lockScreenButton;
|
||||||
|
|
||||||
private EditText passphraseText;
|
private EditText passphraseText;
|
||||||
private ImageButton showButton;
|
// private ImageButton showButton;
|
||||||
private ImageButton hideButton;
|
// private ImageButton hideButton;
|
||||||
private AnimatingToggle visibilityToggle;
|
private AnimatingToggle visibilityToggle;
|
||||||
|
|
||||||
private FingerprintManagerCompat fingerprintManager;
|
private FingerprintManagerCompat fingerprintManager;
|
||||||
@ -203,11 +203,11 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
|||||||
|
|
||||||
private void initializeResources() {
|
private void initializeResources() {
|
||||||
|
|
||||||
ImageButton okButton = findViewById(R.id.ok_button);
|
// ImageButton okButton = findViewById(R.id.ok_button);
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
|
||||||
showButton = findViewById(R.id.passphrase_visibility);
|
// showButton = findViewById(R.id.passphrase_visibility);
|
||||||
hideButton = findViewById(R.id.passphrase_visibility_off);
|
// hideButton = findViewById(R.id.passphrase_visibility_off);
|
||||||
visibilityToggle = findViewById(R.id.button_toggle);
|
visibilityToggle = findViewById(R.id.button_toggle);
|
||||||
passphraseText = findViewById(R.id.passphrase_edit);
|
passphraseText = findViewById(R.id.passphrase_edit);
|
||||||
passphraseAuthContainer = findViewById(R.id.password_auth_container);
|
passphraseAuthContainer = findViewById(R.id.password_auth_container);
|
||||||
@ -217,17 +217,17 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
|||||||
fingerprintCancellationSignal = new CancellationSignal();
|
fingerprintCancellationSignal = new CancellationSignal();
|
||||||
fingerprintListener = new FingerprintListener();
|
fingerprintListener = new FingerprintListener();
|
||||||
|
|
||||||
setSupportActionBar(toolbar);
|
// setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setTitle("");
|
// getSupportActionBar().setTitle("");
|
||||||
|
|
||||||
SpannableString hint = new SpannableString(" " + getString(R.string.PassphrasePromptActivity_enter_passphrase));
|
SpannableString hint = new SpannableString(" " + getString(R.string.PassphrasePromptActivity_enter_passphrase));
|
||||||
hint.setSpan(new RelativeSizeSpan(0.9f), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
hint.setSpan(new RelativeSizeSpan(0.9f), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
hint.setSpan(new TypefaceSpan("sans-serif"), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
hint.setSpan(new TypefaceSpan("sans-serif"), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
|
|
||||||
passphraseText.setHint(hint);
|
passphraseText.setHint(hint);
|
||||||
okButton.setOnClickListener(new OkButtonClickListener());
|
// okButton.setOnClickListener(new OkButtonClickListener());
|
||||||
showButton.setOnClickListener(new ShowButtonOnClickListener());
|
// showButton.setOnClickListener(new ShowButtonOnClickListener());
|
||||||
hideButton.setOnClickListener(new HideButtonOnClickListener());
|
// hideButton.setOnClickListener(new HideButtonOnClickListener());
|
||||||
passphraseText.setOnEditorActionListener(new PassphraseActionListener());
|
passphraseText.setOnEditorActionListener(new PassphraseActionListener());
|
||||||
passphraseText.setImeActionLabel(getString(R.string.prompt_passphrase_activity__unlock),
|
passphraseText.setImeActionLabel(getString(R.string.prompt_passphrase_activity__unlock),
|
||||||
EditorInfo.IME_ACTION_DONE);
|
EditorInfo.IME_ACTION_DONE);
|
||||||
@ -316,7 +316,7 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
|||||||
private class ShowButtonOnClickListener implements OnClickListener {
|
private class ShowButtonOnClickListener implements OnClickListener {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
visibilityToggle.display(hideButton);
|
// visibilityToggle.display(hideButton);
|
||||||
setPassphraseVisibility(true);
|
setPassphraseVisibility(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +324,7 @@ public class PassphrasePromptActivity extends PassphraseActivity {
|
|||||||
private class HideButtonOnClickListener implements OnClickListener {
|
private class HideButtonOnClickListener implements OnClickListener {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
visibilityToggle.display(showButton);
|
// visibilityToggle.display(showButton);
|
||||||
setPassphraseVisibility(false);
|
setPassphraseVisibility(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,6 @@ import android.content.res.TypedArray;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -17,11 +14,16 @@ import android.widget.FrameLayout;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities;
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
@ -209,7 +211,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
|||||||
authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you) : quoteeDisplayName);
|
authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you) : quoteeDisplayName);
|
||||||
|
|
||||||
// We use the raw color resource because Android 4.x was struggling with tints here
|
// We use the raw color resource because Android 4.x was struggling with tints here
|
||||||
quoteBarView.setImageResource(R.color.accent);
|
int colorID = UiModeUtilities.isDayUiMode(getContext()) ? R.color.black : R.color.accent;
|
||||||
|
quoteBarView.setImageResource(colorID);
|
||||||
mainView.setBackgroundColor(ThemeUtil.getThemedColor(getContext(),
|
mainView.setBackgroundColor(ThemeUtil.getThemedColor(getContext(),
|
||||||
outgoing ? R.attr.message_received_background_color : R.attr.message_sent_background_color));
|
outgoing ? R.attr.message_received_background_color : R.attr.message_sent_background_color));
|
||||||
}
|
}
|
||||||
|
@ -3103,15 +3103,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
private void updateSubtitleTextView() {
|
private void updateSubtitleTextView() {
|
||||||
muteIndicatorImageView.setVisibility(View.GONE);
|
muteIndicatorImageView.setVisibility(View.GONE);
|
||||||
subtitleTextView.setVisibility(View.VISIBLE);
|
subtitleTextView.setVisibility(View.VISIBLE);
|
||||||
if (messageStatus != null) {
|
if (recipient.isMuted()) {
|
||||||
switch (messageStatus) {
|
|
||||||
case "calculatingPoW": subtitleTextView.setText("Encrypting message"); break;
|
|
||||||
case "contactingNetwork": subtitleTextView.setText("Tracing a path"); break;
|
|
||||||
case "sendingMessage": subtitleTextView.setText("Sending message"); break;
|
|
||||||
case "messageSent": subtitleTextView.setText("Message sent securely"); break;
|
|
||||||
case "messageFailed": subtitleTextView.setText("Message failed to send"); break;
|
|
||||||
}
|
|
||||||
} else if (recipient.isMuted()) {
|
|
||||||
muteIndicatorImageView.setVisibility(View.VISIBLE);
|
muteIndicatorImageView.setVisibility(View.VISIBLE);
|
||||||
subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()));
|
subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()));
|
||||||
} else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) {
|
} else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) {
|
||||||
@ -3125,10 +3117,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
} else {
|
} else {
|
||||||
subtitleTextView.setVisibility(View.GONE);
|
subtitleTextView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
} else if (PublicKeyValidation.isValid(recipient.getAddress().toString())) {
|
|
||||||
String ourMasterHexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(this);
|
|
||||||
String hexEncodedPublicKey = (recipient.isLocalNumber() && ourMasterHexEncodedPublicKey != null) ? ourMasterHexEncodedPublicKey : recipient.getAddress().toPhoneString();
|
|
||||||
subtitleTextView.setText(hexEncodedPublicKey);
|
|
||||||
} else {
|
} else {
|
||||||
subtitleTextView.setVisibility(View.GONE);
|
subtitleTextView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
seedReminderView.visibility = View.GONE
|
seedReminderView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiple device removal notification
|
// Multi device removal sheet
|
||||||
if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) {
|
if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) {
|
||||||
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
|
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
|
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
|
||||||
@ -223,7 +223,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Light theme introduction
|
// Light theme introduction sheet
|
||||||
if (!TextSecurePreferences.hasSeenLightThemeIntroSheet(this) &&
|
if (!TextSecurePreferences.hasSeenLightThemeIntroSheet(this) &&
|
||||||
UiModeUtilities.isDayUiMode(this)) {
|
UiModeUtilities.isDayUiMode(this)) {
|
||||||
TextSecurePreferences.setHasSeenLightThemeIntroSheet(this)
|
TextSecurePreferences.setHasSeenLightThemeIntroSheet(this)
|
||||||
|
@ -33,8 +33,14 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
|
|||||||
return TextSecurePreferences.getProfileName(context)
|
return TextSecurePreferences.getProfileName(context)
|
||||||
} else {
|
} else {
|
||||||
val database = databaseHelper.readableDatabase
|
val database = databaseHelper.readableDatabase
|
||||||
return database.get(displayNameTable, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor ->
|
val result = database.get(displayNameTable, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor ->
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(displayName))
|
cursor.getString(cursor.getColumnIndexOrThrow(displayName))
|
||||||
|
} ?: return null
|
||||||
|
val suffix = " (...${publicKey.substring(publicKey.count() - 8)})"
|
||||||
|
if (result.endsWith(suffix)) {
|
||||||
|
return result.substring(0..(result.count() - suffix.count()))
|
||||||
|
} else {
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,18 @@ import android.content.Context
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
import kotlinx.android.synthetic.main.dialog_seed.view.*
|
import kotlinx.android.synthetic.main.dialog_seed.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
|
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
|
||||||
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class SeedDialog : DialogFragment() {
|
class SeedDialog : DialogFragment() {
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
|||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
||||||
import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiDeviceProtocol
|
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
object SessionMetaProtocol {
|
object SessionMetaProtocol {
|
||||||
@ -37,24 +36,16 @@ object SessionMetaProtocol {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun handleProfileUpdateIfNeeded(context: Context, content: SignalServiceContent) {
|
fun handleProfileUpdateIfNeeded(context: Context, content: SignalServiceContent) {
|
||||||
val rawDisplayName = content.senderDisplayName.orNull() ?: return
|
val displayName = content.senderDisplayName.orNull() ?: return
|
||||||
if (rawDisplayName.isBlank()) { return }
|
if (displayName.isBlank()) { return }
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
|
||||||
val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
|
val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
|
||||||
val sender = content.sender.toLowerCase()
|
val sender = content.sender.toLowerCase()
|
||||||
if (userMasterPublicKey == sender) {
|
if (userMasterPublicKey == sender) {
|
||||||
// Update the user's local name if the message came from their master device
|
// Update the user's local name if the message came from their master device
|
||||||
TextSecurePreferences.setProfileName(context, rawDisplayName)
|
TextSecurePreferences.setProfileName(context, displayName)
|
||||||
}
|
}
|
||||||
// Don't overwrite if the message came from a linked device; the device name is
|
|
||||||
// stored as a user name
|
|
||||||
val allUserDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey)
|
|
||||||
if (!allUserDevices.contains(sender)) {
|
|
||||||
val displayName = rawDisplayName + " (..." + sender.substring(sender.length - 8) + ")"
|
|
||||||
DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, displayName)
|
DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, displayName)
|
||||||
} else {
|
|
||||||
DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, rawDisplayName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -53,7 +53,9 @@ object MentionUtilities {
|
|||||||
}
|
}
|
||||||
val result = SpannableString(text)
|
val result = SpannableString(text)
|
||||||
for (mention in mentions) {
|
for (mention in mentions) {
|
||||||
result.setSpan(ForegroundColorSpan(context.resources.getColorWithID(R.color.accent, context.theme)), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
val isLightMode = UiModeUtilities.isDayUiMode(context)
|
||||||
|
val colorID = if (isLightMode && isOutgoingMessage) R.color.black else R.color.accent
|
||||||
|
result.setSpan(ForegroundColorSpan(context.resources.getColorWithID(colorID, context.theme)), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
result.setSpan(StyleSpan(Typeface.BOLD), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
result.setSpan(StyleSpan(Typeface.BOLD), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
Loading…
Reference in New Issue
Block a user