From ebf6014e703fb3f170a1de1c482a7fb030bc8b25 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 6 May 2019 13:20:51 -0700 Subject: [PATCH 001/178] Fix crash when contact has no numbers --- .../java/com/moez/QKSMS/feature/compose/ContactAdapter.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ContactAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ContactAdapter.kt index cdceeda05..524bb783c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ContactAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ContactAdapter.kt @@ -62,8 +62,8 @@ class ContactAdapter @Inject constructor() : QkAdapter() { view.avatar.setContact(contact) view.name.text = contact.name view.name.setVisible(view.name.text.isNotEmpty()) - view.address.text = contact.numbers.first()?.address ?: "" - view.type.text = contact.numbers.first()?.type ?: "" + view.address.text = contact.numbers.firstOrNull()?.address ?: "" + view.type.text = contact.numbers.firstOrNull()?.type ?: "" val adapter = view.addresses.adapter as PhoneNumberAdapter adapter.contact = contact -- GitLab From a86229db524c5cecf8f3f733e472e7e0e15ee661 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Wed, 15 May 2019 22:47:08 -0400 Subject: [PATCH 002/178] #1422 - Handle sms_body extra for incoming intents --- .../com/moez/QKSMS/feature/compose/ComposeActivityModule.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt index 51ea25cdd..7bbe34a6d 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt @@ -66,7 +66,9 @@ class ComposeActivityModule { @Provides @Named("text") fun provideSharedText(activity: ComposeActivity): String { - return activity.intent.extras?.getString(Intent.EXTRA_TEXT) ?: "" + return activity.intent.extras?.getString(Intent.EXTRA_TEXT) + ?: activity.intent.extras?.getString("sms_body") + ?: "" } @Provides -- GitLab From 86102e9d16d50b8bb8d36527256fc1724abdc661 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 4 Mar 2019 23:19:06 -0500 Subject: [PATCH 003/178] #1435 - Update to latest SIA package --- .../manager/ExternalBlockingManagerImpl.kt | 31 ++++++++++--------- .../java/com/moez/QKSMS/common/Navigator.kt | 2 +- .../QKSMS/feature/blocked/BlockedViewModel.kt | 3 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt b/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt index ebf56d1c7..4daf184ff 100644 --- a/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt @@ -73,6 +73,9 @@ class ExternalBlockingManagerImpl @Inject constructor( // intent to request a rating if (prefs.sia.get()) { intent = tryOrNull(false) { + context.packageManager.getApplicationInfo("org.mistergroup.shouldianswer", 0).enabled + Intent("org.mistergroup.shouldianswer.PublicService").setPackage("org.mistergroup.shouldianswer") + } ?: tryOrNull(false) { context.packageManager.getApplicationInfo("org.mistergroup.shouldianswerpersonal", 0).enabled Intent("org.mistergroup.shouldianswerpersonal.PublicService") .setPackage("org.mistergroup.shouldianswerpersonal") @@ -96,20 +99,21 @@ class ExternalBlockingManagerImpl @Inject constructor( serviceMessenger = Messenger(service) isBound = true - val msg = Message() - msg.what = GET_NUMBER_RATING - msg.data = bundleOf(Pair("number", address)) - msg.replyTo = Messenger(IncomingHandler { rating -> - subject.onSuccess(rating == RATING_NEGATIVE) - Timber.v("Should block: ${rating == RATING_NEGATIVE}") - - // We're done, so unbind the service - if (isBound && serviceMessenger != null) { - context.unbindService(this) - } - }) + val message = Message().apply { + what = GET_NUMBER_RATING + data = bundleOf("number" to address) + replyTo = Messenger(IncomingHandler { rating -> + subject.onSuccess(rating == RATING_NEGATIVE) + Timber.v("Should block: ${rating == RATING_NEGATIVE}") + + // We're done, so unbind the service + if (isBound && serviceMessenger != null) { + context.unbindService(this@Binder) + } + }) + } - serviceMessenger?.send(msg) + serviceMessenger?.send(message) } override fun onServiceDisconnected(className: ComponentName) { @@ -119,7 +123,6 @@ class ExternalBlockingManagerImpl @Inject constructor( } private class IncomingHandler(private val callback: (rating: Int) -> Unit) : Handler() { - override fun handleMessage(msg: Message) { when (msg.what) { GET_NUMBER_RATING -> callback(msg.data.getInt("rating")) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt b/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt index ddb0d037a..904fae2f2 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt @@ -184,7 +184,7 @@ class Navigator @Inject constructor( * Launch the Play Store and display the Should I Answer? listing */ fun showSia() { - val url = "https://play.google.com/store/apps/details?id=org.mistergroup.shouldianswerpersonal" + val url = "https://play.google.com/store/apps/details?id=org.mistergroup.shouldianswer" val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) startActivity(intent) } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt index dfd6ad394..d8396c474 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt @@ -53,7 +53,8 @@ class BlockedViewModel @Inject constructor( view.siaClickedIntent .map { - tryOrNull(false) { context.packageManager.getApplicationInfo("org.mistergroup.shouldianswerpersonal", 0).enabled } + tryOrNull(false) { context.packageManager.getApplicationInfo("org.mistergroup.shouldianswer", 0).enabled } + ?: tryOrNull(false) { context.packageManager.getApplicationInfo("org.mistergroup.shouldianswerpersonal", 0).enabled } ?: tryOrNull(false) { context.packageManager.getApplicationInfo("org.mistergroup.muzutozvednout", 0).enabled } ?: false } -- GitLab From d6f6c66b63d918e958f9c85019d1925f58c86a25 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Thu, 6 Jun 2019 19:32:49 -0400 Subject: [PATCH 004/178] Upgrade gradle --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index dd44e1e26..30b41283a 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ buildscript { ext.exoplayer_version = "2.8.1" ext.glide_version = "4.8.0" ext.junit_version = '4.12' - ext.kotlin_version = '1.3.0' + ext.kotlin_version = '1.3.31' ext.lifecycle_version = '2.0.0' ext.material_version = '1.0.0' ext.mockito_version = '2.18.3' @@ -38,7 +38,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' + classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "io.realm:realm-gradle-plugin:$realm_version" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 013022680..6914a81f7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Jan 19 18:02:14 EST 2019 +#Thu Jun 06 19:27:58 EDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip -- GitLab From 1215770898049133dd930f0c22680ccf2e47caed Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Thu, 6 Jun 2019 19:43:59 -0400 Subject: [PATCH 005/178] Respect wantBlock param from SIA --- .../manager/ExternalBlockingManagerImpl.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt b/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt index 4daf184ff..2b8e238de 100644 --- a/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/manager/ExternalBlockingManagerImpl.kt @@ -22,6 +22,7 @@ import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.ServiceConnection +import android.os.Bundle import android.os.Handler import android.os.IBinder import android.os.Message @@ -102,9 +103,10 @@ class ExternalBlockingManagerImpl @Inject constructor( val message = Message().apply { what = GET_NUMBER_RATING data = bundleOf("number" to address) - replyTo = Messenger(IncomingHandler { rating -> - subject.onSuccess(rating == RATING_NEGATIVE) - Timber.v("Should block: ${rating == RATING_NEGATIVE}") + replyTo = Messenger(IncomingHandler { response -> + val shouldBlock = response.rating == RATING_NEGATIVE || response.wantBlock + subject.onSuccess(shouldBlock) + Timber.v("Should block: $shouldBlock") // We're done, so unbind the service if (isBound && serviceMessenger != null) { @@ -122,10 +124,15 @@ class ExternalBlockingManagerImpl @Inject constructor( } } - private class IncomingHandler(private val callback: (rating: Int) -> Unit) : Handler() { + private class IncomingHandler(private val callback: (response: Response) -> Unit) : Handler() { + class Response(bundle: Bundle) { + val rating: Int = bundle.getInt("rating") + val wantBlock = bundle.getInt("wantBlock") == 1 + } + override fun handleMessage(msg: Message) { when (msg.what) { - GET_NUMBER_RATING -> callback(msg.data.getInt("rating")) + GET_NUMBER_RATING -> callback(Response(msg.data)) else -> super.handleMessage(msg) } } -- GitLab From 4c8e1a113843239365e537408abec85c68150c23 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Fri, 7 Jun 2019 01:11:05 -0400 Subject: [PATCH 006/178] #1401 - Fix message stuck as sending when delayed messaging enabled --- .../SendSmsReceiver.kt} | 24 +++++++++++-------- .../QKSMS/repository/MessageRepositoryImpl.kt | 6 ++--- presentation/src/main/AndroidManifest.xml | 2 +- .../injection/android/ServiceBuilderModule.kt | 4 ++-- 4 files changed, 20 insertions(+), 16 deletions(-) rename data/src/main/java/com/moez/QKSMS/{service/SendSmsService.kt => receiver/SendSmsReceiver.kt} (65%) diff --git a/data/src/main/java/com/moez/QKSMS/service/SendSmsService.kt b/data/src/main/java/com/moez/QKSMS/receiver/SendSmsReceiver.kt similarity index 65% rename from data/src/main/java/com/moez/QKSMS/service/SendSmsService.kt rename to data/src/main/java/com/moez/QKSMS/receiver/SendSmsReceiver.kt index 6838ddee5..5ac2aefc7 100644 --- a/data/src/main/java/com/moez/QKSMS/service/SendSmsService.kt +++ b/data/src/main/java/com/moez/QKSMS/receiver/SendSmsReceiver.kt @@ -16,27 +16,31 @@ * You should have received a copy of the GNU General Public License * along with QKSMS. If not, see . */ -package com.moez.QKSMS.service +package com.moez.QKSMS.receiver -import android.app.IntentService +import android.content.BroadcastReceiver +import android.content.Context import android.content.Intent import com.moez.QKSMS.interactor.RetrySending import com.moez.QKSMS.repository.MessageRepository import dagger.android.AndroidInjection import javax.inject.Inject -class SendSmsService : IntentService(null) { +class SendSmsReceiver : BroadcastReceiver() { @Inject lateinit var messageRepo: MessageRepository @Inject lateinit var retrySending: RetrySending - override fun onHandleIntent(intent: Intent) { - AndroidInjection.inject(this) + override fun onReceive(context: Context, intent: Intent) { + AndroidInjection.inject(this, context) - val id = intent.getLongExtra("id", 0L) - messageRepo.getMessage(id)?.let { message -> - retrySending.buildObservable(message).blockingSubscribe() - } + intent.getLongExtra("id", -1L) + .takeIf { it >= 0 } + ?.let(messageRepo::getMessage) + ?.let { message -> + val result = goAsync() + retrySending.execute(message) { result.finish() } + } } -} \ No newline at end of file +} diff --git a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt index 91d8cd7e2..8b6dd02c2 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt @@ -42,9 +42,9 @@ import com.moez.QKSMS.model.Attachment import com.moez.QKSMS.model.Conversation import com.moez.QKSMS.model.Message import com.moez.QKSMS.model.MmsPart +import com.moez.QKSMS.receiver.SendSmsReceiver import com.moez.QKSMS.receiver.SmsDeliveredReceiver import com.moez.QKSMS.receiver.SmsSentReceiver -import com.moez.QKSMS.service.SendSmsService import com.moez.QKSMS.util.ImageUtils import com.moez.QKSMS.util.Preferences import com.moez.QKSMS.util.tryOrNull @@ -313,8 +313,8 @@ class MessageRepositoryImpl @Inject constructor( } private fun getIntentForDelayedSms(id: Long): PendingIntent { - val intent = Intent(context, SendSmsService::class.java).putExtra("id", id) - return PendingIntent.getService(context, id.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT) + val intent = Intent(context, SendSmsReceiver::class.java).putExtra("id", id) + return PendingIntent.getBroadcast(context, id.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT) } override fun insertSentSms(subId: Int, threadId: Long, address: String, body: String, date: Long): Message { diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index e9c2555a1..4e13de5f8 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -166,6 +166,7 @@ + @@ -191,7 +192,6 @@ - Date: Fri, 7 Jun 2019 01:22:57 -0400 Subject: [PATCH 007/178] Go async when sending scheduled message --- .../com/moez/QKSMS/receiver/SendScheduledMessageReceiver.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/moez/QKSMS/receiver/SendScheduledMessageReceiver.kt b/data/src/main/java/com/moez/QKSMS/receiver/SendScheduledMessageReceiver.kt index eac9d68ef..dcd2f3938 100644 --- a/data/src/main/java/com/moez/QKSMS/receiver/SendScheduledMessageReceiver.kt +++ b/data/src/main/java/com/moez/QKSMS/receiver/SendScheduledMessageReceiver.kt @@ -35,7 +35,8 @@ class SendScheduledMessageReceiver : BroadcastReceiver() { AndroidInjection.inject(this, context) intent.getLongExtra("id", -1L).takeIf { it >= 0 }?.let { id -> - sendScheduledMessage.buildObservable(id).blockingSubscribe() + val result = goAsync() + sendScheduledMessage.execute(id) { result.finish() } } } -- GitLab From ec14f7a37e6d8b4526629a06641f96ccbb337955 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Fri, 7 Jun 2019 03:08:39 -0400 Subject: [PATCH 008/178] #1424 - Use same color for dark theme status and toolbar --- presentation/src/main/res/values/colors.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presentation/src/main/res/values/colors.xml b/presentation/src/main/res/values/colors.xml index fa99d77c9..2091ee13d 100644 --- a/presentation/src/main/res/values/colors.xml +++ b/presentation/src/main/res/values/colors.xml @@ -25,7 +25,7 @@ #33ffffff #FFFFFF - #1A1E22 + #1d262b #FFFFFF #1d262b -- GitLab From a08f21de931bed635e117d048a59be492b164dab Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Fri, 7 Jun 2019 04:16:53 -0400 Subject: [PATCH 009/178] #1434 - Fix QK Reply clipping --- presentation/src/main/AndroidManifest.xml | 3 ++- .../src/main/res/layout/qkreply_activity.xml | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index 4e13de5f8..8f164b003 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -104,7 +104,8 @@ android:name=".feature.qkreply.QkReplyActivity" android:excludeFromRecents="true" android:taskAffinity="" - android:theme="@style/AppThemeLightDialog" /> + android:theme="@style/AppThemeLightDialog" + android:windowSoftInputMode="adjustResize" /> diff --git a/presentation/src/main/res/layout/qkreply_activity.xml b/presentation/src/main/res/layout/qkreply_activity.xml index 36a5a88d3..f25990e39 100644 --- a/presentation/src/main/res/layout/qkreply_activity.xml +++ b/presentation/src/main/res/layout/qkreply_activity.xml @@ -27,11 +27,7 @@ android:layout_margin="24dp" android:background="@drawable/rounded_rectangle_4dp" android:backgroundTint="?attr/composeBackground" - android:clipChildren="false" - android:clipToPadding="false" android:elevation="8dp" - android:maxWidth="320dp" - android:maxHeight="320dp" tools:context="com.moez.QKSMS.feature.qkreply.QkReplyActivity"> @@ -65,7 +62,9 @@ android:background="@drawable/rounded_rectangle_bottom_4dp" android:backgroundTint="?attr/composeBackground" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toTopOf="@id/message" /> + app:layout_constraintTop_toBottomOf="@id/messages" + app:layout_constraintTop_toTopOf="@id/message" + app:layout_constraintVertical_weight="1" /> + app:layout_constraintBottom_toTopOf="@id/messages" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_weight="1"> Date: Fri, 7 Jun 2019 19:29:01 -0400 Subject: [PATCH 010/178] #824 - Ask user to set QK as default SMS app if they attempt something that requires it --- .../QKSMS/feature/compose/ComposeViewModel.kt | 8 +- .../ConversationInfoPresenter.kt | 5 +- .../moez/QKSMS/feature/main/MainViewModel.kt | 94 ++++++++++++------- 3 files changed, 69 insertions(+), 38 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt index 074c8dd81..bbef29b53 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt @@ -356,6 +356,7 @@ class ComposeViewModel @Inject constructor( // Delete the messages view.optionsItemIntent .filter { it == R.id.delete } + .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } .withLatestFrom(view.messagesSelectedIntent, conversation) { _, messages, conversation -> deleteMessages.execute(DeleteMessages.Params(messages, conversation.id)) } @@ -612,11 +613,8 @@ class ComposeViewModel @Inject constructor( // Send a message when the send button is clicked, and disable editing mode if it's enabled view.sendIntent - .filter { - val hasPermission = permissionManager.hasSendSms() - if (!hasPermission) view.requestSmsPermission() - hasPermission - } + .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.hasSendSms().also { if (!it) view.requestSmsPermission() } } .withLatestFrom(view.textChangedIntent) { _, body -> body } .map { body -> body.toString() } .withLatestFrom(state, attachments, conversation, selectedContacts) { body, state, attachments, conversation, contacts -> diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt index 90bd93176..749a548f4 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt @@ -26,6 +26,7 @@ import com.moez.QKSMS.interactor.MarkArchived import com.moez.QKSMS.interactor.MarkBlocked import com.moez.QKSMS.interactor.MarkUnarchived import com.moez.QKSMS.interactor.MarkUnblocked +import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.model.Conversation import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.MessageRepository @@ -46,7 +47,8 @@ class ConversationInfoPresenter @Inject constructor( private val markUnarchived: MarkUnarchived, private val markBlocked: MarkBlocked, private val markUnblocked: MarkUnblocked, - private val navigator: Navigator + private val navigator: Navigator, + private val permissionManager: PermissionManager ) : QkPresenter( ConversationInfoState(threadId = threadId, media = messageRepo.getPartsForConversation(threadId)) ) { @@ -151,6 +153,7 @@ class ConversationInfoPresenter @Inject constructor( // Show the delete confirmation dialog view.deleteClicks() + .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } .autoDisposable(view.scope()) .subscribe { view.showDeleteDialog() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index 2d5e1b007..f576a35a8 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -206,45 +206,75 @@ class MainViewModel @Inject constructor( .subscribe() view.optionsItemIntent - .withLatestFrom(view.conversationsSelectedIntent) { itemId, conversations -> - when (itemId) { - R.id.archive -> { - markArchived.execute(conversations) - view.clearSelection() - } + .filter { itemId -> itemId == R.id.archive } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markArchived.execute(conversations) + view.clearSelection() + } + .autoDisposable(view.scope()) + .subscribe() - R.id.unarchive -> { - markUnarchived.execute(conversations) - view.clearSelection() - } + view.optionsItemIntent + .filter { itemId -> itemId == R.id.unarchive } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markUnarchived.execute(conversations) + view.clearSelection() + } + .autoDisposable(view.scope()) + .subscribe() - R.id.delete -> view.showDeleteDialog(conversations) + view.optionsItemIntent + .filter { itemId -> itemId == R.id.delete } + .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + view.showDeleteDialog(conversations) + } + .autoDisposable(view.scope()) + .subscribe() - R.id.pin -> { - markPinned.execute(conversations) - view.clearSelection() - } + view.optionsItemIntent + .filter { itemId -> itemId == R.id.pin } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markPinned.execute(conversations) + view.clearSelection() + } + .autoDisposable(view.scope()) + .subscribe() - R.id.unpin -> { - markUnpinned.execute(conversations) - view.clearSelection() - } + view.optionsItemIntent + .filter { itemId -> itemId == R.id.unpin } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markUnpinned.execute(conversations) + view.clearSelection() + } + .autoDisposable(view.scope()) + .subscribe() - R.id.read -> { - markRead.execute(conversations) - view.clearSelection() - } + view.optionsItemIntent + .filter { itemId -> itemId == R.id.read } + .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markRead.execute(conversations) + view.clearSelection() + } + .autoDisposable(view.scope()) + .subscribe() - R.id.unread -> { - markUnread.execute(conversations) - view.clearSelection() - } + view.optionsItemIntent + .filter { itemId -> itemId == R.id.unread } + .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markUnread.execute(conversations) + view.clearSelection() + } + .autoDisposable(view.scope()) + .subscribe() - R.id.block -> { - markBlocked.execute(conversations) - view.clearSelection() - } - } + view.optionsItemIntent + .filter { itemId -> itemId == R.id.block } + .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> + markBlocked.execute(conversations) + view.clearSelection() } .autoDisposable(view.scope()) .subscribe() -- GitLab From ec89c97b45158f04fe605a9d0f2bf4963e223928 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 9 Jun 2019 00:03:24 -0400 Subject: [PATCH 011/178] #1317 - Features on QKSMS+ will link to respective part of app Should help reduce the number of emails telling me the upgrade didn't work --- .../moez/QKSMS/feature/plus/PlusActivity.kt | 13 ++++++++++++ .../com/moez/QKSMS/feature/plus/PlusView.kt | 5 +++++ .../moez/QKSMS/feature/plus/PlusViewModel.kt | 20 +++++++++++++++++++ .../main/res/layout/qksms_plus_activity.xml | 5 +++++ 4 files changed, 43 insertions(+) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusActivity.kt index 316e51037..1df78e045 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusActivity.kt @@ -24,6 +24,7 @@ import androidx.core.view.children import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders import com.jakewharton.rxbinding2.view.clicks +import com.jakewharton.rxbinding2.view.enabled import com.moez.QKSMS.BuildConfig import com.moez.QKSMS.R import com.moez.QKSMS.common.base.QkThemedActivity @@ -36,6 +37,7 @@ import com.moez.QKSMS.common.util.extensions.setVisible import com.moez.QKSMS.common.widget.PreferenceView import com.moez.QKSMS.feature.plus.experiment.UpgradeButtonExperiment import dagger.android.AndroidInjection +import io.reactivex.Observable import kotlinx.android.synthetic.main.collapsing_toolbar.* import kotlinx.android.synthetic.main.preference_view.view.* import kotlinx.android.synthetic.main.qksms_plus_activity.* @@ -52,6 +54,11 @@ class PlusActivity : QkThemedActivity(), PlusView { override val upgradeIntent by lazy { upgrade.clicks() } override val upgradeDonateIntent by lazy { upgradeDonate.clicks() } override val donateIntent by lazy { donate.clicks() } + override val themeClicks by lazy { themes.clicks() } + override val scheduleClicks by lazy { schedule.clicks() } + override val backupClicks by lazy { backup.clicks() } + override val delayedClicks by lazy { delayed.clicks() } + override val nightClicks by lazy { night.clicks() } override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) @@ -97,6 +104,12 @@ class PlusActivity : QkThemedActivity(), PlusView { free.setVisible(fdroid) toUpgrade.setVisible(!fdroid && !state.upgraded) upgraded.setVisible(!fdroid && state.upgraded) + + themes.isEnabled = state.upgraded + schedule.isEnabled = state.upgraded + backup.isEnabled = state.upgraded + delayed.isEnabled = state.upgraded + night.isEnabled = state.upgraded } override fun initiatePurchaseFlow(billingManager: BillingManager, sku: String) { diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusView.kt index a10403289..8d7c67e84 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusView.kt @@ -27,6 +27,11 @@ interface PlusView : QkView { val upgradeIntent: Observable val upgradeDonateIntent: Observable val donateIntent: Observable<*> + val themeClicks: Observable<*> + val scheduleClicks: Observable<*> + val backupClicks: Observable<*> + val delayedClicks: Observable<*> + val nightClicks: Observable<*> fun initiatePurchaseFlow(billingManager: BillingManager, sku: String) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt index e7131bc56..eb70e508f 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt @@ -62,6 +62,26 @@ class PlusViewModel @Inject constructor( view.donateIntent .autoDisposable(view.scope()) .subscribe { navigator.showDonation() } + + view.themeClicks + .autoDisposable(view.scope()) + .subscribe { navigator.showSettings() } + + view.scheduleClicks + .autoDisposable(view.scope()) + .subscribe { navigator.showScheduled() } + + view.backupClicks + .autoDisposable(view.scope()) + .subscribe { navigator.showBackup() } + + view.delayedClicks + .autoDisposable(view.scope()) + .subscribe { navigator.showSettings() } + + view.nightClicks + .autoDisposable(view.scope()) + .subscribe { navigator.showSettings() } } } \ No newline at end of file diff --git a/presentation/src/main/res/layout/qksms_plus_activity.xml b/presentation/src/main/res/layout/qksms_plus_activity.xml index e0602b4ec..f5ec288a2 100644 --- a/presentation/src/main/res/layout/qksms_plus_activity.xml +++ b/presentation/src/main/res/layout/qksms_plus_activity.xml @@ -162,6 +162,7 @@ android:background="?android:attr/divider" /> Date: Sun, 9 Jun 2019 01:44:14 -0400 Subject: [PATCH 012/178] #1393 - Improve how we display long conversation names or group members --- .../moez/QKSMS/common/widget/QkTextView.kt | 30 +++++++++++++++++++ .../conversations/ConversationsAdapter.kt | 15 ++++++++++ .../res/layout/conversation_list_item.xml | 13 ++++---- presentation/src/main/res/values/styles.xml | 1 + 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt index 36c909003..b8aa92560 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt @@ -30,6 +30,20 @@ open class QkTextView @JvmOverloads constructor(context: Context, attrs: Attribu @Inject lateinit var textViewStyler: TextViewStyler + /** + * Collapse a multiline list of strings into a single line + * + * Ex. + * + * Toronto, New York, Los Angeles, + * Seattle, Portland + * + * Will be converted to + * + * Toronto, New York, Los Angeles, +2 + */ + var collapseEnabled: Boolean = false + init { if (!isInEditMode) { appComponent.inject(this) @@ -39,6 +53,22 @@ open class QkTextView @JvmOverloads constructor(context: Context, attrs: Attribu } } + override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { + super.onLayout(changed, left, top, right, bottom) + + if (collapseEnabled) { + layout + ?.takeIf { layout -> layout.lineCount > 0 } + ?.let { layout -> layout.getEllipsisCount(layout.lineCount - 1) } + ?.takeIf { ellipsisCount -> ellipsisCount > 0 } + ?.let { ellipsisCount -> + val lastComma = text.dropLast(ellipsisCount).lastIndexOf(',') + val remainingNames = text.drop(lastComma).count { c -> c == ',' } + text = "${text.take(lastComma)}, +$remainingNames" + } + } + } + override fun setTextColor(color: Int) { super.setTextColor(color) setLinkTextColor(color) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationsAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationsAdapter.kt index 5413f2319..e864cfa93 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationsAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationsAdapter.kt @@ -84,6 +84,21 @@ class ConversationsAdapter @Inject constructor( view.isActivated = isSelected(conversation.id) view.avatars.contacts = conversation.recipients + view.title.collapseEnabled = conversation.recipients.size > 1 + + val conversationTitle = conversation.getTitle() + view.title.text = conversationTitle + if (conversation.recipients.size > 1) { + view.title.layout + ?.takeIf { layout -> layout.lineCount > 0 } + ?.let { layout -> layout.getEllipsisCount(layout.lineCount - 1) } + ?.takeIf { ellipsisCount -> ellipsisCount > 0 } + ?.let { ellipsisCount -> + val lastComma = conversationTitle.dropLast(ellipsisCount).lastIndexOf(',') + val remainingNames = conversationTitle.drop(lastComma).count { c -> c == ',' } + view.title.text = "${conversationTitle.take(lastComma)}, +$remainingNames" + } + } view.title.text = conversation.getTitle() view.date.text = dateFormatter.getConversationTimestamp(conversation.date) view.snippet.text = when (conversation.me) { diff --git a/presentation/src/main/res/layout/conversation_list_item.xml b/presentation/src/main/res/layout/conversation_list_item.xml index fbf423c80..1826f85e7 100644 --- a/presentation/src/main/res/layout/conversation_list_item.xml +++ b/presentation/src/main/res/layout/conversation_list_item.xml @@ -1,5 +1,4 @@ - - " + mAutoDownload); + Timber.v("mAutoDownload ------> " + mAutoDownload); } } @@ -77,11 +74,11 @@ public class DownloadManager { public static void init(Context context) { if (LOCAL_LOGV) { - Log.v(TAG, "DownloadManager.init()"); + Timber.v("DownloadManager.init()"); } if (sInstance != null) { - Log.w(TAG, "Already initialized."); + Timber.w("Already initialized."); } sInstance = new DownloadManager(context); } @@ -101,14 +98,14 @@ public class DownloadManager { boolean autoDownload = prefs.getBoolean("auto_download_mms", true); if (LOCAL_LOGV) { - Log.v(TAG, "auto download without roaming -> " + autoDownload); + Timber.v("auto download without roaming -> " + autoDownload); } if (autoDownload) { boolean alwaysAuto = true; if (LOCAL_LOGV) { - Log.v(TAG, "auto download during roaming -> " + alwaysAuto); + Timber.v("auto download during roaming -> " + alwaysAuto); } if (!roaming || alwaysAuto) { @@ -123,7 +120,7 @@ public class DownloadManager { String roaming = SystemPropertiesProxy.get(context, TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null); if (LOCAL_LOGV) { - Log.v(TAG, "roaming ------> " + roaming); + Timber.v("roaming ------> " + roaming); } return "true".equals(roaming); } @@ -145,7 +142,7 @@ public class DownloadManager { return; } } catch(MmsException e) { - Log.e(TAG, e.getMessage(), e); + Timber.e(e, e.getMessage()); return; } @@ -157,7 +154,7 @@ public class DownloadManager { Toast.makeText(mContext, getMessage(uri), Toast.LENGTH_LONG).show(); } catch (MmsException e) { - Log.e(TAG, e.getMessage(), e); + Timber.e(e, e.getMessage()); } } }); @@ -180,7 +177,7 @@ public class DownloadManager { try { Toast.makeText(mContext, errStr, Toast.LENGTH_LONG).show(); } catch (Exception e) { - Log.e(TAG,"Caught an exception in showErrorCodeToast"); + Timber.e("Caught an exception in showErrorCodeToast"); } } }); diff --git a/android-smsmms/src/main/java/com/android/mms/util/ExternalLogger.java b/android-smsmms/src/main/java/com/android/mms/util/ExternalLogger.java deleted file mode 100755 index e57e41592..000000000 --- a/android-smsmms/src/main/java/com/android/mms/util/ExternalLogger.java +++ /dev/null @@ -1,36 +0,0 @@ - -package com.android.mms.util; - - -import java.util.concurrent.CopyOnWriteArrayList; - -public class ExternalLogger { - private static final CopyOnWriteArrayList sListener = new CopyOnWriteArrayList(); - - public interface LoggingListener { - void onLogException(String tag, Throwable e); - void onLogMessage(String tag, String message); - } - - private ExternalLogger(){} - - public static void addListener(LoggingListener listener) { - sListener.add(listener); - } - - public static void removeListener(LoggingListener listener) { - sListener.remove(listener); - } - - public static void logException(String tag, Throwable e) { - for (LoggingListener listener: sListener) { - listener.onLogException(tag, e); - } - } - - public static void logMessage(String tag, String message) { - for (LoggingListener listener: sListener) { - listener.onLogMessage(tag, message); - } - } -} diff --git a/android-smsmms/src/main/java/com/android/mms/util/RateController.java b/android-smsmms/src/main/java/com/android/mms/util/RateController.java index 9c3985c40..fa4365dcb 100755 --- a/android-smsmms/src/main/java/com/android/mms/util/RateController.java +++ b/android-smsmms/src/main/java/com/android/mms/util/RateController.java @@ -24,12 +24,9 @@ import android.content.IntentFilter; import android.database.Cursor; import android.database.sqlite.SqliteWrapper; import android.provider.Telephony.Mms.Rate; -import com.android.mms.logs.LogTag; -import com.klinker.android.logger.Log; +import timber.log.Timber; public class RateController { - private static final String TAG = LogTag.TAG; - private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; private static final int RATE_LIMIT = 100; @@ -55,7 +52,7 @@ public class RateController { @Override public void onReceive(Context context, Intent intent) { if (LOCAL_LOGV) { - Log.v(TAG, "Intent received: " + intent); + Timber.v("Intent received: " + intent); } if (RATE_LIMIT_CONFIRMED_ACTION.equals(intent.getAction())) { @@ -74,11 +71,11 @@ public class RateController { public static void init(Context context) { if (LOCAL_LOGV) { - Log.v(TAG, "RateController.init()"); + Timber.v("RateController.init()"); } if (sInstance != null) { - Log.w(TAG, "Already initialized."); + Timber.w("Already initialized."); return; } sInstance = new RateController(context); @@ -149,7 +146,7 @@ public class RateController { for (int t = 0; (mAnswer == NO_ANSWER) && (t < ANSWER_TIMEOUT); t += 1000) { try { if (LOCAL_LOGV) { - Log.v(TAG, "Waiting for answer..." + t / 1000); + Timber.v("Waiting for answer..." + t / 1000); } wait(1000L); } catch (InterruptedException e) { diff --git a/android-smsmms/src/main/java/com/android/mms/util/SendingProgressTokenManager.java b/android-smsmms/src/main/java/com/android/mms/util/SendingProgressTokenManager.java index fdd397f07..a0d4dcc00 100755 --- a/android-smsmms/src/main/java/com/android/mms/util/SendingProgressTokenManager.java +++ b/android-smsmms/src/main/java/com/android/mms/util/SendingProgressTokenManager.java @@ -16,14 +16,11 @@ package com.android.mms.util; -import com.android.mms.logs.LogTag; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.util.HashMap; public class SendingProgressTokenManager { - private static final String TAG = LogTag.TAG; - private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; private static final HashMap TOKEN_POOL; @@ -36,21 +33,21 @@ public class SendingProgressTokenManager { synchronized public static long get(Object key) { Long token = TOKEN_POOL.get(key); if (LOCAL_LOGV) { - Log.v(TAG, "TokenManager.get(" + key + ") -> " + token); + Timber.v("TokenManager.get(" + key + ") -> " + token); } return token != null ? token : NO_TOKEN; } synchronized public static void put(Object key, long token) { if (LOCAL_LOGV) { - Log.v(TAG, "TokenManager.put(" + key + ", " + token + ")"); + Timber.v("TokenManager.put(" + key + ", " + token + ")"); } TOKEN_POOL.put(key, token); } synchronized public static void remove(Object key) { if (LOCAL_LOGV) { - Log.v(TAG, "TokenManager.remove(" + key + ")"); + Timber.v("TokenManager.remove(" + key + ")"); } TOKEN_POOL.remove(key); } diff --git a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/EncodedStringValue.java b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/EncodedStringValue.java index 706be7df9..26de8f6b4 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/EncodedStringValue.java +++ b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/EncodedStringValue.java @@ -16,7 +16,7 @@ package com.google.android.mms.pdu_alt; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -27,8 +27,6 @@ import java.util.ArrayList; * Encoded-string-value = Text-string | Value-length Char-set Text-string */ public class EncodedStringValue implements Cloneable { - private static final String TAG = "EncodedStringValue"; - private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; /** @@ -74,7 +72,7 @@ public class EncodedStringValue implements Cloneable { mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME); mCharacterSet = CharacterSets.DEFAULT_CHARSET; } catch (UnsupportedEncodingException e) { - Log.e(TAG, "Default encoding must be supported.", e); + Timber.e(e, "Default encoding must be supported."); } } @@ -140,7 +138,7 @@ public class EncodedStringValue implements Cloneable { return new String(mData, name); } catch (UnsupportedEncodingException e) { if (LOCAL_LOGV) { - Log.v(TAG, e.getMessage(), e); + Timber.v(e, e.getMessage()); } try { return new String(mData, CharacterSets.MIMENAME_ISO_8859_1); @@ -172,7 +170,7 @@ public class EncodedStringValue implements Cloneable { newTextString.write(mData); newTextString.write(textString); } catch (IOException e) { - Log.e(TAG, "logging error", e); + Timber.e(e, "logging error"); e.printStackTrace(); throw new NullPointerException( "appendTextString: failed when write a new Text-string"); @@ -196,7 +194,7 @@ public class EncodedStringValue implements Cloneable { try { return new EncodedStringValue(mCharacterSet, dstBytes); } catch (Exception e) { - Log.e(TAG, "logging error", e); + Timber.e(e, "logging error"); e.printStackTrace(); throw new CloneNotSupportedException(e.getMessage()); } diff --git a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduComposer.java b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduComposer.java index fbba0e2b6..8e9f5edb5 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduComposer.java +++ b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduComposer.java @@ -19,7 +19,7 @@ package com.google.android.mms.pdu_alt; import android.content.ContentResolver; import android.content.Context; import android.text.TextUtils; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; @@ -80,7 +80,6 @@ public class PduComposer { * Block size when read data from InputStream. */ static private final int PDU_COMPOSER_BLOCK_SIZE = 1024; - private static final String TAG = "PduComposer"; /** * The output message. @@ -886,7 +885,7 @@ public class PduComposer { appendTextString(part.getContentType()); } catch (ArrayIndexOutOfBoundsException e){ - Log.e(TAG, "logging error", e); + Timber.e(e, "logging error"); e.printStackTrace(); } diff --git a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduParser.java b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduParser.java index 75cd1c860..654de146d 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduParser.java +++ b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduParser.java @@ -16,10 +16,9 @@ package com.google.android.mms.pdu_alt; -import com.android.mms.util.ExternalLogger; import com.google.android.mms.ContentType; import com.google.android.mms.InvalidHeaderValueException; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -80,8 +79,6 @@ public class PduParser { /** * The log tag. */ - private static final String LOG_TAG = "PduParser"; - private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; /** @@ -149,33 +146,33 @@ public class PduParser { switch (messageType) { case PduHeaders.MESSAGE_TYPE_SEND_REQ: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_REQ"); + Timber.v("parse: MESSAGE_TYPE_SEND_REQ"); } SendReq sendReq = new SendReq(mHeaders, mBody); return sendReq; case PduHeaders.MESSAGE_TYPE_SEND_CONF: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_CONF"); + Timber.v("parse: MESSAGE_TYPE_SEND_CONF"); } SendConf sendConf = new SendConf(mHeaders); return sendConf; case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFICATION_IND"); + Timber.v("parse: MESSAGE_TYPE_NOTIFICATION_IND"); } NotificationInd notificationInd = new NotificationInd(mHeaders); return notificationInd; case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFYRESP_IND"); + Timber.v("parse: MESSAGE_TYPE_NOTIFYRESP_IND"); } NotifyRespInd notifyRespInd = new NotifyRespInd(mHeaders); return notifyRespInd; case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_RETRIEVE_CONF"); + Timber.v("parse: MESSAGE_TYPE_RETRIEVE_CONF"); } RetrieveConf retrieveConf = new RetrieveConf(mHeaders, mBody); @@ -203,33 +200,33 @@ public class PduParser { // multipart/signed return retrieveConf; } else { - ExternalLogger.logMessage(LOG_TAG, "Unsupported ContentType: " + ctTypeStr); + Timber.v("Unsupported ContentType: " + ctTypeStr); } return null; case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_DELIVERY_IND"); + Timber.v("parse: MESSAGE_TYPE_DELIVERY_IND"); } DeliveryInd deliveryInd = new DeliveryInd(mHeaders); return deliveryInd; case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_ACKNOWLEDGE_IND"); + Timber.v("parse: MESSAGE_TYPE_ACKNOWLEDGE_IND"); } AcknowledgeInd acknowledgeInd = new AcknowledgeInd(mHeaders); return acknowledgeInd; case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_ORIG_IND"); + Timber.v("parse: MESSAGE_TYPE_READ_ORIG_IND"); } ReadOrigInd readOrigInd = new ReadOrigInd(mHeaders); return readOrigInd; case PduHeaders.MESSAGE_TYPE_READ_REC_IND: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_REC_IND"); + Timber.v("parse: MESSAGE_TYPE_READ_REC_IND"); } ReadRecInd readRecInd = new ReadRecInd(mHeaders); @@ -261,7 +258,7 @@ public class PduParser { pduDataStream.reset(); byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); + Timber.v("TextHeader: " + new String(bVal)); } /* we should ignore it at the moment */ continue; @@ -271,7 +268,7 @@ public class PduParser { { int messageType = extractByteValue(pduDataStream); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: messageType: " + messageType); + Timber.v("parseHeaders: messageType: " + messageType); } switch (messageType) { // We don't support these kind of messages now. @@ -335,8 +332,7 @@ public class PduParser { { int value = extractByteValue(pduDataStream); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: byte: " + headerField + " value: " + - value); + Timber.v("parseHeaders: byte: " + headerField + " value: " + value); } try { @@ -360,7 +356,7 @@ public class PduParser { try { long value = parseLongInteger(pduDataStream); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: longint: " + headerField + " value: " + + Timber.v("parseHeaders: longint: " + headerField + " value: " + value); } headers.setLongInteger(value, headerField); @@ -379,7 +375,7 @@ public class PduParser { try { long value = parseIntegerValue(pduDataStream); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: int: " + headerField + " value: " + + Timber.v("parseHeaders: int: " + headerField + " value: " + value); } headers.setLongInteger(value, headerField); @@ -415,7 +411,7 @@ public class PduParser { if (null != value) { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: string: " + headerField + " value: " + + Timber.v("parseHeaders: string: " + headerField + " value: " + new String(value)); } headers.setTextString(value, headerField); @@ -444,7 +440,7 @@ public class PduParser { if (null != value) { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: encoded string: " + headerField + Timber.v("parseHeaders: encoded string: " + headerField + " value: " + value.getString()); } headers.setEncodedStringValue(value, headerField); @@ -470,7 +466,7 @@ public class PduParser { if (null != address) { String str = new String(address); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: (to/cc/bcc) address: " + headerField + Timber.v("parseHeaders: (to/cc/bcc) address: " + headerField + " value: " + str); } int endIndex = str.indexOf("/"); @@ -525,7 +521,7 @@ public class PduParser { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: time value: " + headerField + Timber.v("parseHeaders: time value: " + headerField + " value: " + timeValue); } headers.setLongInteger(timeValue, headerField); @@ -579,7 +575,7 @@ public class PduParser { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: from address: " + headerField + Timber.v("parseHeaders: from address: " + headerField + " value: " + from.getString()); } headers.setEncodedStringValue(from, PduHeaders.FROM); @@ -597,7 +593,7 @@ public class PduParser { pduDataStream.mark(1); int messageClass = extractByteValue(pduDataStream); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MESSAGE_CLASS: " + headerField + Timber.v("parseHeaders: MESSAGE_CLASS: " + headerField + " value: " + messageClass); } @@ -650,7 +646,7 @@ public class PduParser { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MMS_VERSION: " + headerField + Timber.v("parseHeaders: MMS_VERSION: " + headerField + " value: " + version); } headers.setOctet(version, PduHeaders.MMS_VERSION); @@ -685,7 +681,7 @@ public class PduParser { if (null != previouslySentBy) { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_BY: " + headerField + Timber.v("parseHeaders: PREVIOUSLY_SENT_BY: " + headerField + " value: " + previouslySentBy.getString()); } headers.setEncodedStringValue(previouslySentBy, @@ -718,7 +714,7 @@ public class PduParser { try { long perviouslySentDate = parseLongInteger(pduDataStream); if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_DATE: " + headerField + Timber.v("parseHeaders: PREVIOUSLY_SENT_DATE: " + headerField + " value: " + perviouslySentDate); } headers.setLongInteger(perviouslySentDate, @@ -737,7 +733,7 @@ public class PduParser { * Encoded-string-value */ if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MM_FLAGS: " + headerField + Timber.v("parseHeaders: MM_FLAGS: " + headerField + " NOT REALLY SUPPORTED"); } @@ -761,7 +757,7 @@ public class PduParser { case PduHeaders.MBOX_QUOTAS: { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MBOX_TOTALS: " + headerField); + Timber.v("parseHeaders: MBOX_TOTALS: " + headerField); } /* Value-length */ parseValueLength(pduDataStream); @@ -784,7 +780,7 @@ public class PduParser { case PduHeaders.ELEMENT_DESCRIPTOR: { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: ELEMENT_DESCRIPTOR: " + headerField); + Timber.v("parseHeaders: ELEMENT_DESCRIPTOR: " + headerField); } parseContentType(pduDataStream, null); @@ -802,8 +798,7 @@ public class PduParser { if (null != contentType) { try { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: CONTENT_TYPE: " + headerField + - contentType.toString()); + Timber.v("parseHeaders: CONTENT_TYPE: " + headerField + contentType.toString()); } headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); } catch(NullPointerException e) { @@ -829,7 +824,7 @@ public class PduParser { case PduHeaders.ATTRIBUTES: default: { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: Unknown header: " + headerField); + Timber.v("parseHeaders: Unknown header: " + headerField); } log("Unknown header"); } @@ -961,7 +956,7 @@ public class PduParser { */ private static void log(String text) { if (LOCAL_LOGV) { - Log.v(LOG_TAG, text); + Timber.v(text); } } @@ -1475,7 +1470,7 @@ public class PduParser { map.put(PduPart.P_CHARSET, charsetInt); } catch (UnsupportedEncodingException e) { // Not a well-known charset, use "*". - Log.e(LOG_TAG, Arrays.toString(charsetStr), e); + Timber.e(e, Arrays.toString(charsetStr)); map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET); } } else { @@ -1510,10 +1505,10 @@ public class PduParser { break; default: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Content-Type parameter"); + Timber.v("Not supported Content-Type parameter"); } if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Content-Type"); + Timber.e("Corrupt Content-Type"); } else { lastLen = 0; } @@ -1522,7 +1517,7 @@ public class PduParser { } if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Content-Type"); + Timber.e("Corrupt Content-Type"); } } @@ -1572,7 +1567,7 @@ public class PduParser { contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); } } else { - Log.e(LOG_TAG, "Corrupt content-type"); + Timber.e("Corrupt content-type"); return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" } @@ -1583,7 +1578,7 @@ public class PduParser { } if (parameterLen < 0) { - Log.e(LOG_TAG, "Corrupt MMS message"); + Timber.e("Corrupt MMS message"); return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" } } else if (cur <= TEXT_MAX) { @@ -1722,10 +1717,10 @@ public class PduParser { break; default: if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); + Timber.v("Not supported Part headers: " + header); } if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); + Timber.e("Corrupt Part headers"); return false; } lastLen = 0; @@ -1746,11 +1741,11 @@ public class PduParser { lastLen = length - (startPos - tempPos); } else { if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); + Timber.v("Not supported Part headers: " + header); } // Skip all headers of this part. if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); + Timber.e("Corrupt Part headers"); return false; } lastLen = 0; @@ -1758,7 +1753,7 @@ public class PduParser { } if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Part headers"); + Timber.e("Corrupt Part headers"); return false; } diff --git a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPart.java b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPart.java index 6bfff3de1..9cb631f6c 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPart.java +++ b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPart.java @@ -118,8 +118,6 @@ public class PduPart { */ private byte[] mPartData = null; - private static final String TAG = "PduPart"; - /** * Empty Constructor. */ diff --git a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPersister.java b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPersister.java index 8b4680e27..638b4c9ab 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPersister.java +++ b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/PduPersister.java @@ -46,7 +46,7 @@ import com.google.android.mms.util_alt.DrmConvertSession; import com.google.android.mms.util_alt.PduCache; import com.google.android.mms.util_alt.PduCacheEntry; import com.google.android.mms.util_alt.SqliteWrapper; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.ByteArrayOutputStream; import java.io.File; @@ -65,8 +65,6 @@ import java.util.Set; * This class is the high-level manager of PDU storage. */ public class PduPersister { - private static final String TAG = "PduPersister"; - private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; private static final long DUMMY_THREAD_ID = Long.MAX_VALUE; @@ -367,7 +365,7 @@ public class PduPersister { try { if ((c == null) || (c.getCount() == 0)) { if (LOCAL_LOGV) { - Log.v(TAG, "loadParts(" + msgId + "): no part to load."); + Timber.v("loadParts(" + msgId + "): no part to load."); } return null; } @@ -456,7 +454,7 @@ public class PduPersister { len = is.read(buffer); } } catch (IOException e) { - Log.e(TAG, "Failed to load part data", e); + Timber.e(e, "Failed to load part data"); c.close(); throw new MmsException(e); } finally { @@ -464,7 +462,7 @@ public class PduPersister { try { is.close(); } catch (IOException e) { - Log.e(TAG, "Failed to close stream", e); + Timber.e(e, "Failed to close stream"); } // Ignore } } @@ -508,7 +506,7 @@ public class PduPersister { addrType); break; default: - Log.e(TAG, "Unknown address type: " + addrType); + Timber.e("Unknown address type: " + addrType); break; } } @@ -535,12 +533,12 @@ public class PduPersister { synchronized (PDU_CACHE_INSTANCE) { if (PDU_CACHE_INSTANCE.isUpdating(uri)) { if (LOCAL_LOGV) { - Log.v(TAG, "load: " + uri + " blocked by isUpdating()"); + Timber.v("load: " + uri + " blocked by isUpdating()"); } try { PDU_CACHE_INSTANCE.wait(); } catch (InterruptedException e) { - Log.e(TAG, "load: ", e); + Timber.e(e, "load: "); } cacheEntry = PDU_CACHE_INSTANCE.get(uri); if (cacheEntry != null) { @@ -845,12 +843,12 @@ public class PduPersister { try { path = convertUriToPath(mContext, uri); if (LOCAL_LOGV) { - Log.v(TAG, "drm uri: " + uri + " path: " + path); + Timber.v("drm uri: " + uri + " path: " + path); } File f = new File(path); long len = f.length(); if (LOCAL_LOGV) { - Log.v(TAG, "drm path: " + path + " len: " + len); + Timber.v("drm path: " + path + " len: " + len); } if (len > 0) { // we're not going to re-persist and re-encrypt an already @@ -858,7 +856,7 @@ public class PduPersister { return; } } catch (Exception e) { - Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e); + Timber.e(e, "Can't get file info for: " + part.getDataUri()); } } // We haven't converted the file yet, start the conversion @@ -874,7 +872,7 @@ public class PduPersister { if (data == null) { dataUri = part.getDataUri(); if ((dataUri == null) || (dataUri == uri)) { - Log.w(TAG, "Can't find data for this part."); + Timber.w("Can't find data for this part."); return; } // dataUri can look like: @@ -887,7 +885,7 @@ public class PduPersister { } if (LOCAL_LOGV) { - Log.v(TAG, "Saving data to: " + uri); + Timber.v("Saving data to: " + uri); } byte[] buffer = new byte[8192]; @@ -905,7 +903,7 @@ public class PduPersister { } } else { if (LOCAL_LOGV) { - Log.v(TAG, "Saving data to: " + uri); + Timber.v("Saving data to: " + uri); } if (!isDrm) { os.write(data); @@ -921,24 +919,24 @@ public class PduPersister { } } } catch (FileNotFoundException e) { - Log.e(TAG, "Failed to open Input/Output stream.", e); + Timber.e(e, "Failed to open Input/Output stream."); throw new MmsException(e); } catch (IOException e) { - Log.e(TAG, "Failed to read/write data.", e); + Timber.e(e, "Failed to read/write data."); throw new MmsException(e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { - Log.e(TAG, "IOException while closing: " + os, e); + Timber.e(e, "IOException while closing: " + os); } // Ignore } if (is != null) { try { is.close(); } catch (IOException e) { - Log.e(TAG, "IOException while closing: " + is, e); + Timber.e(e, "IOException while closing: " + is); } // Ignore } if (drmConvertSession != null) { @@ -1025,12 +1023,12 @@ public class PduPersister { // purging it. if (PDU_CACHE_INSTANCE.isUpdating(uri)) { if (LOCAL_LOGV) { - Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()"); + Timber.v("updateHeaders: " + uri + " blocked by isUpdating()"); } try { PDU_CACHE_INSTANCE.wait(); } catch (InterruptedException e) { - Log.e(TAG, "updateHeaders: ", e); + Timber.e(e, "updateHeaders: "); } } } @@ -1193,12 +1191,12 @@ public class PduPersister { synchronized (PDU_CACHE_INSTANCE) { if (PDU_CACHE_INSTANCE.isUpdating(uri)) { if (LOCAL_LOGV) { - Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()"); + Timber.v("updateParts: " + uri + " blocked by isUpdating()"); } try { PDU_CACHE_INSTANCE.wait(); } catch (InterruptedException e) { - Log.e(TAG, "updateParts: ", e); + Timber.e(e, "updateParts: "); } cacheEntry = PDU_CACHE_INSTANCE.get(uri); if (cacheEntry != null) { @@ -1301,12 +1299,12 @@ public class PduPersister { // purging it. if (PDU_CACHE_INSTANCE.isUpdating(uri)) { if (LOCAL_LOGV) { - Log.v(TAG, "persist: " + uri + " blocked by isUpdating()"); + Timber.v("persist: " + uri + " blocked by isUpdating()"); } try { PDU_CACHE_INSTANCE.wait(); } catch (InterruptedException e) { - Log.e(TAG, "persist1: ", e); + Timber.e(e, "persist1: "); } } } @@ -1552,7 +1550,7 @@ public class PduPersister { return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1); } catch (UnsupportedEncodingException e) { // Impossible to reach here! - Log.e(TAG, "ISO_8859_1 must be supported!", e); + Timber.e(e, "ISO_8859_1 must be supported!"); return ""; } } @@ -1565,7 +1563,7 @@ public class PduPersister { return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1); } catch (UnsupportedEncodingException e) { // Impossible to reach here! - Log.e(TAG, "ISO_8859_1 must be supported!", e); + Timber.e(e, "ISO_8859_1 must be supported!"); return new byte[0]; } } @@ -1583,7 +1581,7 @@ public class PduPersister { */ public Cursor getPendingMessages(long dueTime) { if (!checkReadSmsPermissions()) { - Log.w(TAG, "No read sms permissions have been granted"); + Timber.w("No read sms permissions have been granted"); return null; } Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon(); diff --git a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/SendReq.java b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/SendReq.java index 2c527d456..47bf0150e 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/SendReq.java +++ b/android-smsmms/src/main/java/com/google/android/mms/pdu_alt/SendReq.java @@ -17,10 +17,9 @@ package com.google.android.mms.pdu_alt; import com.google.android.mms.InvalidHeaderValueException; -import com.klinker.android.logger.Log; +import timber.log.Timber; public class SendReq extends MultimediaMessagePdu { - private static final String TAG = "SendReq"; public SendReq() { super(); @@ -35,7 +34,7 @@ public class SendReq extends MultimediaMessagePdu { setTransactionId(generateTransactionId()); } catch (InvalidHeaderValueException e) { // Impossible to reach here since all headers we set above are valid. - Log.e(TAG, "Unexpected InvalidHeaderValueException.", e); + Timber.e(e, "Unexpected InvalidHeaderValueException."); throw new RuntimeException(e); } } diff --git a/android-smsmms/src/main/java/com/google/android/mms/smil/SmilHelper.java b/android-smsmms/src/main/java/com/google/android/mms/smil/SmilHelper.java index 007e769b7..27053dfdd 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/smil/SmilHelper.java +++ b/android-smsmms/src/main/java/com/google/android/mms/smil/SmilHelper.java @@ -4,12 +4,12 @@ import com.android.mms.dom.smil.SmilDocumentImpl; import com.google.android.mms.ContentType; import com.google.android.mms.pdu_alt.PduBody; import com.google.android.mms.pdu_alt.PduPart; -import com.klinker.android.logger.Log; import org.w3c.dom.smil.SMILDocument; import org.w3c.dom.smil.SMILElement; import org.w3c.dom.smil.SMILLayoutElement; import org.w3c.dom.smil.SMILMediaElement; import org.w3c.dom.smil.SMILParElement; +import timber.log.Timber; public class SmilHelper { @@ -88,7 +88,7 @@ public class SmilHelper { par.appendChild(textElement); hasMedia = true; } else { - Log.e("creating_smil_document", "unknown mimetype"); + Timber.e("creating_smil_document", "unknown mimetype"); } } diff --git a/android-smsmms/src/main/java/com/google/android/mms/util_alt/AbstractCache.java b/android-smsmms/src/main/java/com/google/android/mms/util_alt/AbstractCache.java index beebc2b8c..69123232a 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/util_alt/AbstractCache.java +++ b/android-smsmms/src/main/java/com/google/android/mms/util_alt/AbstractCache.java @@ -16,12 +16,11 @@ package com.google.android.mms.util_alt; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.util.HashMap; public abstract class AbstractCache { - private static final String TAG = "AbstractCache"; private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; @@ -35,14 +34,14 @@ public abstract class AbstractCache { public boolean put(K key, V value) { if (LOCAL_LOGV) { - Log.v(TAG, "Trying to put " + key + " into cache."); + Timber.v("Trying to put " + key + " into cache."); } if (mCacheMap.size() >= MAX_CACHED_ITEMS) { // TODO Should remove the oldest or least hit cached entry // and then cache the new one. if (LOCAL_LOGV) { - Log.v(TAG, "Failed! size limitation reached."); + Timber.v("Failed! size limitation reached."); } return false; } @@ -53,7 +52,7 @@ public abstract class AbstractCache { mCacheMap.put(key, cacheEntry); if (LOCAL_LOGV) { - Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total."); + Timber.v(key + " cached, " + mCacheMap.size() + " items total."); } return true; } @@ -62,7 +61,7 @@ public abstract class AbstractCache { public V get(K key) { if (LOCAL_LOGV) { - Log.v(TAG, "Trying to get " + key + " from cache."); + Timber.v("Trying to get " + key + " from cache."); } if (key != null) { @@ -70,7 +69,7 @@ public abstract class AbstractCache { if (cacheEntry != null) { cacheEntry.hit++; if (LOCAL_LOGV) { - Log.v(TAG, key + " hit " + cacheEntry.hit + " times."); + Timber.v(key + " hit " + cacheEntry.hit + " times."); } return cacheEntry.value; } @@ -80,13 +79,13 @@ public abstract class AbstractCache { public V purge(K key) { if (LOCAL_LOGV) { - Log.v(TAG, "Trying to purge " + key); + Timber.v("Trying to purge " + key); } CacheEntry v = mCacheMap.remove(key); if (LOCAL_LOGV) { - Log.v(TAG, mCacheMap.size() + " items cached."); + Timber.v(mCacheMap.size() + " items cached."); } return v != null ? v.value : null; @@ -94,8 +93,7 @@ public abstract class AbstractCache { public void purgeAll() { if (LOCAL_LOGV) { - Log.v(TAG, "Purging cache, " + mCacheMap.size() - + " items dropped."); + Timber.v("Purging cache, " + mCacheMap.size() + " items dropped."); } mCacheMap.clear(); } diff --git a/android-smsmms/src/main/java/com/google/android/mms/util_alt/DownloadDrmHelper.java b/android-smsmms/src/main/java/com/google/android/mms/util_alt/DownloadDrmHelper.java index 7845e52c7..bb039b2f3 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/util_alt/DownloadDrmHelper.java +++ b/android-smsmms/src/main/java/com/google/android/mms/util_alt/DownloadDrmHelper.java @@ -18,10 +18,10 @@ package com.google.android.mms.util_alt; import android.content.Context; import android.drm.DrmManagerClient; -import com.klinker.android.logger.Log; +import timber.log.Timber; public class DownloadDrmHelper { - private static final String TAG = "DownloadDrmHelper"; + /** The MIME type of special DRM files */ public static final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message"; @@ -46,10 +46,9 @@ public class DownloadDrmHelper { result = drmClient.canHandle("", mimetype); } } catch (IllegalArgumentException e) { - Log.w(TAG, - "DrmManagerClient instance could not be created, context is Illegal."); + Timber.w("DrmManagerClient instance could not be created, context is Illegal."); } catch (IllegalStateException e) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); + Timber.w("DrmManagerClient didn't initialize properly."); } } return result; @@ -99,10 +98,9 @@ public class DownloadDrmHelper { result = drmClient.getOriginalMimeType(path); } } catch (IllegalArgumentException ex) { - Log.w(TAG, - "Can't get original mime type since path is null or empty string."); + Timber.w("Can't get original mime type since path is null or empty string."); } catch (IllegalStateException ex) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); + Timber.w("DrmManagerClient didn't initialize properly."); } return result; } diff --git a/android-smsmms/src/main/java/com/google/android/mms/util_alt/DrmConvertSession.java b/android-smsmms/src/main/java/com/google/android/mms/util_alt/DrmConvertSession.java index 0de09b1b7..3c38ed7fc 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/util_alt/DrmConvertSession.java +++ b/android-smsmms/src/main/java/com/google/android/mms/util_alt/DrmConvertSession.java @@ -18,7 +18,7 @@ package com.google.android.mms.util_alt; import android.content.Context; import android.drm.DrmConvertedStatus; import android.drm.DrmManagerClient; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.FileNotFoundException; import java.io.IOException; @@ -28,7 +28,6 @@ import java.io.RandomAccessFile; public class DrmConvertSession { private DrmManagerClient mDrmClient; private int mConvertSessionId; - private static final String TAG = "DrmConvertSession"; private static final int STATUS_UNKNOWN_ERROR = 491; private static final int STATUS_NOT_ACCEPTABLE = 406; @@ -56,16 +55,15 @@ public class DrmConvertSession { try { convertSessionId = drmClient.openConvertSession(mimeType); } catch (IllegalArgumentException e) { - Log.w(TAG, "Conversion of Mimetype: " + mimeType + Timber.w("Conversion of Mimetype: " + mimeType + " is not supported.", e); } catch (IllegalStateException e) { - Log.w(TAG, "Could not access Open DrmFramework.", e); + Timber.w(e, "Could not access Open DrmFramework."); } } catch (IllegalArgumentException e) { - Log.w(TAG, - "DrmManagerClient instance could not be created, context is Illegal."); + Timber.w("DrmManagerClient instance could not be created, context is Illegal."); } catch (IllegalStateException e) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); + Timber.w("DrmManagerClient didn't initialize properly."); } } @@ -102,10 +100,10 @@ public class DrmConvertSession { result = convertedStatus.convertedData; } } catch (IllegalArgumentException e) { - Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: " + Timber.w("Buffer with data to convert is illegal. Convertsession: " + mConvertSessionId, e); } catch (IllegalStateException e) { - Log.w(TAG, "Could not convert data. Convertsession: " + + Timber.w("Could not convert data. Convertsession: " + mConvertSessionId, e); } } else { @@ -143,15 +141,15 @@ public class DrmConvertSession { result = STATUS_SUCCESS; } catch (FileNotFoundException e) { result = STATUS_FILE_ERROR; - Log.w(TAG, "File: " + filename + " could not be found.", e); + Timber.w(e, "File: " + filename + " could not be found."); } catch (IOException e) { result = STATUS_FILE_ERROR; - Log.w(TAG, "Could not access File: " + filename + " .", e); + Timber.w(e, "Could not access File: " + filename + " ."); } catch (IllegalArgumentException e) { result = STATUS_FILE_ERROR; - Log.w(TAG, "Could not open file in mode: rw", e); + Timber.w(e, "Could not open file in mode: rw"); } catch (SecurityException e) { - Log.w(TAG, "Access to File: " + filename + + Timber.w("Access to File: " + filename + " was denied denied by SecurityManager.", e); } finally { if (rndAccessFile != null) { @@ -159,14 +157,14 @@ public class DrmConvertSession { rndAccessFile.close(); } catch (IOException e) { result = STATUS_FILE_ERROR; - Log.w(TAG, "Failed to close File:" + filename + Timber.w("Failed to close File:" + filename + ".", e); } } } } } catch (IllegalStateException e) { - Log.w(TAG, "Could not close convertsession. Convertsession: " + + Timber.w("Could not close convertsession. Convertsession: " + mConvertSessionId, e); } } diff --git a/android-smsmms/src/main/java/com/google/android/mms/util_alt/PduCache.java b/android-smsmms/src/main/java/com/google/android/mms/util_alt/PduCache.java index 878f91e76..d677ece90 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/util_alt/PduCache.java +++ b/android-smsmms/src/main/java/com/google/android/mms/util_alt/PduCache.java @@ -20,13 +20,13 @@ import android.content.ContentUris; import android.content.UriMatcher; import android.net.Uri; import android.provider.Telephony.Mms; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.util.HashMap; import java.util.HashSet; public final class PduCache extends AbstractCache { - private static final String TAG = "PduCache"; + private static final boolean LOCAL_LOGV = false; private static final int MMS_ALL = 0; @@ -82,7 +82,7 @@ public final class PduCache extends AbstractCache { synchronized public static final PduCache getInstance() { if (sInstance == null) { if (LOCAL_LOGV) { - Log.v(TAG, "Constructing new PduCache instance."); + Timber.v("Constructing new PduCache instance."); } sInstance = new PduCache(); } @@ -202,14 +202,14 @@ public final class PduCache extends AbstractCache { } if (LOCAL_LOGV) { - Log.v(TAG, uri + " -> " + normalizedKey); + Timber.v(uri + " -> " + normalizedKey); } return normalizedKey; } private void purgeByMessageBox(Integer msgBoxId) { if (LOCAL_LOGV) { - Log.v(TAG, "Purge cache in message box: " + msgBoxId); + Timber.v("Purge cache in message box: " + msgBoxId); } if (msgBoxId != null) { @@ -235,7 +235,7 @@ public final class PduCache extends AbstractCache { private void purgeByThreadId(long threadId) { if (LOCAL_LOGV) { - Log.v(TAG, "Purge cache in thread: " + threadId); + Timber.v("Purge cache in thread: " + threadId); } HashSet thread = mThreads.remove(threadId); diff --git a/android-smsmms/src/main/java/com/google/android/mms/util_alt/SqliteWrapper.java b/android-smsmms/src/main/java/com/google/android/mms/util_alt/SqliteWrapper.java index 823bac361..462cf468d 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/util_alt/SqliteWrapper.java +++ b/android-smsmms/src/main/java/com/google/android/mms/util_alt/SqliteWrapper.java @@ -24,10 +24,9 @@ import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.net.Uri; import android.widget.Toast; -import com.klinker.android.logger.Log; +import timber.log.Timber; public final class SqliteWrapper { - private static final String TAG = "SqliteWrapper"; private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE = "unable to open database file"; @@ -69,7 +68,7 @@ public final class SqliteWrapper { try { return resolver.query(uri, projection, selection, selectionArgs, sortOrder); } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when query: ", e); + Timber.e(e, "Catch a SQLiteException when query: "); checkSQLiteException(context, e); return null; } @@ -79,7 +78,7 @@ public final class SqliteWrapper { try { return cursor.requery(); } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when requery: ", e); + Timber.e(e, "Catch a SQLiteException when requery: "); checkSQLiteException(context, e); return false; } @@ -89,7 +88,7 @@ public final class SqliteWrapper { try { return resolver.update(uri, values, where, selectionArgs); } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when update: ", e); + Timber.e(e, "Catch a SQLiteException when update: "); checkSQLiteException(context, e); return -1; } @@ -100,7 +99,7 @@ public final class SqliteWrapper { try { return resolver.delete(uri, where, selectionArgs); } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when delete: ", e); + Timber.e(e, "Catch a SQLiteException when delete: "); checkSQLiteException(context, e); return -1; } @@ -111,7 +110,7 @@ public final class SqliteWrapper { try { return resolver.insert(uri, values); } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when insert: ", e); + Timber.e(e, "Catch a SQLiteException when insert: "); checkSQLiteException(context, e); return null; } diff --git a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedReceiver.java b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedReceiver.java index 2e57fbe5e..b8da3699a 100755 --- a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedReceiver.java +++ b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedReceiver.java @@ -23,7 +23,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.provider.Telephony; import android.telephony.SmsManager; -import android.util.Log; import com.android.mms.service_alt.DownloadRequest; import com.android.mms.service_alt.MmsConfig; import com.android.mms.transaction.DownloadManager; @@ -41,6 +40,7 @@ import com.google.android.mms.pdu_alt.PduParser; import com.google.android.mms.pdu_alt.PduPersister; import com.google.android.mms.pdu_alt.RetrieveConf; import com.google.android.mms.util_alt.SqliteWrapper; +import timber.log.Timber; import java.io.File; import java.io.FileInputStream; @@ -54,8 +54,6 @@ import java.util.concurrent.Executors; import static com.google.android.mms.pdu_alt.PduHeaders.STATUS_RETRIEVED; public class MmsReceivedReceiver extends BroadcastReceiver { - private static final String TAG = "MmsReceivedReceiver"; - public static final String MMS_RECEIVED = "com.klinker.android.messaging.MMS_RECEIVED"; public static final String EXTRA_FILE_PATH = "file_path"; public static final String EXTRA_LOCATION_URL = "location_url"; @@ -79,10 +77,10 @@ public class MmsReceivedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Log.v(TAG, "MMS has finished downloading, persisting it to the database"); + Timber.v("MMS has finished downloading, persisting it to the database"); String path = intent.getStringExtra(EXTRA_FILE_PATH); - Log.v(TAG, path); + Timber.v(path); FileInputStream reader = null; Uri messageUri = null; @@ -102,28 +100,28 @@ public class MmsReceivedReceiver extends BroadcastReceiver { intent.getStringExtra(EXTRA_LOCATION_URL), Utils.getDefaultSubscriptionId(), null); - Log.v(TAG, "response saved successfully"); - Log.v(TAG, "response length: " + response.length); + Timber.v("response saved successfully"); + Timber.v("response length: " + response.length); mDownloadFile.delete(); if (tasks != null) { - Log.v(TAG, "running the common async notifier for download"); + Timber.v("running the common async notifier for download"); for (CommonAsyncTask task : tasks) task.executeOnExecutor(RECEIVE_NOTIFICATION_EXECUTOR); } } catch (FileNotFoundException e) { errorMessage = "MMS received, file not found exception"; - Log.e(TAG, errorMessage, e); + Timber.e(e, errorMessage); } catch (IOException e) { errorMessage = "MMS received, io exception"; - Log.e(TAG, errorMessage, e); + Timber.e(e, errorMessage); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { errorMessage = "MMS received, io exception"; - Log.e(TAG, "MMS received, io exception", e); + Timber.e(e, "MMS received, io exception"); } } } @@ -275,7 +273,7 @@ public class MmsReceivedReceiver extends BroadcastReceiver { sendPdu(new PduComposer(mContext, notifyRespInd).make()); } } catch (MmsException | IOException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); } return null; } @@ -296,7 +294,7 @@ public class MmsReceivedReceiver extends BroadcastReceiver { // the MMS proxy-relay doesn't require an ACK. byte[] tranId = mRetrieveConf.getTransactionId(); if (tranId != null) { - Log.v(TAG, "sending ACK to MMSC: " + mTransactionSettings.getMmscUrl()); + Timber.v("sending ACK to MMSC: " + mTransactionSettings.getMmscUrl()); // Create M-Acknowledge.ind com.google.android.mms.pdu_alt.AcknowledgeInd acknowledgeInd; @@ -315,7 +313,7 @@ public class MmsReceivedReceiver extends BroadcastReceiver { sendPdu(new PduComposer(mContext, acknowledgeInd).make()); } } catch (IOException | MmsException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); } } return null; @@ -324,12 +322,12 @@ public class MmsReceivedReceiver extends BroadcastReceiver { private List getNotificationTask(Context context, Intent intent, byte[] response) { if (response.length == 0) { - Log.v(TAG, "MmsReceivedReceiver.sendNotification blank response"); + Timber.v("MmsReceivedReceiver.sendNotification blank response"); return null; } if (getMmscInfoForReceptionAck() == null) { - Log.v(TAG, "No MMSC information set, so no notification tasks will be able to complete"); + Timber.v("No MMSC information set, so no notification tasks will be able to complete"); return null; } @@ -337,7 +335,7 @@ public class MmsReceivedReceiver extends BroadcastReceiver { (new PduParser(response, new MmsConfig.Overridden(new MmsConfig(context), null). getSupportMmsContentDisposition())).parse(); if (pdu == null || !(pdu instanceof RetrieveConf)) { - android.util.Log.e(TAG, "MmsReceivedReceiver.sendNotification failed to parse pdu"); + Timber.e("MmsReceivedReceiver.sendNotification failed to parse pdu"); return null; } @@ -352,7 +350,7 @@ public class MmsReceivedReceiver extends BroadcastReceiver { return responseTasks; } catch (MmsException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); return null; } } diff --git a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java index ab4111efa..1fc398f0c 100755 --- a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java +++ b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java @@ -25,7 +25,7 @@ import com.google.android.mms.pdu_alt.PduParser; import com.google.android.mms.pdu_alt.PduPersister; import com.google.android.mms.pdu_alt.RetrieveConf; import com.google.android.mms.util_alt.SqliteWrapper; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.File; import java.io.FileInputStream; @@ -33,14 +33,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import static com.google.android.mms.pdu_alt.PduHeaders.STATUS_RETRIEVED; -import static com.klinker.android.send_message.MmsReceivedReceiver.EXTRA_FILE_PATH; -import static com.klinker.android.send_message.MmsReceivedReceiver.EXTRA_LOCATION_URL; -import static com.klinker.android.send_message.MmsReceivedReceiver.EXTRA_TRIGGER_PUSH; -import static com.klinker.android.send_message.MmsReceivedReceiver.EXTRA_URI; +import static com.klinker.android.send_message.MmsReceivedReceiver.*; public class MmsReceivedService extends IntentService { - private static final String TAG = "MmsReceivedService"; - private static final String LOCATION_SELECTION = Telephony.Mms.MESSAGE_TYPE + "=? AND " + Telephony.Mms.CONTENT_LOCATION + " =?"; @@ -54,10 +49,10 @@ public class MmsReceivedService extends IntentService { @Override protected void onHandleIntent(Intent intent) { - Log.v(TAG, "MMS has finished downloading, persisting it to the database"); + Timber.v("MMS has finished downloading, persisting it to the database"); String path = intent.getStringExtra(EXTRA_FILE_PATH); - Log.v(TAG, path); + Timber.v(path); FileInputStream reader = null; try { @@ -75,19 +70,19 @@ public class MmsReceivedService extends IntentService { intent.getStringExtra(EXTRA_LOCATION_URL), Utils.getDefaultSubscriptionId(), null); - Log.v(TAG, "response saved successfully"); - Log.v(TAG, "response length: " + response.length); + Timber.v("response saved successfully"); + Timber.v("response length: " + response.length); mDownloadFile.delete(); } catch (FileNotFoundException e) { - Log.e(TAG, "MMS received, file not found exception", e); + Timber.e(e, "MMS received, file not found exception"); } catch (IOException e) { - Log.e(TAG, "MMS received, io exception", e); + Timber.e(e, "MMS received, io exception"); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { - Log.e(TAG, "MMS received, io exception", e); + Timber.e(e, "MMS received, io exception"); } } @@ -228,7 +223,7 @@ public class MmsReceivedService extends IntentService { sendPdu(new PduComposer(mContext, notifyRespInd).make()); } } catch (MmsException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); } } } @@ -265,9 +260,9 @@ public class MmsReceivedService extends IntentService { sendPdu(new PduComposer(mContext, acknowledgeInd).make()); } } catch (InvalidHeaderValueException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); } catch (MmsException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); } } } @@ -278,15 +273,14 @@ public class MmsReceivedService extends IntentService { return null; } - final GenericPdu pdu = - (new PduParser(response, new MmsConfig.Overridden(new MmsConfig(context), null). - getSupportMmsContentDisposition())).parse(); - if (pdu == null || !(pdu instanceof RetrieveConf)) { - android.util.Log.e(TAG, "MmsReceivedReceiver.sendNotification failed to parse pdu"); + final GenericPdu pdu = (new PduParser(response, new MmsConfig.Overridden(new MmsConfig(context), null). + getSupportMmsContentDisposition())).parse(); + if (!(pdu instanceof RetrieveConf)) { + Timber.e("MmsReceivedReceiver.sendNotification failed to parse pdu"); return null; } - try { + try {Ω NotificationInd ind = getNotificationInd(context, intent); TransactionSettings transactionSettings = new TransactionSettings(context, null); if (intent.getBooleanExtra(EXTRA_TRIGGER_PUSH, false)) { @@ -295,7 +289,7 @@ public class MmsReceivedService extends IntentService { return new AcknowledgeIndTask(context, ind, transactionSettings, (RetrieveConf) pdu); } } catch (MmsException e) { - Log.e(TAG, "error", e); + Timber.e(e, "error"); return null; } } @@ -309,7 +303,7 @@ public class MmsReceivedService extends IntentService { // need retry ? task.run(); } catch (IOException e) { - Log.e(TAG, "MMS send received notification, io exception", e); + Timber.e(e, "MMS send received notification, io exception"); throw e; } } diff --git a/android-smsmms/src/main/java/com/klinker/android/send_message/Utils.java b/android-smsmms/src/main/java/com/klinker/android/send_message/Utils.java index c04508b06..2fc446932 100755 --- a/android-smsmms/src/main/java/com/klinker/android/send_message/Utils.java +++ b/android-smsmms/src/main/java/com/klinker/android/send_message/Utils.java @@ -17,7 +17,7 @@ import android.text.TextUtils; import com.android.mms.service_alt.MmsNetworkManager; import com.android.mms.service_alt.exception.MmsNetworkException; import com.google.android.mms.util_alt.SqliteWrapper; -import com.klinker.android.logger.Log; +import timber.log.Timber; import java.io.IOException; import java.lang.reflect.Method; @@ -39,7 +39,6 @@ public class Utils { * characters to compare against when checking for 160 character sending compatibility */ public static final String GSM_CHARACTERS_REGEX = "^[A-Za-z0-9 \\r\\n@Ł$ĽčéůěňÇŘřĹĺ\u0394_\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039EĆćßÉ!\"#$%&'()*+,\\-./:;<=>?ĄÄÖŃܧżäöńüŕ^{}\\\\\\[~\\]|\u20AC]*$"; - private static final String TAG = "Utils"; public static final int DEFAULT_SUBSCRIPTION_ID = 1; /** @@ -130,7 +129,7 @@ public class Utils { throw new IOException("Cannot establish route to proxy " + inetAddr); } } catch (Exception e) { - Log.e(TAG, "Cannot establishh route to proxy " + inetAddr, e); + Timber.e(e, "Cannot establishh route to proxy " + inetAddr); } } else { Uri uri = Uri.parse(url); @@ -145,7 +144,7 @@ public class Utils { throw new IOException("Cannot establish route to proxy " + inetAddr); } } catch (Exception e) { - Log.e(TAG, "Cannot establishh route to proxy " + inetAddr + " for " + url, e); + Timber.e(e, "Cannot establishh route to proxy " + inetAddr + " for " + url); } } } @@ -165,7 +164,7 @@ public class Utils { m.setAccessible(true); return (Boolean) m.invoke(cm); } catch (Exception e) { - Log.e(TAG, "exception thrown", e); + Timber.e(e, "exception thrown"); return null; } } @@ -181,7 +180,7 @@ public class Utils { Method m = c.getMethod("getDataEnabled"); return (boolean) m.invoke(telephonyManager); } catch (Exception e) { - Log.e(TAG, "exception thrown", e); + Timber.e(e, "exception thrown"); return true; } } @@ -198,7 +197,7 @@ public class Utils { Method m = c.getMethod("getDataEnabled", int.class); return (boolean) m.invoke(telephonyManager, subId); } catch (Exception e) { - Log.e(TAG, "exception thrown", e); + Timber.e(e, "exception thrown"); return isDataEnabled(telephonyManager); } } @@ -225,7 +224,7 @@ public class Utils { m.setAccessible(true); m.invoke(telephonyService, enabled); } catch (Exception e) { - Log.e(TAG, "error enabling data on lollipop", e); + Timber.e(e, "error enabling data on lollipop"); } } diff --git a/common/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java b/common/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java index 9d4f32be1..c49c8c768 100644 --- a/common/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java +++ b/common/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java @@ -4,9 +4,9 @@ package com.bumptech.glide.gifencoder; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; -import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import timber.log.Timber; import java.io.BufferedOutputStream; import java.io.FileOutputStream; @@ -14,7 +14,6 @@ import java.io.IOException; import java.io.OutputStream; public class AnimatedGifEncoder { - private static final String TAG = "AnimatedGifEncoder"; // The minimum % of an images pixels that must be transparent for us to set a transparent index // automatically. @@ -412,10 +411,7 @@ public class AnimatedGifEncoder { // Assume images with greater where more than n% of the pixels are transparent actually have // transparency. See issue #214. hasTransparentPixels = transparentPercentage > MIN_TRANSPARENT_PERCENTAGE; - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "got pixels for frame with " + transparentPercentage - + "% transparent pixels"); - } + Timber.d("got pixels for frame with " + transparentPercentage + "% transparent pixels"); } /** -- GitLab From 4520e1c138f0afd153add804760cb7cd5e8e4ed6 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Tue, 11 Jun 2019 10:06:24 -0400 Subject: [PATCH 017/178] Whoops --- .../com/klinker/android/send_message/MmsReceivedService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java index 1fc398f0c..5f206e4e4 100755 --- a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java +++ b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java @@ -280,7 +280,7 @@ public class MmsReceivedService extends IntentService { return null; } - try {Ω + try { NotificationInd ind = getNotificationInd(context, intent); TransactionSettings transactionSettings = new TransactionSettings(context, null); if (intent.getBooleanExtra(EXTRA_TRIGGER_PUSH, false)) { -- GitLab From 757545a9385e2fdce5d8665c45cef6f503112649 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Wed, 12 Jun 2019 11:04:23 -0400 Subject: [PATCH 018/178] Add crashlytics dependency --- .travis.yml | 7 ++++--- build.gradle | 1 + keystore.enc | Bin 3584 -> 0 bytes presentation/build.gradle | 3 +++ secrets.tar.enc | Bin 0 -> 9744 bytes 5 files changed, 8 insertions(+), 3 deletions(-) delete mode 100644 keystore.enc create mode 100644 secrets.tar.enc diff --git a/.travis.yml b/.travis.yml index 22ce00551..21a695675 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,8 +36,9 @@ android: # Set up Android-sdk and the emulator before_install: - # Decrypt keystore - - openssl aes-256-cbc -K $encrypted_4d1d940e2c65_key -iv $encrypted_4d1d940e2c65_iv -in keystore.enc -out keystore -d + # Decrypt keystore and google-services.json + - openssl aes-256-cbc -K $encrypted_4d1d940e2c65_key -iv $encrypted_4d1d940e2c65_iv -in secrets.tar.enc -out secrets.tar -d + - tar xvf secrets.tar - echo 'count=0' > /home/travis/.android/repositories.cfg # Avoid warning - ls -lar $HOME/**/* @@ -49,7 +50,7 @@ before_install: - yes | sdkmanager "platforms;android-${EMULATOR_API_LEVEL}" # Android platform required by emulator - yes | sdkmanager "platforms;android-${COMPILE_API_LEVEL}" # Android platform required by compiler - yes | sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" # Android build tools - - yes | sdkmanager "${EMULATOR}" # Install emulator system image + - yes | sdkmanager "${EMULATOR}" # Install emulator system image - sdkmanager --list || true # Print out package list for debug purposes # Run the emulator diff --git a/build.gradle b/build.gradle index 30b41283a..6e29944ac 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.4.1' + classpath 'com.google.gms:google-services:4.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "io.realm:realm-gradle-plugin:$realm_version" } diff --git a/keystore.enc b/keystore.enc deleted file mode 100644 index 89817b4dec6f8b8932dcd5a62d941fb725920592..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3584 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 literal 0 HcmV?d00001 -- GitLab From 24addd6641ad55d0551d653227bfd6724b26af2e Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Wed, 12 Jun 2019 11:31:58 -0400 Subject: [PATCH 019/178] Upgrade build tools version in travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 21a695675..8243fb383 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ env: - EMULATOR_TAG=default # Possible values are default, google_apis, android-tv, android-wear, android-wear-cn - EMULATOR_ABI=armeabi-v7a # Default is armeabi-v7a, possible options are: x86, x86_64, mips, arm64-v8a, armeabi-v7a. Note: check commit comment - EMULATOR_NAME=qksms3 - - ANDROID_BUILD_TOOLS_VERSION=27.0.2 # Match build-tools version used in build.gradle + - ANDROID_BUILD_TOOLS_VERSION=28.0.3 # Match build-tools version used in build.gradle - EMULATOR="system-images;android-${EMULATOR_API_LEVEL};${EMULATOR_TAG};${EMULATOR_ABI}" # Used to install/create emulator android: -- GitLab From 74268a2c9663dd8051ffb39d8df21e8b8f570597 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Fri, 14 Jun 2019 01:35:09 -0400 Subject: [PATCH 020/178] Add crashlytics crash reporting --- build.gradle | 3 ++ presentation/build.gradle | 10 ++++-- .../com/moez/QKSMS/common/QKApplication.kt | 7 ++-- .../moez/QKSMS/common/util/CrashlyticsTree.kt | 30 ++++++++++++++++ .../moez/QKSMS/common/util/CrashlyticsTree.kt | 32 ++++++++++++++++++ secrets.tar.enc | Bin 9744 -> 8208 bytes 6 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 presentation/src/noAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt create mode 100644 presentation/src/withAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt diff --git a/build.gradle b/build.gradle index 6e29944ac..6873f91c5 100644 --- a/build.gradle +++ b/build.gradle @@ -32,6 +32,7 @@ buildscript { ext.abiCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2] repositories { + maven { url 'https://maven.fabric.io/public' } maven { url 'https://maven.google.com' } jcenter() google() @@ -41,6 +42,7 @@ buildscript { classpath 'com.android.tools.build:gradle:3.4.1' classpath 'com.google.gms:google-services:4.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'io.fabric.tools:gradle:1.29.0' classpath "io.realm:realm-gradle-plugin:$realm_version" } } @@ -50,6 +52,7 @@ allprojects { google() jcenter() maven { url "https://jitpack.io" } + maven { url 'https://maven.fabric.io/public' } maven { url 'https://maven.google.com' } maven { name 'glide-snapshot' diff --git a/presentation/build.gradle b/presentation/build.gradle index b3bf8ce14..5372ac9aa 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -179,7 +179,6 @@ dependencies { implementation "com.bugsnag:bugsnag-android:4.1.1" implementation "com.github.chrisbanes:PhotoView:2.0.0" implementation "com.f2prateek.rx.preferences2:rx-preferences:$rx_preferences_version" - implementation 'com.google.firebase:firebase-core:16.0.9' implementation "com.google.android:flexbox:0.3.1" implementation "com.jakewharton.timber:timber:$timber_version" implementation "com.squareup.moshi:moshi:$moshi_version" @@ -189,10 +188,17 @@ dependencies { implementation project(":common") implementation project(':data') implementation project(':domain') + + withAnalyticsImplementation 'com.google.firebase:firebase-core:16.0.9' + withAnalyticsImplementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' + noAnalyticsDebug project(path: ':data', configuration: 'noAnalyticsDebug') noAnalyticsRelease project(path: ':data', configuration: 'noAnalyticsRelease') withAnalyticsDebug project(path: ':data', configuration: 'withAnalyticsDebug') withAnalyticsRelease project(path: ':data', configuration: 'withAnalyticsRelease') } -apply plugin: 'com.google.gms.google-services' +if (getGradle().getStartParameter().getTaskRequests().toString().contains("WithAnalytics")) { + apply plugin: 'io.fabric' + apply plugin: 'com.google.gms.google-services' +} diff --git a/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt b/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt index e6a2bdb78..4c1b8256b 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt @@ -31,6 +31,7 @@ import com.bugsnag.android.Configuration import com.moez.QKSMS.BuildConfig import com.moez.QKSMS.R import com.moez.QKSMS.common.util.BugsnagTree +import com.moez.QKSMS.common.util.CrashlyticsTree import com.moez.QKSMS.common.util.FileLoggingTree import com.moez.QKSMS.injection.AppComponentManager import com.moez.QKSMS.injection.appComponent @@ -71,8 +72,6 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn projectPackages = packages }) - RxJava2Debug.enableRxJava2AssemblyTracking() - Realm.init(this) Realm.setDefaultConfiguration(RealmConfiguration.Builder() .compactOnLaunch() @@ -97,7 +96,9 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn EmojiCompat.init(FontRequestEmojiCompatConfig(this, fontRequest)) - Timber.plant(Timber.DebugTree(), BugsnagTree(), fileLoggingTree) + Timber.plant(Timber.DebugTree(), BugsnagTree(), CrashlyticsTree(), fileLoggingTree) + + RxJava2Debug.enableRxJava2AssemblyTracking(arrayOf("com.moez.QKSMS")) } override fun activityInjector(): AndroidInjector { diff --git a/presentation/src/noAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt b/presentation/src/noAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt new file mode 100644 index 000000000..4b897e3de --- /dev/null +++ b/presentation/src/noAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.common.util + +import timber.log.Timber +import javax.inject.Inject + +class CrashlyticsTree : Timber.Tree() { + + override fun log(priority: Int, tag: String?, message: String?, throwable: Throwable?) { + // Do nothing for noAnalytics build flavor + } + +} diff --git a/presentation/src/withAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt b/presentation/src/withAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt new file mode 100644 index 000000000..5dcec3685 --- /dev/null +++ b/presentation/src/withAnalytics/java/com/moez/QKSMS/common/util/CrashlyticsTree.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.common.util + +import com.crashlytics.android.Crashlytics +import timber.log.Timber + +class CrashlyticsTree : Timber.Tree() { + + override fun log(priority: Int, tag: String?, message: String?, throwable: Throwable?) { + Crashlytics.log(message) + + throwable?.run(Crashlytics::logException) + } + +} diff --git a/secrets.tar.enc b/secrets.tar.enc index 124887a324666182870936f27f59fdf151f47457..35ec7e2a41fd55d371889a7165714576c7fb4506 100644 GIT binary patch literal 8208 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 literal 9744 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 -- GitLab From 274b217a56098b88d3bc96ef0427b0e29a2f88ec Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 17 Jun 2019 02:17:30 -0400 Subject: [PATCH 021/178] Show changelog after app update --- .../QKSMS/manager/ChangelogManagerImpl.kt | 49 ++++++++ .../java/com/moez/QKSMS/util/Preferences.kt | 1 + .../moez/QKSMS/manager/ChangelogManager.kt | 28 +++++ .../moez/QKSMS/common/util/TextViewStyler.kt | 10 ++ .../feature/changelog/ChangelogAdapter.kt | 54 +++++++++ .../feature/changelog/ChangelogDialog.kt | 55 +++++++++ .../moez/QKSMS/feature/main/MainActivity.kt | 7 ++ .../com/moez/QKSMS/feature/main/MainView.kt | 2 + .../moez/QKSMS/feature/main/MainViewModel.kt | 11 ++ .../com/moez/QKSMS/injection/AppModule.kt | 6 + .../src/main/res/layout/changelog_dialog.xml | 109 ++++++++++++++++++ .../main/res/layout/changelog_list_item.xml | 30 +++++ presentation/src/main/res/values/attrs.xml | 1 + .../src/main/res/values/donottranslate.xml | 32 ++++- 14 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 data/src/main/java/com/moez/QKSMS/manager/ChangelogManagerImpl.kt create mode 100644 domain/src/main/java/com/moez/QKSMS/manager/ChangelogManager.kt create mode 100644 presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogAdapter.kt create mode 100644 presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogDialog.kt create mode 100644 presentation/src/main/res/layout/changelog_dialog.xml create mode 100644 presentation/src/main/res/layout/changelog_list_item.xml diff --git a/data/src/main/java/com/moez/QKSMS/manager/ChangelogManagerImpl.kt b/data/src/main/java/com/moez/QKSMS/manager/ChangelogManagerImpl.kt new file mode 100644 index 000000000..d42336fae --- /dev/null +++ b/data/src/main/java/com/moez/QKSMS/manager/ChangelogManagerImpl.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.manager + +import android.content.Context +import com.moez.QKSMS.model.SyncLog +import com.moez.QKSMS.util.Preferences +import io.realm.Realm +import javax.inject.Inject + +class ChangelogManagerImpl @Inject constructor( + private val context: Context, + private val prefs: Preferences +) : ChangelogManager { + + override fun didUpdate(): Boolean { + val oldVersion = prefs.version.get() + val newVersion = context.packageManager.getPackageInfo(context.packageName, 0).versionCode + val lastSync = Realm.getDefaultInstance().use { realm -> realm.where(SyncLog::class.java)?.max("date") ?: 0 } + + if (oldVersion != newVersion) { + prefs.version.set(newVersion) + } + + return when { + oldVersion == 0 && lastSync != 0 -> true // Just updated to 3.6.5. TODO: Remove this after 3.6.5 + oldVersion == 0 -> false // First install + oldVersion != newVersion -> true // Update + else -> false + } + } + +} diff --git a/data/src/main/java/com/moez/QKSMS/util/Preferences.kt b/data/src/main/java/com/moez/QKSMS/util/Preferences.kt index f2ba12f0f..a13858f84 100644 --- a/data/src/main/java/com/moez/QKSMS/util/Preferences.kt +++ b/data/src/main/java/com/moez/QKSMS/util/Preferences.kt @@ -87,6 +87,7 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) val mobileOnly = rxPrefs.getBoolean("mobileOnly", false) val mmsSize = rxPrefs.getInteger("mmsSize", 300) val logging = rxPrefs.getBoolean("logging", false) + val version = rxPrefs.getInteger("version", 0) fun theme(threadId: Long = 0): Preference { val default = rxPrefs.getInteger("theme", 0xFF0097A7.toInt()) diff --git a/domain/src/main/java/com/moez/QKSMS/manager/ChangelogManager.kt b/domain/src/main/java/com/moez/QKSMS/manager/ChangelogManager.kt new file mode 100644 index 000000000..65cf0159f --- /dev/null +++ b/domain/src/main/java/com/moez/QKSMS/manager/ChangelogManager.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.manager + +interface ChangelogManager { + + /** + * Returns true if the app has benn updated since the last time this method was called + */ + fun didUpdate(): Boolean + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt b/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt index 92c14d5ab..4ad25a186 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt @@ -52,6 +52,7 @@ class TextViewStyler @Inject constructor( const val SIZE_SECONDARY = 1 const val SIZE_TERTIARY = 2 const val SIZE_TOOLBAR = 3 + const val SIZE_DIALOG = 4 fun applyEditModeAttributes(textView: TextView, attrs: AttributeSet?) { textView.run { @@ -89,6 +90,7 @@ class TextViewStyler @Inject constructor( SIZE_SECONDARY -> 14f SIZE_TERTIARY -> 12f SIZE_TOOLBAR -> 20f + SIZE_DIALOG -> 18f else -> textSize / paint.density } } @@ -177,6 +179,14 @@ class TextViewStyler @Inject constructor( Preferences.TEXT_SIZE_LARGER -> 26f else -> 20f } + + SIZE_DIALOG -> textView.textSize = when (textSizePref) { + Preferences.TEXT_SIZE_SMALL -> 16f + Preferences.TEXT_SIZE_NORMAL -> 18f + Preferences.TEXT_SIZE_LARGE -> 20f + Preferences.TEXT_SIZE_LARGER -> 24f + else -> 18f + } } } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogAdapter.kt new file mode 100644 index 000000000..27714c93f --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogAdapter.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.feature.changelog + +import android.graphics.Typeface +import android.view.LayoutInflater +import android.view.ViewGroup +import com.moez.QKSMS.R +import com.moez.QKSMS.common.base.QkAdapter +import com.moez.QKSMS.common.base.QkViewHolder +import kotlinx.android.synthetic.main.changelog_list_item.* + +class ChangelogAdapter(val keywords: List, data: List) : QkAdapter() { + + init { + this.data = data + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QkViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.changelog_list_item, parent, false) + return QkViewHolder(view).apply { + if (viewType == 0) { + changelogItem.setTypeface(changelogItem.typeface, Typeface.BOLD) + } + } + } + + override fun onBindViewHolder(holder: QkViewHolder, position: Int) { + val item = getItem(position) + + holder.changelogItem.text = item + } + + override fun getItemViewType(position: Int): Int { + return if (getItem(position) in keywords) 0 else 1 + } + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogDialog.kt b/presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogDialog.kt new file mode 100644 index 000000000..5df7077cf --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/changelog/ChangelogDialog.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.feature.changelog + +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import com.moez.QKSMS.BuildConfig +import com.moez.QKSMS.R +import com.moez.QKSMS.feature.main.MainActivity +import io.reactivex.subjects.PublishSubject +import io.reactivex.subjects.Subject +import kotlinx.android.synthetic.main.changelog_dialog.view.* + +class ChangelogDialog(activity: MainActivity) { + + val moreClicks: Subject = PublishSubject.create() + + private val dialog: AlertDialog + private val adapter = ChangelogAdapter( + activity.resources.getStringArray(R.array.changelog_keywords).asList(), + activity.resources.getStringArray(R.array.changelog).asList()) + + init { + val layout = LayoutInflater.from(activity).inflate(R.layout.changelog_dialog, null) + + dialog = AlertDialog.Builder(activity) + .setCancelable(true) + .setView(layout) + .create() + + layout.version.text = activity.getString(R.string.changelog_version, BuildConfig.VERSION_NAME) + layout.changelog.adapter = adapter + layout.more.setOnClickListener { dialog.dismiss(); moreClicks.onNext(Unit) } + layout.dismiss.setOnClickListener { dialog.dismiss() } + } + + fun show() = dialog.show() + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt index 5bf9728b5..3d58ec996 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt @@ -52,6 +52,7 @@ import com.moez.QKSMS.common.util.extensions.scrapViews import com.moez.QKSMS.common.util.extensions.setBackgroundTint import com.moez.QKSMS.common.util.extensions.setTint import com.moez.QKSMS.common.util.extensions.setVisible +import com.moez.QKSMS.feature.changelog.ChangelogDialog import com.moez.QKSMS.feature.conversations.ConversationItemTouchCallback import com.moez.QKSMS.feature.conversations.ConversationsAdapter import com.moez.QKSMS.repository.SyncRepository @@ -105,6 +106,7 @@ class MainActivity : QkThemedActivity(), MainView { override val conversationsSelectedIntent by lazy { conversationsAdapter.selectionChanges } override val confirmDeleteIntent: Subject> = PublishSubject.create() override val swipeConversationIntent by lazy { itemTouchCallback.swipes } + override val changelogMoreIntent by lazy { changelog.moreClicks } override val undoArchiveIntent: Subject = PublishSubject.create() override val snackbarButtonIntent: Subject = PublishSubject.create() override val backPressedIntent: Subject = PublishSubject.create() @@ -113,6 +115,7 @@ class MainActivity : QkThemedActivity(), MainView { private val toggle by lazy { ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.main_drawer_open_cd, 0) } private val itemTouchHelper by lazy { ItemTouchHelper(itemTouchCallback) } private val progressAnimator by lazy { ObjectAnimator.ofInt(syncingProgress, "progress", 0, 0) } + private val changelog by lazy { ChangelogDialog(this) } private val archiveSnackbar by lazy { Snackbar.make(drawerLayout, R.string.toast_archived, Snackbar.LENGTH_LONG).apply { setAction(R.string.button_undo) { undoArchiveIntent.onNext(Unit) } @@ -344,6 +347,10 @@ class MainActivity : QkThemedActivity(), MainView { .show() } + override fun showChangelog() { + changelog.show() + } + override fun showArchivedSnackbar() { archiveSnackbar.show() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt index f14d9f5b0..fb4f8a260 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt @@ -36,6 +36,7 @@ interface MainView : QkView { val conversationsSelectedIntent: Observable> val confirmDeleteIntent: Observable> val swipeConversationIntent: Observable> + val changelogMoreIntent: Observable<*> val undoArchiveIntent: Observable val snackbarButtonIntent: Observable val backPressedIntent: Observable @@ -44,6 +45,7 @@ interface MainView : QkView { fun clearSearch() fun clearSelection() fun showDeleteDialog(conversations: List) + fun showChangelog() fun showArchivedSnackbar() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index 255930f41..0c22bb394 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -36,6 +36,7 @@ import com.moez.QKSMS.interactor.MarkUnpinned import com.moez.QKSMS.interactor.MarkUnread import com.moez.QKSMS.interactor.MigratePreferences import com.moez.QKSMS.interactor.SyncMessages +import com.moez.QKSMS.manager.ChangelogManager import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.manager.RatingManager import com.moez.QKSMS.model.SyncLog @@ -57,6 +58,7 @@ class MainViewModel @Inject constructor( markAllSeen: MarkAllSeen, migratePreferences: MigratePreferences, syncRepository: SyncRepository, + private val changelogManager: ChangelogManager, private val conversationRepo: ConversationRepository, private val deleteConversations: DeleteConversations, private val markArchived: MarkArchived, @@ -141,6 +143,15 @@ class MainViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe { syncMessages.execute(Unit) } + // Show changelog + if (changelogManager.didUpdate()) { + view.showChangelog() + } + + view.changelogMoreIntent + .autoDisposable(view.scope()) + .subscribe { navigator.showChangelog() } + view.queryChangedIntent .debounce(200, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) diff --git a/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt b/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt index 1bfa652f9..a4a3798c2 100644 --- a/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt +++ b/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt @@ -1,3 +1,4 @@ + /* * Copyright (C) 2017 Moez Bhatti * @@ -37,6 +38,8 @@ import com.moez.QKSMS.manager.AlarmManager import com.moez.QKSMS.manager.AlarmManagerImpl import com.moez.QKSMS.manager.AnalyticsManager import com.moez.QKSMS.manager.AnalyticsManagerImpl +import com.moez.QKSMS.manager.ChangelogManager +import com.moez.QKSMS.manager.ChangelogManagerImpl import com.moez.QKSMS.manager.ExternalBlockingManager import com.moez.QKSMS.manager.ExternalBlockingManagerImpl import com.moez.QKSMS.manager.KeyManager @@ -125,6 +128,9 @@ class AppModule(private var application: Application) { @Provides fun externalBlockingManager(manager: ExternalBlockingManagerImpl): ExternalBlockingManager = manager + @Provides + fun changelogManager(manager: ChangelogManagerImpl): ChangelogManager = manager + @Provides fun provideKeyManager(manager: KeyManagerImpl): KeyManager = manager diff --git a/presentation/src/main/res/layout/changelog_dialog.xml b/presentation/src/main/res/layout/changelog_dialog.xml new file mode 100644 index 000000000..f05958852 --- /dev/null +++ b/presentation/src/main/res/layout/changelog_dialog.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/layout/changelog_list_item.xml b/presentation/src/main/res/layout/changelog_list_item.xml new file mode 100644 index 000000000..d681a175c --- /dev/null +++ b/presentation/src/main/res/layout/changelog_list_item.xml @@ -0,0 +1,30 @@ + + + diff --git a/presentation/src/main/res/values/attrs.xml b/presentation/src/main/res/values/attrs.xml index 9677ad8f1..e7c7b7e7d 100644 --- a/presentation/src/main/res/values/attrs.xml +++ b/presentation/src/main/res/values/attrs.xml @@ -34,6 +34,7 @@ + diff --git a/presentation/src/main/res/values/donottranslate.xml b/presentation/src/main/res/values/donottranslate.xml index 6b164ce2e..8cdfb1eee 100644 --- a/presentation/src/main/res/values/donottranslate.xml +++ b/presentation/src/main/res/values/donottranslate.xml @@ -30,4 +30,34 @@ GNU General Public License v3.0 © 2014–2018 - \ No newline at end of file + New in QKSMS + Version %s + + Added + Improved + Fixed + + + Added + - Support for latest version of Should I Answer + - New swipe action to mark a conversation unread + - Updates will now show a changelog! + + Improved + - Added unread indicator to make those conversations easier to spot + - Better support for sharing text from other apps + - Should I Answer integration will respect numbers that you have manually blocked + - Status bar for dark theme will match toolbar + - Make sure to ask to be default SMS app before attempting to perform actions that require it + - Features on QKSMS+ page will now link to their respective parts of the app + - Long list of names for group chat will be shortened + + Fixed + - Messages sometimes get stuck "Sending…" + - QK Reply window glitches when it\'s too big + - Crash in compose screen when a contact has no numbers + + More + Dismiss + + -- GitLab From c8441d56f93bb4b9da3ae01dfee43b93f80b553f Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 17 Jun 2019 11:05:11 -0400 Subject: [PATCH 022/178] Add spacing above changelog version --- presentation/src/main/res/layout/changelog_dialog.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/presentation/src/main/res/layout/changelog_dialog.xml b/presentation/src/main/res/layout/changelog_dialog.xml index f05958852..d0c4e556c 100644 --- a/presentation/src/main/res/layout/changelog_dialog.xml +++ b/presentation/src/main/res/layout/changelog_dialog.xml @@ -44,6 +44,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="24dp" + android:layout_marginTop="4dp" android:layout_marginEnd="24dp" app:layout_constraintBottom_toTopOf="@id/changelog" app:layout_constraintTop_toBottomOf="@id/title" -- GitLab From 3a0bd2f17f512765298fd9b9c5491f7348b720eb Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 17 Jun 2019 11:11:17 -0400 Subject: [PATCH 023/178] Update translations --- .../src/main/res/values-ar/strings.xml | 1 + .../src/main/res/values-bn/strings.xml | 1 + .../src/main/res/values-cs/strings.xml | 1 + .../src/main/res/values-da/strings.xml | 1 + .../src/main/res/values-de/strings.xml | 1 + .../src/main/res/values-es/strings.xml | 1 + .../src/main/res/values-fa/strings.xml | 1 + .../src/main/res/values-fi/strings.xml | 1 + .../src/main/res/values-fr/strings.xml | 1 + .../src/main/res/values-hi/strings.xml | 235 ++++----- .../src/main/res/values-hr/strings.xml | 1 + .../src/main/res/values-hu/strings.xml | 1 + .../src/main/res/values-in/strings.xml | 1 + .../src/main/res/values-it/strings.xml | 3 +- .../src/main/res/values-iw/strings.xml | 1 + .../src/main/res/values-ja/strings.xml | 3 +- .../src/main/res/values-ko/strings.xml | 1 + .../src/main/res/values-lt/strings.xml | 1 + .../src/main/res/values-ne/strings.xml | 1 + .../src/main/res/values-nl/strings.xml | 1 + .../src/main/res/values-no/strings.xml | 449 +++++++++--------- .../src/main/res/values-pl/strings.xml | 1 + .../src/main/res/values-pt-rBR/strings.xml | 1 + .../src/main/res/values-pt/strings.xml | 1 + .../src/main/res/values-ro/strings.xml | 1 + .../src/main/res/values-ru/strings.xml | 1 + .../src/main/res/values-sk/strings.xml | 1 + .../src/main/res/values-sr/strings.xml | 1 + .../src/main/res/values-sv/strings.xml | 1 + .../src/main/res/values-th/strings.xml | 1 + .../src/main/res/values-tl/strings.xml | 1 + .../src/main/res/values-tr/strings.xml | 1 + .../src/main/res/values-uk/strings.xml | 1 + .../src/main/res/values-ur/strings.xml | 1 + .../src/main/res/values-vi/strings.xml | 1 + .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh/strings.xml | 1 + 37 files changed, 380 insertions(+), 343 deletions(-) diff --git a/presentation/src/main/res/values-ar/strings.xml b/presentation/src/main/res/values-ar/strings.xml index 491b75e40..8c9f2ba6a 100644 --- a/presentation/src/main/res/values-ar/strings.xml +++ b/presentation/src/main/res/values-ar/strings.xml @@ -225,6 +225,7 @@ حذف مكالمة تعليمها مقروءة + Mark unread تأكيدات الإستلام تأكيد أنه تم إرسال الرسائل بنجاح diff --git a/presentation/src/main/res/values-bn/strings.xml b/presentation/src/main/res/values-bn/strings.xml index 9da0e0c57..c46be6d39 100644 --- a/presentation/src/main/res/values-bn/strings.xml +++ b/presentation/src/main/res/values-bn/strings.xml @@ -217,6 +217,7 @@ মুছে ফেলুন কল পঠিত হিসেবে চিহ্নিত করুন + Mark unread ডেলিভারি নিশ্চিতকরন নিশ্চিত করুন যে বার্তা সফলভাবে পাঠানো হয়েছে diff --git a/presentation/src/main/res/values-cs/strings.xml b/presentation/src/main/res/values-cs/strings.xml index 7126480ec..e903e3084 100644 --- a/presentation/src/main/res/values-cs/strings.xml +++ b/presentation/src/main/res/values-cs/strings.xml @@ -221,6 +221,7 @@ Smazat Volat Přečteno + Označit jako nepřečtené Potvrzení o doručení Potvrdit, že zprávy byly odeslány úspěšně diff --git a/presentation/src/main/res/values-da/strings.xml b/presentation/src/main/res/values-da/strings.xml index 9ac4bd6f0..97c288609 100644 --- a/presentation/src/main/res/values-da/strings.xml +++ b/presentation/src/main/res/values-da/strings.xml @@ -217,6 +217,7 @@ Slet Ring op Markér som læst + Markér som ulæst Leveringskvitteringer Bekræft, at SMS\'er er afsendt korrekt diff --git a/presentation/src/main/res/values-de/strings.xml b/presentation/src/main/res/values-de/strings.xml index a7fce6a13..0bbd0027c 100644 --- a/presentation/src/main/res/values-de/strings.xml +++ b/presentation/src/main/res/values-de/strings.xml @@ -217,6 +217,7 @@ Löschen Anrufen Als gelesen markieren + Einstellung Streichbewegung Zustellbestätigungen Bestätigung, dass Nachrichten erfolgreich gesendet wurden diff --git a/presentation/src/main/res/values-es/strings.xml b/presentation/src/main/res/values-es/strings.xml index 50d65361f..48a376160 100644 --- a/presentation/src/main/res/values-es/strings.xml +++ b/presentation/src/main/res/values-es/strings.xml @@ -217,6 +217,7 @@ Eliminar Llamar Marcar como leído + Mark unread Confirmaciones de envió Confirmar cuando los mensajes se envien con éxito diff --git a/presentation/src/main/res/values-fa/strings.xml b/presentation/src/main/res/values-fa/strings.xml index aa6d7b1a5..3fdf4a4a1 100644 --- a/presentation/src/main/res/values-fa/strings.xml +++ b/presentation/src/main/res/values-fa/strings.xml @@ -217,6 +217,7 @@ پاک کردن تماس خوانده شده + Mark unread تأیید تحویل تأیید ارسال موفق پیام diff --git a/presentation/src/main/res/values-fi/strings.xml b/presentation/src/main/res/values-fi/strings.xml index 60f871f96..7c9077407 100644 --- a/presentation/src/main/res/values-fi/strings.xml +++ b/presentation/src/main/res/values-fi/strings.xml @@ -217,6 +217,7 @@ Delete Call Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-fr/strings.xml b/presentation/src/main/res/values-fr/strings.xml index 83efb7e95..2b5ff73ec 100644 --- a/presentation/src/main/res/values-fr/strings.xml +++ b/presentation/src/main/res/values-fr/strings.xml @@ -217,6 +217,7 @@ Supprimer Appeler Marquer comme lu + Marquer comme non-lu Accusés de réception Demander un accusé de réception pour chaque SMS envoyé diff --git a/presentation/src/main/res/values-hi/strings.xml b/presentation/src/main/res/values-hi/strings.xml index 1e344aba7..7ebab8da1 100644 --- a/presentation/src/main/res/values-hi/strings.xml +++ b/presentation/src/main/res/values-hi/strings.xml @@ -19,9 +19,9 @@ ~ along with QKSMS. If not, see . --> - New conversation - Compose - Shortcut disabled + नई बातचीत + रचना + शॉर्टकट अक्षम किया गया संग्रहीत सेटिंग्स सूचनाएं @@ -39,110 +39,110 @@ संग्रह असंग्रहित हटाएँ - Pin to top - Unpin + शीर्ष पर पिन करें + अनपिन पढ़ा हुआ चिह्नित करें अपठित चिह्नित करें ब्लॉक संदेशों को सिंक्रनाइज़ कर रहा है.. । - You: %s - Results in messages - %d messages - Your conversations will appear here - No results - Your archived conversations will appear here - Start new conversation - Love texting again - Make QKSMS your default SMS app - Change - Permission required - QKSMS needs permission to send and view SMS messages - QKSMS needs permission to view your contacts - Allow - Inbox - Archived - Scheduled - Blocking - More - Settings - QKSMS+ - Help & feedback - Invite friends - QKSMS+ - Unlock amazing new features, and support development - Enjoying QKSMS? - Share some love and rate us on Google Play! - OKAY! - DISMISS - Delete + आप: %s + संदेशों में परिणाम + %d संदेश + आपकी बातचीत यहां दिखाई देगी + कोई परिणाम नहीं + आपके संग्रहीत वार्तालाप यहां दिखाई देंगे + नई वार्तालाप प्रारंभ करें + फिर से टेक्स्टिंग करिये + QKSMS अपना डिफ़ॉल्ट SMS एप्लिकेशन बनाएं + बदलें + अनुमति आवश्यक + QKSMS भेजने और एसएमएस संदेश देखने के लिए अनुमति की जरूरत है + QKSMS अपने संपर्कों को देखने के लिए अनुमति की जरूरत है + अनुमति दे + इनबॉक्स + संग्रहीत + अनुसूचित + अवरुद्ध + और + सेटिंग्स + QKSMS + + मदद और प्रतिक्रिया + मित्रों को आमंत्रित करें + QKSMS + + अद्भुत नई सुविधाओं को अनलॉक करें, और विकास का समर्थन करें + QKSMS का आनंद ले रहे? + कुछ प्यार साझा करें और गूगल प्ले पर हमें मूल्यांकन करें + ठीक! + खारिज + हटाएँ - Are you sure you would like to delete this conversation? - Are you sure you would like to delete %d conversations? + क्या आप वाकई इस वार्तालाप को हटाना चाहते हैं? + क्या आप वाकई %d वार्तालापों को हटाना चाहते हैं? - Copy text - Forward - Delete + पाठ की प्रतिलिपि बनाएं + अग्रेषित करें + मिटाएँ - %d selected - %1$d of %2$d results - Send as group message - Recipients and replies will be visible to everyone - This is the start of your conversation. Say something nice! - Contact card - Scheduled for - Selected time must be in the future! - You must unlock QKSMS+ to use scheduled messaging - Added to scheduled messages - Write a message… - Copy text - Forward - Delete - Previous - Next - Clear - Message details - Type: %s - From: %s - To: %s - Subject: %s - Priority: %s - Size: %s - Sent: %s - Received: %s - Delivered: %s - Error code: %d + %d चयनित + %1$d के %2$d परिणाम + समूह संदेश के रूप में भेजें + प्राप्तकर्ता और उत्तर सभी को दिखाई देंगे + यह आपकी बातचीत की शुरुआत है । कुछ अच्छा कहिये! + संपर्क कार्ड + के लिए निर्धारित + चयनित समय भविष्य में होना चाहिए! + आप QKSMS + अनुसूचित संदेश का उपयोग करने के लिए अनलॉक करना होगा + अनुसूचित संदेशों में जोड़ा गया + संदेश लिखें + पाठ की प्रतिलिपि बनाएं + आगे + मिटायें + पिछला + अगला + साफ करें + संदेश विवरण + टाइप %s + से: %s + को: %s + विषय: %s + महत्व: %s + आकार: %s + भेजा गया: %s + प्राप्त: %s + वितरित: %s + त्रुटि संकेत: %d Add an attachment - Attach a photo - Take a photo - Schedule message + चित्र संलग्न करें + चित्र खिंचे + संदेश अनुसूचित करें Attach a contact Error reading contact %s selected, change SIM card - Send message - Sending… - Delivered %s - Failed to send. Tap to try again - Details + संदेश भेजें + भेज रहा है… + %s वितरित + भेजने में असफल। पुनः प्रयास करें + विवरण Conversation title Enter title - Notifications + अधिसूचनाएँ Theme - Archive + संग्रह Unarchive - Block + अवरुदध करें Unblock - Delete conversation + वार्तालाप मिटाऐं Couldn\'t load media Saved to gallery Backup and restore Backing up messages Restoring from backup - Last backup - Loading… - Never + पिछला बेकप + लोड हो रहा है... + कभी नहीं Restore - Select a backup + किसी बैकअप का चयन करें Please unlock QKSMS+ to use backup and restore Backup in progress… Restore in progress… @@ -150,39 +150,39 @@ Are you sure you would like to restore your messages from this backup? Stop restore Messages that have already been restored will remain on your device - Backups - No backups found + बैकअप + कोई बैकअप नहीं मिला - %d message - %d messages + %d संदेश + %d संदेशें - Currently, only SMS is supported by Backup and Restore. MMS support and scheduled backups will be coming soon! - Backup now - Parsing backup… - %d/%d messages - Saving backup… - Syncing messages… - Finished! - Backup and restore - Scheduled - Automatically send a message, at the exact moment you\'d like - Hey! When was your birthday again? - It\'s on December 23rd - Happy birthday! Look at what a great friend I am, remembering your birthday - Sending on December 23rd  - Schedule a message - Scheduled message + वर्तमान में, केवल एसएमएस बैकअप और बहाल द्वारा समर्थित है| एमएमएस समर्थन और अनुसूचित बैकअप जल्द ही आ रहा है! + अभी बैकअप लें + बैकअप पदच्छेद हो रहा है... + %d/%d संदेशें + बैकअप सहेजा जा रहा है... + संदेश सिंक्रनाइज़ हो रहा है... + समाप्त! + बैकअप और पुनर्स्थापना + अनुसूचित + स्वचालित रूप से एक संदेश भेजें, जिस समय आप चाहते हैं + सुनो! आपका जन्मदिन कब था? + यह 23 दिसंबर को था + जन्मदिन की शुभकामनाएं! देखो, मैं कौन सा मित्र हूं, तुम्हारा जन्मदिन याद कर रहा हूं + 23 दिसंबर को भेजा जा रहा है  + एक संदेश अनुसूचित करें + निर्धारित संदेश - Send now - Delete + अभी भेजें + मिटायें - Appearance - General - QK Reply - Theme - Night mode - Pure black night mode - Start time + दिखावट + सामान्य + QK उत्तर + थीम + रात्रि अंदाज़ + शुद्ध काली रात अंदाज़ + शुरुआत समय End time Font size Use system font @@ -213,12 +213,13 @@ CHANGE None - Archive - Delete - Call + संग्रह + मिटायें + कॉल करें Mark read + Mark unread - Delivery confirmations + वितरण पुष्टि Confirm that messages were sent successfully Strip accents Remove accents from characters in outgoing SMS messages diff --git a/presentation/src/main/res/values-hr/strings.xml b/presentation/src/main/res/values-hr/strings.xml index 3f197de4b..d891c5211 100644 --- a/presentation/src/main/res/values-hr/strings.xml +++ b/presentation/src/main/res/values-hr/strings.xml @@ -219,6 +219,7 @@ Delete Call Mark read + Mark unread Potvrde o dostavi Budite sigurni da su se poruke uspješno poslale diff --git a/presentation/src/main/res/values-hu/strings.xml b/presentation/src/main/res/values-hu/strings.xml index 74c5c1773..26a24e740 100644 --- a/presentation/src/main/res/values-hu/strings.xml +++ b/presentation/src/main/res/values-hu/strings.xml @@ -217,6 +217,7 @@ Törlés Hívás Megjelölés olvasottként + Mark unread Elküldés megerősítése Megerősíti, hogy az üzenetek sikeresen el lettek-e küldve diff --git a/presentation/src/main/res/values-in/strings.xml b/presentation/src/main/res/values-in/strings.xml index 91516be09..ccc750f9b 100644 --- a/presentation/src/main/res/values-in/strings.xml +++ b/presentation/src/main/res/values-in/strings.xml @@ -215,6 +215,7 @@ Hapus Panggil Tandai dibaca + Mark unread Konfirmasi pengiriman Mengonfirmasi bahwa pesan telah berhasil dikirim diff --git a/presentation/src/main/res/values-it/strings.xml b/presentation/src/main/res/values-it/strings.xml index 64b53c219..36fc14e60 100644 --- a/presentation/src/main/res/values-it/strings.xml +++ b/presentation/src/main/res/values-it/strings.xml @@ -26,7 +26,7 @@ Impostazioni Notifiche Tema - Cerca nei messaggi… + Cerca in posta in arrivo… Digita un nome o un numero Salta Continua @@ -217,6 +217,7 @@ Elimina Chiama Segna come letto + Segna come non letto Conferme di recapito Conferma che i messaggi siano stati inviati con successo diff --git a/presentation/src/main/res/values-iw/strings.xml b/presentation/src/main/res/values-iw/strings.xml index 052eaca95..9e024dc09 100644 --- a/presentation/src/main/res/values-iw/strings.xml +++ b/presentation/src/main/res/values-iw/strings.xml @@ -221,6 +221,7 @@ מחיקה התקשרות סימון כנקרא + סימון כלא נקרא אישור מסירה אישור שההודעות נשלחו בהצלחה diff --git a/presentation/src/main/res/values-ja/strings.xml b/presentation/src/main/res/values-ja/strings.xml index ad52ffb35..cf9bc9568 100644 --- a/presentation/src/main/res/values-ja/strings.xml +++ b/presentation/src/main/res/values-ja/strings.xml @@ -42,7 +42,7 @@ 上部に固定します。 固定を解除します。 既読にする - 未読にします。 + 未読にする ブロック 同期メッセージ… あなた: %s @@ -215,6 +215,7 @@ 削除 電話 既読にする + 未読にする 配信確認 メッセージが正常に送信されたことを確認します diff --git a/presentation/src/main/res/values-ko/strings.xml b/presentation/src/main/res/values-ko/strings.xml index 01feef233..f1e69ba32 100644 --- a/presentation/src/main/res/values-ko/strings.xml +++ b/presentation/src/main/res/values-ko/strings.xml @@ -217,6 +217,7 @@ 삭제 전화 읽음으로 표시 + Mark unread 전송 확인 전송 성공을 확인합니다 diff --git a/presentation/src/main/res/values-lt/strings.xml b/presentation/src/main/res/values-lt/strings.xml index c4f73a0be..8ad57e537 100644 --- a/presentation/src/main/res/values-lt/strings.xml +++ b/presentation/src/main/res/values-lt/strings.xml @@ -221,6 +221,7 @@ Delete Call Mark read + Mark unread Žinučių pristatymo patvirtinimai Patvirtinti, kad pranešimai buvo sėkmingai išsiųsti diff --git a/presentation/src/main/res/values-ne/strings.xml b/presentation/src/main/res/values-ne/strings.xml index c754c0943..8eceb6bbe 100644 --- a/presentation/src/main/res/values-ne/strings.xml +++ b/presentation/src/main/res/values-ne/strings.xml @@ -217,6 +217,7 @@ Delete Call Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-nl/strings.xml b/presentation/src/main/res/values-nl/strings.xml index e6b5e522f..be73edd99 100644 --- a/presentation/src/main/res/values-nl/strings.xml +++ b/presentation/src/main/res/values-nl/strings.xml @@ -217,6 +217,7 @@ Verwijderen Bellen Markeer als gelezen + Mark unread Afleverrapporten Bevestig dat berichten met succes zijn verzonden diff --git a/presentation/src/main/res/values-no/strings.xml b/presentation/src/main/res/values-no/strings.xml index 183ddb3d9..15fe250d9 100644 --- a/presentation/src/main/res/values-no/strings.xml +++ b/presentation/src/main/res/values-no/strings.xml @@ -19,15 +19,15 @@ ~ along with QKSMS. If not, see . --> - New conversation - Compose - Shortcut disabled + Ny samtale + Skriv + Snarvei deaktivert Arkivert Innstillinger Varsler Tema - Søk innboks… - Skriv inn et navn eller nummer + Søk i innboks … + Skriv navn eller nummer Hopp over Fortsett Ring @@ -39,8 +39,8 @@ Arkiv Fjern fra arkiv Slett - Pin to top - Unpin + Fest øverst + Løsne Marker som lest Marker som ulest Blokker @@ -67,103 +67,103 @@ Innstillinger QKSMS+ Hjelp og tilbakemelding - Invite friends + Inviter venner QKSMS+ - Lås opp fantastiske nye funksjoner, og støtt utvikling + Aktiver fantastiske nye funksjoner og støtt utviklingen Liker du QKSMS? Del litt kjærlighet og vurder oss på Google Play! - OK! - AVVIS + Ok! + Avvis Slett - Are you sure you would like to delete this conversation? - Are you sure you would like to delete %d conversations? + Er du sikker på at du vil slette samtalen? + Er du sikker på at du vil slette %d samtaler? Kopier tekst - Forward - Delete + Videresend + Slett - %d selected - %1$d of %2$d results - Send as group message - Recipients and replies will be visible to everyone - This is the start of your conversation. Say something nice! - Contact card - Scheduled for - Selected time must be in the future! - You must unlock QKSMS+ to use scheduled messaging - Added to scheduled messages - Write a message… - Copy text - Forward - Delete - Previous - Next - Clear - Message details + %d valgt + %1$d av %2$d funn + Send som gruppemelding + Mottakere og svar er synlig for alle + Nå starter samtalen. Si noe hyggelig! + Kontakt + Planlagt for + Valgt tid må være i fremtid. + Du må ha QKSMS+ for å kunne bruke planlagte meldinger + Lagt til planlagte meldinger + Skriv en melding + Kopier tekst + Videresend + Slett + Forrige + Neste + Tøm + Meldingsinformasjon Type: %s - From: %s - To: %s - Subject: %s - Priority: %s - Size: %s - Sent: %s - Received: %s - Delivered: %s - Error code: %d - Add an attachment - Attach a photo - Take a photo - Schedule message - Attach a contact - Error reading contact - %s selected, change SIM card - Send message - Sending… - Delivered %s - Failed to send. Tap to try again - Details - Conversation title - Enter title - Notifications - Theme - Archive - Unarchive - Block - Unblock - Delete conversation - Couldn\'t load media - Saved to gallery - Backup and restore - Backing up messages - Restoring from backup - Last backup - Loading… - Never - Restore - Select a backup - Please unlock QKSMS+ to use backup and restore - Backup in progress… - Restore in progress… - Restore from backup - Are you sure you would like to restore your messages from this backup? - Stop restore - Messages that have already been restored will remain on your device - Backups - No backups found + Fra: %s + Til: %s + Emne: %s + Prioritet: %s + Størrelse: %s + Sendt: %s + Mottatt: %s + Levert: %s + Feilkode: %d + Legg til vedlegg + Legg til bilde + Ta bilde + Planlegg melding + Legg til kontakt + Feil ved åpning av kontakt + %s er valgt, velg annet SIM-kort + Send melding + Sender … + Levert %s + Feil ved sending. Trykk for å prøve igjen + Detaljer + Tittel på samtalen + Legg inn tittel + Varsler + Drakt + Arkiv + Fjern fra arkiv + Blokker + Ta bort blokkering + Slett samtale + Media kunne ikke lastes + Lagret i galleriet + Sikkerhetskopiering og gjenoppretting + Sikkerhetskopierer meldinger + Gjenoppretter fra sikkerhetskopi + Siste sikkerhetskopi + Henter … + Aldri + Gjenopprett + Velg en sikkerhetskopi + Vennligst aktiver QKSMS+ for å bruke sikkerhetskopiering og gjenoppretting + Sikkerhetskopiering pågår … + Gjenoppretting pågår … + Gjenopprett fra sikkerhetskopi + Er du sikker på at du vil gjenopprette meldinger fra denne sikkerhetskopien? + Avbryt gjenoppretting + Meldinger som allerede er gjenopprettet vil forbli på din enhet + Sikkerhetskopier + Fant ingen sikkerhetskopier - %d message - %d messages + %d melding + %d meldinger - Currently, only SMS is supported by Backup and Restore. MMS support and scheduled backups will be coming soon! - Backup now - Parsing backup… - %d/%d messages - Saving backup… - Syncing messages… - Finished! - Backup and restore + Per idag er bare mulig å sikkerhetskopiere SMS. MMS og planlagte sikkerhetskopier kommer snart. + Sikkerhetskopier nå + Ser gjennom sikkerhetskopien … + %d/%d meldinger + Lagrer sikkerhetskopi … + Synkroniserer meldinger … + Ferdig! + Sikkerhetskopiering og gjenoppretting Planlagt Send automatisk en melding på det tidspunktet du ønsker Hei! Når var fødselsdagen din igjen? @@ -198,160 +198,161 @@ Lyd Ingen QK Svar - Popup for new messages - Tap to dismiss - Tap outside of the popup to close it - Blocking + Sprettopp-vindu ved nye meldinger + Trykk for å forkaste + Trykk hvor som helst utenfor sprettopp-vinduet for å lukke det + Blokkering - Should I Answer? - Automatically filter messages from unsolicited numbers by using the \"Should I Answer\" app - Delayed sending - Swipe actions - Configure swipe actions for conversations - Right swipe - Left swipe - CHANGE + Skal jeg svare? + Filtrer meldinger fra ukjente numre automatisk med \"Skal jeg svare\"-appen + Forsinket sending + Sveipe-handlinger + Still inn sveipe-handlinger for samtaler + Høyre-sveip + Venstre-sveip + Endring - None - Archive - Delete - Call - Mark read + Ingen + Arkivér + Slett + Ring + Marker som lest + Mark unread - Delivery confirmations - Confirm that messages were sent successfully - Strip accents - Remove accents from characters in outgoing SMS messages - Mobile numbers only - When composing a message, only show mobile numbers - Auto-compress MMS attachments - Sync messages - Re-sync your messages with the native Android SMS database - About QKSMS - Version %s - Debug logging enabled - Debug logging disabled - Enter duration (seconds) - Blocking - Your blocked conversations will appear here - Unblock - Would you like to unblock this conversation? - About - Version - Developer - Source code - Changelog - Contact - License - Copyright - Support development, unlock everything - You can save a starving developer for just %s - Lifetime upgrade for %1$s %2$s - Unlock + donate for %1$s %2$s - Thank you for supporting QKSMS! - You now have access to all QKSMS+ features - QKSMS+ is free for F-Droid users! If you\'d like to support development, feel free to make a donation. - Donate via PayPal - Coming soon - Premium themes - Unlock beautiful theme colors not available on the Material Design palette - Custom auto-emoji - Create custom auto-emoji shortcuts - Message backup - Automatically back up your messages. Never again worry about losing your history if you change phones or your phone gets lost - Scheduled messages - Schedule messages to automatically be sent at a specific time and date - Delayed sending - Wait a few seconds before sending your message - Automatic night mode - Enable night mode based on the time of day - Advanced blocking - Block messages that contain keywords or match patterns - Auto-forward - Automatically forward messages from certain senders - Auto-respond - Automatically respond to incoming messages with a preset response - More - QKSMS is under active development, and your purchase will include all future QKSMS+ features! - Loading… - View more conversations - Mark read - Call - Delete - Show more - Show less - Open conversation + Leveringsbekreftelse + Bekreft at melding ble sendt + Ta bort akutt-tegn + Ta bort akutt-tegn fra utgående meldinger + Kun mobilnummre + Vis kun mobilnummre når du skriver ny melding + Komprimer MMS-vedlegg + Synkroniser meldinger + Resynkroniser meldinger med Androids interne meldingslager + Om QKSMS + Versjon %s + Feillogg aktivert + Feillogg deaktivert + Legg inn forsinkelse (i sekunder) + Blokkert + Samtaler du blokkerer vil vises her + Ta bort blokkering + Vil du ta bort blokkering av denne samtalen? + Om + Versjon + Utvikler + Kildekode + Endringslogg + Kontakt + Lisens + Kopibeskyttelse + Støtt utviklingen, aktiver alle funksjoner + Du kan redde en sultende programmerer for bare %s + Oppdateringer på livstid for %1$s %2$s + Aktiver + donér for %1$s %2$s + Takk for at du støtter QKSMS! + Du har nå tilgang til alle funksjoner i QKSMS+ + QKSMS+ er gratis for F-Droid-brukere. Om du ønsker å støtte utviklingen, kan du gjerne donere. + Donér med PayPal + Kommer snart + Premium drakter + Aktiver vakre draktfarger som ikke er tilgjengelig i Material-design-paletten + Egne auto-emoji + Lag egne auto-emoji snarveier + Sikkerhetskopi av meldinger + Automatisk sikkerhetskopiering av dine meldinger. Slutt på bekymringer om å miste dine meldinger når du bytter telefon eller mister den + Planlagte meldinger + Planlegg at meldinger sendes automatisk ved en tid og dato + Forsinket sending + Vent noen sekunder før meldingen sendes + Automatisk nattmodus + Aktiver nattmodus basert på tid på døgnet + Avansert blokkering + Blokker meldinger som inneholder visse stikkord eller mønstre + Auto-videresend + Videresend meldinger fra gitte avsendere automatisk + Auto-svar + Svar på innkommende meldinger automatisk med et forhåndsdefinert svar + Mer + QKSMS er i stadig utvikling og ditt kjøp inkluderer alle fremtidige QKSMS+ funksjoner! + Laster inn … + Last inn flere samtaler + Marker som lest + Ring + Slett + Vis mer + Vis mindre + Åpne samtale Material QKSMS+ HEX - Apply + Bruk - None - Mark read - Reply - Call - Delete + Ingen + Marker som lest + Svar + Ring + Slett - Cancel - Delete - Save - Stop - More - Set - Unblock - Undo - Copied - Archived conversation - You must unlock QKSMS+ to use this + Avbryt + Slett + Lagre + Avbryt + Mer + Angi + Slipp inn + Angre + Kopiert + Arkiverte samtaler + Du må aktivere QKSMS+ for å bruke dette - New message - %s new messages + Ny melding + %s nye meldinger - Message not sent - The message to %s failed to send + Meldingen ble ikke sendt + Meldingen til %s kunne ikke sendes - Disabled - Always on - Automatic + Deaktivert + Alltid på + Automatisk - Show name and message - Show name - Hide contents + Vis navn og melding + Vis navn + Skjul innhold - Small + Liten Normal - Large - Larger + Stor + Større - No delay - Short - Medium - Long + Ingen forsinkelse + Kort + Middels + Lang - 100KB - 200KB - 300KB (Recommended) - 600KB - 1000KB - 2000KB - No compression + 100 KB + 200 KB + 300 KB (anbefalt) + 600 KB + 1000 KB + 2000 KB + Ingen komprimering - Okay - Give me a moment - On my way - Thanks - Sounds good - What\'s up? - Agreed - No - Love you - Sorry + Ok + Vent litt + Er på vei + Takk + Høres bra ut + Skjer\'a? + I orden + Nei + Glad i deg + Beklager LOL - That\'s okay + Det er greit diff --git a/presentation/src/main/res/values-pl/strings.xml b/presentation/src/main/res/values-pl/strings.xml index 0d9c635f8..f4c62f190 100644 --- a/presentation/src/main/res/values-pl/strings.xml +++ b/presentation/src/main/res/values-pl/strings.xml @@ -221,6 +221,7 @@ Usuń Zadzwoń Oznacz jako przeczytane + Mark unread Potwierdzenie dostarczenia Potwierdzaj dostarczenie każdej wysłanej wiadomości diff --git a/presentation/src/main/res/values-pt-rBR/strings.xml b/presentation/src/main/res/values-pt-rBR/strings.xml index 01cb0282e..0704f6748 100644 --- a/presentation/src/main/res/values-pt-rBR/strings.xml +++ b/presentation/src/main/res/values-pt-rBR/strings.xml @@ -217,6 +217,7 @@ Apagar Ligar Marcar como lida + Marcar como não lida Confirmações de entrega Confirma se as mensagens foram enviadas com sucesso diff --git a/presentation/src/main/res/values-pt/strings.xml b/presentation/src/main/res/values-pt/strings.xml index 724dfc15f..3825f2044 100644 --- a/presentation/src/main/res/values-pt/strings.xml +++ b/presentation/src/main/res/values-pt/strings.xml @@ -217,6 +217,7 @@ Apagar Ligar Marcar como lida + Marcar como não lida Confirmações de entrega Confirma se as mensagens foram enviadas com sucesso diff --git a/presentation/src/main/res/values-ro/strings.xml b/presentation/src/main/res/values-ro/strings.xml index 3cfb2bf5c..1dba4ac9d 100644 --- a/presentation/src/main/res/values-ro/strings.xml +++ b/presentation/src/main/res/values-ro/strings.xml @@ -219,6 +219,7 @@ Delete Call Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-ru/strings.xml b/presentation/src/main/res/values-ru/strings.xml index 4a5148224..353b55e96 100644 --- a/presentation/src/main/res/values-ru/strings.xml +++ b/presentation/src/main/res/values-ru/strings.xml @@ -221,6 +221,7 @@ Удалить Позвонить Отметить прочитанным + Пометить непрочитанным Отчёты о доставке Подтверждение успешной отправки сообщений diff --git a/presentation/src/main/res/values-sk/strings.xml b/presentation/src/main/res/values-sk/strings.xml index 5399274fa..2ec43b776 100644 --- a/presentation/src/main/res/values-sk/strings.xml +++ b/presentation/src/main/res/values-sk/strings.xml @@ -221,6 +221,7 @@ Odstrániť Zavolať Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-sr/strings.xml b/presentation/src/main/res/values-sr/strings.xml index a2e61274f..9619c9b59 100644 --- a/presentation/src/main/res/values-sr/strings.xml +++ b/presentation/src/main/res/values-sr/strings.xml @@ -219,6 +219,7 @@ Delete Call Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-sv/strings.xml b/presentation/src/main/res/values-sv/strings.xml index 12ea392e3..1303d5863 100644 --- a/presentation/src/main/res/values-sv/strings.xml +++ b/presentation/src/main/res/values-sv/strings.xml @@ -217,6 +217,7 @@ Ta bort Ring Markera som läst + Mark unread Leveransrapporter Bekräfta att meddelanden har skickats diff --git a/presentation/src/main/res/values-th/strings.xml b/presentation/src/main/res/values-th/strings.xml index 4bc242b68..12baa605c 100644 --- a/presentation/src/main/res/values-th/strings.xml +++ b/presentation/src/main/res/values-th/strings.xml @@ -215,6 +215,7 @@ Delete Call Mark read + Mark unread ยืนยันการส่ง ยืนยันว่า ส่งข้อความเรียบร้อยแล้ว diff --git a/presentation/src/main/res/values-tl/strings.xml b/presentation/src/main/res/values-tl/strings.xml index 2fdb80ddc..cd3c3e034 100644 --- a/presentation/src/main/res/values-tl/strings.xml +++ b/presentation/src/main/res/values-tl/strings.xml @@ -217,6 +217,7 @@ Delete Call Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-tr/strings.xml b/presentation/src/main/res/values-tr/strings.xml index 768cb8a0e..38dc41a4a 100644 --- a/presentation/src/main/res/values-tr/strings.xml +++ b/presentation/src/main/res/values-tr/strings.xml @@ -217,6 +217,7 @@ Sil Ara Okundu olarak işaretle + Okunmadı olarak işaretle İletim raporları Mesajınızın sorunsuz gönderildiğinin onayını alın diff --git a/presentation/src/main/res/values-uk/strings.xml b/presentation/src/main/res/values-uk/strings.xml index 48da75c73..81b834248 100644 --- a/presentation/src/main/res/values-uk/strings.xml +++ b/presentation/src/main/res/values-uk/strings.xml @@ -221,6 +221,7 @@ Видалити Виклик Позначити як прочитане + Позначити як непрочитане Звіти про доставку Підтвердження успішного надсилання повідомлень diff --git a/presentation/src/main/res/values-ur/strings.xml b/presentation/src/main/res/values-ur/strings.xml index 43cc89d7b..2e3e1ac95 100644 --- a/presentation/src/main/res/values-ur/strings.xml +++ b/presentation/src/main/res/values-ur/strings.xml @@ -217,6 +217,7 @@ Delete Call Mark read + Mark unread Delivery confirmations Confirm that messages were sent successfully diff --git a/presentation/src/main/res/values-vi/strings.xml b/presentation/src/main/res/values-vi/strings.xml index 380ab8d72..074b3ea92 100644 --- a/presentation/src/main/res/values-vi/strings.xml +++ b/presentation/src/main/res/values-vi/strings.xml @@ -215,6 +215,7 @@ Xoá Gọi điện Đánh dấu là đã đọc + Đánh dấu là chưa đọc Xác nhận đã gửi tin Xác nhận rằng các tin nhắn được gửi thành công diff --git a/presentation/src/main/res/values-zh-rCN/strings.xml b/presentation/src/main/res/values-zh-rCN/strings.xml index 6adc9074b..058e5a4a6 100644 --- a/presentation/src/main/res/values-zh-rCN/strings.xml +++ b/presentation/src/main/res/values-zh-rCN/strings.xml @@ -215,6 +215,7 @@ 删除 呼叫 标记为已读 + 标记为未读 送达确认 确认短信已成功送达 diff --git a/presentation/src/main/res/values-zh/strings.xml b/presentation/src/main/res/values-zh/strings.xml index 39783ccc6..9c5a252e1 100644 --- a/presentation/src/main/res/values-zh/strings.xml +++ b/presentation/src/main/res/values-zh/strings.xml @@ -215,6 +215,7 @@ Delete Call Mark read + Mark unread 送達確認 確認訊息已成功送達 -- GitLab From 363337a76c7be62aca750a17b33b477590124d76 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 17 Jun 2019 12:26:34 -0400 Subject: [PATCH 024/178] Increment to 3.6.5 --- presentation/build.gradle | 4 ++-- presentation/src/main/res/values/donottranslate.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/presentation/build.gradle b/presentation/build.gradle index 5372ac9aa..5cf3f95f6 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -31,8 +31,8 @@ android { applicationId "com.moez.QKSMS" minSdkVersion 21 targetSdkVersion 28 - versionCode 194 - versionName "3.6.4" + versionCode 195 + versionName "3.6.5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildConfigField "String", "BUGSNAG_API_KEY", "\"${System.getenv("BUGSNAG_API_KEY")}\"" diff --git a/presentation/src/main/res/values/donottranslate.xml b/presentation/src/main/res/values/donottranslate.xml index 8cdfb1eee..e1518db82 100644 --- a/presentation/src/main/res/values/donottranslate.xml +++ b/presentation/src/main/res/values/donottranslate.xml @@ -48,7 +48,7 @@ - Better support for sharing text from other apps - Should I Answer integration will respect numbers that you have manually blocked - Status bar for dark theme will match toolbar - - Make sure to ask to be default SMS app before attempting to perform actions that require it + - QKSMS will ask to be default SMS app instead if trying to perform actions that it doesn\'t have permission to do - Features on QKSMS+ page will now link to their respective parts of the app - Long list of names for group chat will be shortened -- GitLab From 4494f3f39d4e4fd07843efd9e48da6f60964d8c7 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Tue, 18 Jun 2019 18:24:04 -0400 Subject: [PATCH 025/178] Fix crash when a single comma doesn't fit in collapsed textview --- .../java/com/moez/QKSMS/common/widget/QkTextView.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt index b8aa92560..bc771a1cf 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/QkTextView.kt @@ -25,8 +25,9 @@ import com.moez.QKSMS.common.util.TextViewStyler import com.moez.QKSMS.injection.appComponent import javax.inject.Inject -open class QkTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) - : EmojiAppCompatTextView(context, attrs) { +open class QkTextView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null +) : EmojiAppCompatTextView(context, attrs) { @Inject lateinit var textViewStyler: TextViewStyler @@ -61,8 +62,9 @@ open class QkTextView @JvmOverloads constructor(context: Context, attrs: Attribu ?.takeIf { layout -> layout.lineCount > 0 } ?.let { layout -> layout.getEllipsisCount(layout.lineCount - 1) } ?.takeIf { ellipsisCount -> ellipsisCount > 0 } - ?.let { ellipsisCount -> - val lastComma = text.dropLast(ellipsisCount).lastIndexOf(',') + ?.let { ellipsisCount -> text.dropLast(ellipsisCount).lastIndexOf(',') } + ?.takeIf { lastComma -> lastComma >= 0 } + ?.let { lastComma -> val remainingNames = text.drop(lastComma).count { c -> c == ',' } text = "${text.take(lastComma)}, +$remainingNames" } -- GitLab From e613100984624254e89baef0898894d9ee1fd5ae Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Tue, 18 Jun 2019 18:39:38 -0400 Subject: [PATCH 026/178] Only show changelog for EN --- .../src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index 0c22bb394..e3bcb3e1c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -50,6 +50,7 @@ import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import io.reactivex.schedulers.Schedulers import io.realm.Realm +import java.util.* import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -144,7 +145,7 @@ class MainViewModel @Inject constructor( .subscribe { syncMessages.execute(Unit) } // Show changelog - if (changelogManager.didUpdate()) { + if (changelogManager.didUpdate() && Locale.getDefault().language.startsWith("en")) { view.showChangelog() } -- GitLab From da4685297b0b5949c6abaa18b6de6a4c500fe243 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Tue, 18 Jun 2019 18:42:16 -0400 Subject: [PATCH 027/178] Update translations --- .../src/main/res/values-hi/strings.xml | 28 ++++++++-------- .../src/main/res/values-tl/strings.xml | 32 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/presentation/src/main/res/values-hi/strings.xml b/presentation/src/main/res/values-hi/strings.xml index 7ebab8da1..d52f6f05a 100644 --- a/presentation/src/main/res/values-hi/strings.xml +++ b/presentation/src/main/res/values-hi/strings.xml @@ -127,14 +127,14 @@ Conversation title Enter title अधिसूचनाएँ - Theme + थीम संग्रह Unarchive अवरुदध करें Unblock वार्तालाप मिटाऐं Couldn\'t load media - Saved to gallery + गैलरी मैं सेव किया गया है Backup and restore Backing up messages Restoring from backup @@ -144,7 +144,7 @@ Restore किसी बैकअप का चयन करें Please unlock QKSMS+ to use backup and restore - Backup in progress… + बैकअप हो रहा है Restore in progress… Restore from backup Are you sure you would like to restore your messages from this backup? @@ -184,20 +184,20 @@ शुद्ध काली रात अंदाज़ शुरुआत समय End time - Font size + लिखाई का आकर Use system font Automatic emoji - Notifications + सूचनाएं Tap to customize Actions - Button 1 - Button 2 - Button 3 + बटन एक + बटन दो + बटन तीन Notification previews - Vibration - Sound - None - QK Reply + कंपन + ध्वनियाँ + कुछ नहीं + QK जवाब Popup for new messages Tap to dismiss Tap outside of the popup to close it @@ -208,8 +208,8 @@ Delayed sending Swipe actions Configure swipe actions for conversations - Right swipe - Left swipe + दाहिने तरफ से खींचे + बायें तरफ से खींचे CHANGE None diff --git a/presentation/src/main/res/values-tl/strings.xml b/presentation/src/main/res/values-tl/strings.xml index cd3c3e034..15c183832 100644 --- a/presentation/src/main/res/values-tl/strings.xml +++ b/presentation/src/main/res/values-tl/strings.xml @@ -19,27 +19,27 @@ ~ along with QKSMS. If not, see . --> - New conversation - Compose + Bagong usapan + Sumulat Shortcut disabled - Archived + Nakatabi Mga setting Notifications Theme - Search inbox… + Hanapin sa inbox… Sumulat - Skip - Continue + Laktawan + Magpatuloy Tawagan - Details + Mga detalye Save to gallery Open navigation drawer %d selected Clear - Archive - Unarchive - Delete - Pin to top + Itabi + Ilabas + Burahin + I-ipit sa itaas Unpin Mark read Mark unread @@ -48,10 +48,10 @@ You: %s Results in messages %d messages - Your conversations will appear here - No results - Your archived conversations will appear here - Start new conversation + Ang iyong mga pakikipag-usap ay makikita rito + Walang nakita + Ang iyong mga isinantabing pakikipag-usap at makikita rito + Magsimula ng bagong usapan Love texting again Make QKSMS your default SMS app Change @@ -60,7 +60,7 @@ QKSMS needs permission to view your contacts Allow Inbox - Archived + Nakatabi Scheduled Blocking More -- GitLab From 3076d86b52277cb5af132a88907cafd01e8ca924 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Tue, 18 Jun 2019 18:42:28 -0400 Subject: [PATCH 028/178] Increment to 3.6.6 --- presentation/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/presentation/build.gradle b/presentation/build.gradle index 5cf3f95f6..d05dab76c 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -31,8 +31,8 @@ android { applicationId "com.moez.QKSMS" minSdkVersion 21 targetSdkVersion 28 - versionCode 195 - versionName "3.6.5" + versionCode 196 + versionName "3.6.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildConfigField "String", "BUGSNAG_API_KEY", "\"${System.getenv("BUGSNAG_API_KEY")}\"" -- GitLab From 208584b60a32733740c90836c54d7b5304726124 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Wed, 17 Jul 2019 10:09:16 -0400 Subject: [PATCH 029/178] Upgrade gradle version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6873f91c5..5b07340b6 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.4.1' + classpath 'com.android.tools.build:gradle:3.4.2' classpath 'com.google.gms:google-services:4.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'io.fabric.tools:gradle:1.29.0' -- GitLab From d57d644f902abb207379a5f1d3138b0fa7bd61c8 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Wed, 17 Jul 2019 10:10:12 -0400 Subject: [PATCH 030/178] #1461 - Check permission before trying to save image --- .../com/moez/QKSMS/feature/gallery/GalleryActivity.kt | 6 ++++++ .../com/moez/QKSMS/feature/gallery/GalleryView.kt | 2 ++ .../moez/QKSMS/feature/gallery/GalleryViewModel.kt | 11 +++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryActivity.kt index ce7b851a7..4af41a7e4 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryActivity.kt @@ -18,9 +18,11 @@ */ package com.moez.QKSMS.feature.gallery +import android.Manifest import android.os.Bundle import android.view.Menu import android.view.MenuItem +import androidx.core.app.ActivityCompat import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders @@ -99,6 +101,10 @@ class GalleryActivity : QkActivity(), GalleryView { override fun pageChanged(): Observable = pageChangedSubject + override fun requestStoragePermission() { + ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 0) + } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.gallery, menu) return super.onCreateOptionsMenu(menu) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryView.kt index 2d1f2e515..b51b823b9 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryView.kt @@ -28,4 +28,6 @@ interface GalleryView : QkView { fun screenTouched(): Observable<*> fun pageChanged(): Observable + fun requestStoragePermission() + } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt index 5c233c990..68033caa9 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt @@ -25,6 +25,7 @@ import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.extensions.makeToast import com.moez.QKSMS.extensions.mapNotNull import com.moez.QKSMS.interactor.SaveImage +import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.MessageRepository import com.uber.autodispose.kotlin.autoDisposable @@ -39,7 +40,8 @@ class GalleryViewModel @Inject constructor( messageRepo: MessageRepository, @Named("partId") private val partId: Long, private val context: Context, - private val saveImage: SaveImage + private val saveImage: SaveImage, + private val permissions: PermissionManager ) : QkViewModel(GalleryState()) { init { @@ -47,7 +49,11 @@ class GalleryViewModel @Inject constructor( .mapNotNull(messageRepo::getMessageForPart) .mapNotNull { message -> message.threadId } .doOnNext { threadId -> newState { copy(parts = messageRepo.getPartsForConversation(threadId)) } } - .doOnNext { threadId -> newState { copy(title = conversationRepo.getConversation(threadId)?.getTitle()) } } + .doOnNext { threadId -> + newState { + copy(title = conversationRepo.getConversation(threadId)?.getTitle()) + } + } .subscribe() } @@ -64,6 +70,7 @@ class GalleryViewModel @Inject constructor( // Save image to device view.optionsItemSelected() .filter { itemId -> itemId == R.id.save } + .filter { permissions.hasStorage().also { if (!it) view.requestStoragePermission() } } .withLatestFrom(view.pageChanged()) { _, part -> part.id } .autoDisposable(view.scope()) .subscribe { partId -> saveImage.execute(partId) { context.makeToast(R.string.gallery_toast_saved) } } -- GitLab From 4681b0389571fc0f691fa7577ce263e310e98ab4 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Fri, 26 Jul 2019 19:37:13 -0400 Subject: [PATCH 031/178] Build app bundle and universal apk --- .travis.yml | 7 +++---- presentation/build.gradle | 20 -------------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8243fb383..3ea7b7f45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,7 @@ before_script: # Build APK script: - | - ./gradlew :presentation:assembleWithAnalyticsRelease assembleAndroidTest -PtestCoverageEnabled='true' + ./gradlew :presentation:assembleWithAnalyticsRelease :presentation:bundleWithAnalyticsRelease assembleAndroidTest -PtestCoverageEnabled='true' retval=$? if [$retval -ne 0]; then echo "error on assembling, exit code: "$retval @@ -91,9 +91,8 @@ deploy: api_key: secure: XF7V/I02gpyOzCAFXEFyrThXVUUnKjSaWQ8lppO50mVtdugimjWIPtHrcYASaJQf9INhqo0lamk+khPxtKxc1BSCp8o+c22UKcpczyjD4kK27a3zKfuNQWteBRjCH34vIGnrRFSHSWYLIgeuoIK3q5Lq4IBK/Od3mfpRaDt1ER+IqMzR3L205x1H8dW3MVuxXgdnq3jHlRpq86oOe293+dnblVCtWUvAzwhZPnnbBc4JUaNomMI7dLJ/pAigByCoHHmG9pc2Cky1yyWVAnTZFAlf2PbzPDLRRnXmHuYKfHxiZgd/l8JTiZdhky9cXgFoSxvJyDABRqqLxVNfXt2ZwgdtiulZml8RB1FB0L37qL72mxWgi6y9IbQgt/FG20K2QpSBglk0bCGLS+h5Yz3kV4fhsBY7llpWGw14BvlAx9sUfl3Ej+IUsWoJgA00TFNGDG8sMyOFoCQVz/sB4Dv4h+JfynJZcmm8okcfYrWBHOoHY7cH3chBWp/2A736f2A/aqnBd6z8a03toe2ILC9eSOiIhrVxPyqLmEKBD1rCduVFNteqGwm9G9YwKpvFibTqu0gqEtfF7cmuMH6M5PYExI5EzoewZTYmgp02+lBuFAEMvycVvXcu8VfeeT6cgeLlmz2hsbo93UfoSQyP+gSojMOOkVUsl6mIp1STLiJ5IRY= file: - - /home/travis/build/moezbhatti/qksms/presentation/build/outputs/apk/withAnalytics/release/presentation-withAnalytics-arm64-v8a-release.apk - - /home/travis/build/moezbhatti/qksms/presentation/build/outputs/apk/withAnalytics/release/presentation-withAnalytics-armeabi-v7a-release.apk - - /home/travis/build/moezbhatti/qksms/presentation/build/outputs/apk/withAnalytics/release/presentation-withAnalytics-universal-release.apk + - /home/travis/build/moezbhatti/qksms/presentation/build/outputs/bundle/withAnalyticsRelease/presentation.aab + - /home/travis/build/moezbhatti/qksms/presentation/build/outputs/apk/withAnalytics/release/presentation-withAnalytics-release.apk on: repo: moezbhatti/qksms tags: true \ No newline at end of file diff --git a/presentation/build.gradle b/presentation/build.gradle index d05dab76c..2d0140b3c 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -65,15 +65,6 @@ android { noAnalytics { dimension "analytics" } } - splits { - abi { - enable true - reset() - include 'armeabi-v7a', 'arm64-v8a' - universalApk true - } - } - if (System.getenv("CI") == "true") { signingConfigs.release.storeFile = file("../keystore") signingConfigs.release.storePassword = System.getenv("keystore_password") @@ -86,17 +77,6 @@ androidExtensions { experimental = true } -import com.android.build.OutputFile - -// For each APK output variant, override versionCode with one that is unique -// https://developer.android.com/studio/build/gradle-tips.html#configure-dynamic-version-codes -android.applicationVariants.all { variant -> - variant.outputs.each { output -> - def baseAbiVersionCode = abiCodes.get(output.getFilter(OutputFile.ABI), 0) - output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode - } -} - configurations { noAnalyticsDebug noAnalyticsRelease -- GitLab From 3915b9322b2642210d153e2e6fee8b84d2ddc91c Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Fri, 26 Jul 2019 23:34:00 -0400 Subject: [PATCH 032/178] #505 - Signature support --- .../QKSMS/repository/MessageRepositoryImpl.kt | 14 ++++-- .../java/com/moez/QKSMS/util/Preferences.kt | 1 + .../moez/QKSMS/common/widget/FieldDialog.kt | 48 +++++++++++++++++++ .../ConversationInfoController.kt | 34 ++++--------- .../feature/settings/SettingsController.kt | 12 +++++ .../feature/settings/SettingsPresenter.kt | 14 +++++- .../QKSMS/feature/settings/SettingsState.kt | 1 + .../QKSMS/feature/settings/SettingsView.kt | 2 + .../res/drawable/ic_short_text_black_24dp.xml | 9 ++++ .../src/main/res/layout/field_dialog.xml | 33 +++++++++++++ .../main/res/layout/settings_controller.xml | 9 +++- presentation/src/main/res/values/strings.xml | 2 +- 12 files changed, 146 insertions(+), 33 deletions(-) create mode 100644 presentation/src/main/java/com/moez/QKSMS/common/widget/FieldDialog.kt create mode 100644 presentation/src/main/res/drawable/ic_short_text_black_24dp.xml create mode 100644 presentation/src/main/res/layout/field_dialog.xml diff --git a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt index 8b6dd02c2..d22984605 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt @@ -218,10 +218,16 @@ class MessageRepositoryImpl @Inject constructor( attachments: List, delay: Int ) { + val signedBody = when { + prefs.signature.get().isEmpty() -> body + body.isNotEmpty() -> body + '\n' + prefs.signature.get() + else -> prefs.signature.get() + } + if (addresses.size == 1 && attachments.isEmpty()) { // SMS if (delay > 0) { // With delay val sendTime = System.currentTimeMillis() + delay - val message = insertSentSms(subId, threadId, addresses.first(), body, sendTime) + val message = insertSentSms(subId, threadId, addresses.first(), signedBody, sendTime) val intent = getIntentForDelayedSms(message.id) @@ -232,14 +238,14 @@ class MessageRepositoryImpl @Inject constructor( alarmManager.setExact(AlarmManager.RTC_WAKEUP, sendTime, intent) } } else { // No delay - val message = insertSentSms(subId, threadId, addresses.first(), body, System.currentTimeMillis()) + val message = insertSentSms(subId, threadId, addresses.first(), signedBody, System.currentTimeMillis()) sendSms(message) } } else { // MMS val parts = arrayListOf() - if (body.isNotBlank()) { - parts += MMSPart("text", ContentType.TEXT_PLAIN, body.toByteArray()) + if (signedBody.isNotBlank()) { + parts += MMSPart("text", ContentType.TEXT_PLAIN, signedBody.toByteArray()) } // Add the GIFs as attachments diff --git a/data/src/main/java/com/moez/QKSMS/util/Preferences.kt b/data/src/main/java/com/moez/QKSMS/util/Preferences.kt index a13858f84..53437b2d7 100644 --- a/data/src/main/java/com/moez/QKSMS/util/Preferences.kt +++ b/data/src/main/java/com/moez/QKSMS/util/Preferences.kt @@ -83,6 +83,7 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) val swipeLeft = rxPrefs.getInteger("swipeLeft", SWIPE_ACTION_ARCHIVE) val autoEmoji = rxPrefs.getBoolean("autoEmoji", true) val delivery = rxPrefs.getBoolean("delivery", false) + val signature = rxPrefs.getString("signature", "") val unicode = rxPrefs.getBoolean("unicode", false) val mobileOnly = rxPrefs.getBoolean("mobileOnly", false) val mmsSize = rxPrefs.getInteger("mmsSize", 300) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/FieldDialog.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/FieldDialog.kt new file mode 100644 index 000000000..1649edf68 --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/FieldDialog.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.common.widget + +import android.app.Activity +import android.content.DialogInterface +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import com.moez.QKSMS.R +import kotlinx.android.synthetic.main.field_dialog.view.* + +class FieldDialog(context: Activity, hint: String, listener: (String) -> Unit) : AlertDialog(context) { + + private val layout = LayoutInflater.from(context).inflate(R.layout.field_dialog, null) + + init { + layout.field.hint = hint + + setView(layout) + setButton(DialogInterface.BUTTON_NEUTRAL, context.getString(R.string.button_cancel)) { _, _ -> } + setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.button_delete)) { _, _ -> listener("") } + setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.button_save)) { _, _ -> + listener(layout.field.text.toString()) + } + } + + fun setText(text: String): FieldDialog { + layout.field.setText(text) + return this + } + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt index caabfebb7..f5140e88c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt @@ -18,7 +18,6 @@ */ package com.moez.QKSMS.feature.conversationinfo -import android.text.InputFilter import android.view.View import androidx.appcompat.app.AlertDialog import com.bluelinelabs.conductor.RouterTransaction @@ -28,11 +27,9 @@ import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.QkChangeHandler import com.moez.QKSMS.common.base.QkController import com.moez.QKSMS.common.util.extensions.animateLayoutChanges -import com.moez.QKSMS.common.util.extensions.dpToPx -import com.moez.QKSMS.common.util.extensions.resolveThemeColor import com.moez.QKSMS.common.util.extensions.scrapViews import com.moez.QKSMS.common.util.extensions.setVisible -import com.moez.QKSMS.common.widget.QkEditText +import com.moez.QKSMS.common.widget.FieldDialog import com.moez.QKSMS.feature.conversationinfo.injection.ConversationInfoModule import com.moez.QKSMS.feature.themepicker.ThemePickerController import com.moez.QKSMS.injection.appComponent @@ -43,7 +40,9 @@ import io.reactivex.subjects.Subject import kotlinx.android.synthetic.main.conversation_info_controller.* import javax.inject.Inject -class ConversationInfoController(val threadId: Long = 0) : QkController(), ConversationInfoView { +class ConversationInfoController( + val threadId: Long = 0 +) : QkController(), ConversationInfoView { @Inject override lateinit var presenter: ConversationInfoPresenter @Inject lateinit var navigator: Navigator @@ -51,6 +50,10 @@ class ConversationInfoController(val threadId: Long = 0) : QkController = PublishSubject.create() private val confirmDeleteSubject: Subject = PublishSubject.create() @@ -130,26 +133,7 @@ class ConversationInfoController(val threadId: Long = 0) : QkController nameChangeSubject.onNext(editText.text.toString()) } - .setNegativeButton(R.string.button_cancel, null) - .show() - } + override fun showNameDialog(name: String) = nameDialog.setText(name).show() override fun showThemePicker(threadId: Long) { router.pushController(RouterTransaction.with(ThemePickerController(threadId)) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt index d90ae0163..ffa8f1dd1 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt @@ -37,6 +37,7 @@ import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.common.util.extensions.animateLayoutChanges import com.moez.QKSMS.common.util.extensions.setBackgroundTint import com.moez.QKSMS.common.util.extensions.setVisible +import com.moez.QKSMS.common.widget.FieldDialog import com.moez.QKSMS.common.widget.PreferenceView import com.moez.QKSMS.feature.settings.about.AboutController import com.moez.QKSMS.feature.settings.swipe.SwipeActionsController @@ -65,9 +66,14 @@ class SettingsController : QkController = PublishSubject.create() private val startTimeSelectedSubject: Subject> = PublishSubject.create() private val endTimeSelectedSubject: Subject> = PublishSubject.create() + private val signatureSubject: Subject = PublishSubject.create() private val progressAnimator by lazy { ObjectAnimator.ofInt(syncingProgress, "progress", 0, 0) } @@ -119,6 +125,8 @@ class SettingsController : QkController = sendDelayDialog.adapter.menuItemClicks + override fun signatureSet(): Observable = signatureSubject + override fun mmsSizeSelected(): Observable = mmsSizeDialog.adapter.menuItemClicks override fun render(state: SettingsState) { @@ -140,6 +148,8 @@ class SettingsController : QkController newState { copy(deliveryEnabled = enabled) } } + disposables += prefs.signature.asObservable() + .subscribe { signature -> newState { copy(signature = signature) } } + val textSizeLabels = context.resources.getStringArray(R.array.text_sizes) disposables += prefs.textSize.asObservable() .subscribe { textSize -> @@ -153,6 +156,8 @@ class SettingsPresenter @Inject constructor( R.id.delivery -> prefs.delivery.set(!prefs.delivery.get()) + R.id.signature -> view.showSignatureDialog(prefs.signature.get()) + R.id.textSize -> view.showTextSizePicker() R.id.systemFont -> prefs.systemFont.set(!prefs.systemFont.get()) @@ -205,7 +210,7 @@ class SettingsPresenter @Inject constructor( view.textSizeSelected() .autoDisposable(view.scope()) - .subscribe { prefs.textSize.set(it) } + .subscribe(prefs.textSize::set) view.sendDelaySelected() .withLatestFrom(billingManager.upgradeStatus) { duration, upgraded -> @@ -218,9 +223,14 @@ class SettingsPresenter @Inject constructor( .autoDisposable(view.scope()) .subscribe() + view.signatureSet() + .doOnNext(prefs.signature::set) + .autoDisposable(view.scope()) + .subscribe() + view.mmsSizeSelected() .autoDisposable(view.scope()) - .subscribe { prefs.mmsSize.set(it) } + .subscribe(prefs.mmsSize::set) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsState.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsState.kt index 18285627b..d2a359957 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsState.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsState.kt @@ -33,6 +33,7 @@ data class SettingsState( val sendDelaySummary: String = "", val sendDelayId: Int = 0, val deliveryEnabled: Boolean = false, + val signature: String = "", val textSizeSummary: String = "", val textSizeId: Int = Preferences.TEXT_SIZE_NORMAL, val systemFontEnabled: Boolean = false, diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsView.kt index 081d4c08c..80431508e 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsView.kt @@ -31,6 +31,7 @@ interface SettingsView : QkViewContract { fun nightEndSelected(): Observable> fun textSizeSelected(): Observable fun sendDelaySelected(): Observable + fun signatureSet(): Observable fun mmsSizeSelected(): Observable fun showQksmsPlusSnackbar() @@ -39,6 +40,7 @@ interface SettingsView : QkViewContract { fun showEndTimePicker(hour: Int, minute: Int) fun showTextSizePicker() fun showDelayDurationDialog() + fun showSignatureDialog(signature: String) fun showMmsSizePicker() fun showSwipeActions() fun showThemePicker() diff --git a/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml b/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml new file mode 100644 index 000000000..11c24c5a3 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/layout/field_dialog.xml b/presentation/src/main/res/layout/field_dialog.xml new file mode 100644 index 000000000..76326dd54 --- /dev/null +++ b/presentation/src/main/res/layout/field_dialog.xml @@ -0,0 +1,33 @@ + + + diff --git a/presentation/src/main/res/layout/settings_controller.xml b/presentation/src/main/res/layout/settings_controller.xml index 9fa9f4a3c..198ac6076 100644 --- a/presentation/src/main/res/layout/settings_controller.xml +++ b/presentation/src/main/res/layout/settings_controller.xml @@ -144,6 +144,13 @@ app:title="@string/settings_delivery_title" app:widget="@layout/settings_switch_widget" /> + + - \ No newline at end of file + diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 1562885a9..718d1db65 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -138,7 +138,6 @@ Details Conversation title - Enter title Notifications Theme Archive @@ -241,6 +240,7 @@ Delivery confirmations Confirm that messages were sent successfully + Signature Strip accents Remove accents from characters in outgoing SMS messages Mobile numbers only -- GitLab From 04ea57ebb0adc8c97bb6149aeed0767cc63da5fe Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sat, 27 Jul 2019 01:03:29 -0400 Subject: [PATCH 033/178] Remove unused service --- .../send_message/MmsReceivedService.java | 310 ------------------ 1 file changed, 310 deletions(-) delete mode 100755 android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java diff --git a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java deleted file mode 100755 index 5f206e4e4..000000000 --- a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsReceivedService.java +++ /dev/null @@ -1,310 +0,0 @@ -package com.klinker.android.send_message; - - -import android.app.IntentService; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.provider.Telephony; -import android.telephony.SmsManager; -import com.android.mms.service_alt.DownloadRequest; -import com.android.mms.service_alt.MmsConfig; -import com.android.mms.transaction.DownloadManager; -import com.android.mms.transaction.HttpUtils; -import com.android.mms.transaction.TransactionSettings; -import com.android.mms.util.SendingProgressTokenManager; -import com.google.android.mms.InvalidHeaderValueException; -import com.google.android.mms.MmsException; -import com.google.android.mms.pdu_alt.EncodedStringValue; -import com.google.android.mms.pdu_alt.GenericPdu; -import com.google.android.mms.pdu_alt.NotificationInd; -import com.google.android.mms.pdu_alt.NotifyRespInd; -import com.google.android.mms.pdu_alt.PduComposer; -import com.google.android.mms.pdu_alt.PduHeaders; -import com.google.android.mms.pdu_alt.PduParser; -import com.google.android.mms.pdu_alt.PduPersister; -import com.google.android.mms.pdu_alt.RetrieveConf; -import com.google.android.mms.util_alt.SqliteWrapper; -import timber.log.Timber; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; - -import static com.google.android.mms.pdu_alt.PduHeaders.STATUS_RETRIEVED; -import static com.klinker.android.send_message.MmsReceivedReceiver.*; - -public class MmsReceivedService extends IntentService { - private static final String LOCATION_SELECTION = - Telephony.Mms.MESSAGE_TYPE + "=? AND " + Telephony.Mms.CONTENT_LOCATION + " =?"; - - public MmsReceivedService() { - super("MmsReceivedService"); - } - - public MmsReceivedService(String name) { - super(name); - } - - @Override - protected void onHandleIntent(Intent intent) { - Timber.v("MMS has finished downloading, persisting it to the database"); - - String path = intent.getStringExtra(EXTRA_FILE_PATH); - Timber.v(path); - - FileInputStream reader = null; - try { - File mDownloadFile = new File(path); - final int nBytes = (int) mDownloadFile.length(); - reader = new FileInputStream(mDownloadFile); - final byte[] response = new byte[nBytes]; - reader.read(response, 0, nBytes); - - CommonNotificationTask task = getNotificationTask(this, intent, response); - executeNotificationTask(task); - - DownloadRequest.persist(this, response, - new MmsConfig.Overridden(new MmsConfig(this), null), - intent.getStringExtra(EXTRA_LOCATION_URL), - Utils.getDefaultSubscriptionId(), null); - - Timber.v("response saved successfully"); - Timber.v("response length: " + response.length); - mDownloadFile.delete(); - } catch (FileNotFoundException e) { - Timber.e(e, "MMS received, file not found exception"); - } catch (IOException e) { - Timber.e(e, "MMS received, io exception"); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - Timber.e(e, "MMS received, io exception"); - } - } - - handleHttpError(this, intent); - DownloadManager.finishDownload(intent.getStringExtra(EXTRA_LOCATION_URL)); - } - } - - private static void handleHttpError(Context context, Intent intent) { - final int httpError = intent.getIntExtra(SmsManager.EXTRA_MMS_HTTP_STATUS, 0); - if (httpError == 404 || - httpError == 400) { - // Delete the corresponding NotificationInd - SqliteWrapper.delete(context, - context.getContentResolver(), - Telephony.Mms.CONTENT_URI, - LOCATION_SELECTION, - new String[]{ - Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND), - intent.getStringExtra(EXTRA_LOCATION_URL) - }); - } - } - - private static NotificationInd getNotificationInd(Context context, Intent intent) throws MmsException { - return (NotificationInd) PduPersister.getPduPersister(context).load((Uri) intent.getParcelableExtra(EXTRA_URI)); - } - - private static abstract class CommonNotificationTask { - protected final Context mContext; - private final TransactionSettings mTransactionSettings; - final NotificationInd mNotificationInd; - final String mContentLocation; - - CommonNotificationTask(Context context, TransactionSettings settings, NotificationInd ind) { - mContext = context; - mTransactionSettings = settings; - mNotificationInd = ind; - mContentLocation = new String(ind.getContentLocation()); - } - - /** - * A common method to send a PDU to MMSC. - * - * @param pdu A byte array which contains the data of the PDU. - * @param mmscUrl Url of the recipient MMSC. - * @return A byte array which contains the response data. - * If an HTTP error code is returned, an IOException will be thrown. - * @throws java.io.IOException if any error occurred on network interface or - * an HTTP error code(>=400) returned from the server. - * @throws com.google.android.mms.MmsException if pdu is null. - */ - byte[] sendPdu(byte[] pdu, String mmscUrl) throws IOException, MmsException { - return sendPdu(SendingProgressTokenManager.NO_TOKEN, pdu, mmscUrl); - } - - /** - * A common method to send a PDU to MMSC. - * - * @param pdu A byte array which contains the data of the PDU. - * @return A byte array which contains the response data. - * If an HTTP error code is returned, an IOException will be thrown. - * @throws java.io.IOException if any error occurred on network interface or - * an HTTP error code(>=400) returned from the server. - * @throws com.google.android.mms.MmsException if pdu is null. - */ - byte[] sendPdu(byte[] pdu) throws IOException, MmsException { - return sendPdu(SendingProgressTokenManager.NO_TOKEN, pdu, - mTransactionSettings.getMmscUrl()); - } - - /** - * A common method to send a PDU to MMSC. - * - * @param token The token to identify the sending progress. - * @param pdu A byte array which contains the data of the PDU. - * @param mmscUrl Url of the recipient MMSC. - * @return A byte array which contains the response data. - * If an HTTP error code is returned, an IOException will be thrown. - * @throws java.io.IOException if any error occurred on network interface or - * an HTTP error code(>=400) returned from the server. - * @throws com.google.android.mms.MmsException if pdu is null. - */ - private byte[] sendPdu(final long token, final byte[] pdu, - final String mmscUrl) throws IOException, MmsException { - if (pdu == null) { - throw new MmsException(); - } - - if (mmscUrl == null) { - throw new IOException("Cannot establish route: mmscUrl is null"); - } - - if (com.android.mms.transaction.Transaction.useWifi(mContext)) { - return HttpUtils.httpConnection( - mContext, token, - mmscUrl, - pdu, HttpUtils.HTTP_POST_METHOD, - false, null, 0); - } - - return Utils.ensureRouteToMmsNetwork(mContext, mmscUrl, mTransactionSettings.getProxyAddress(), new Utils.Task() { - @Override - public byte[] run() throws IOException { - return HttpUtils.httpConnection( - mContext, token, - mmscUrl, - pdu, HttpUtils.HTTP_POST_METHOD, - mTransactionSettings.isProxySet(), - mTransactionSettings.getProxyAddress(), - mTransactionSettings.getProxyPort()); - } - }); - } - - public abstract void run() throws IOException; - } - - private static class NotifyRespTask extends CommonNotificationTask { - NotifyRespTask(Context context, NotificationInd ind, TransactionSettings settings) { - super(context, settings, ind); - } - - @Override - public void run() throws IOException { - // Create the M-NotifyResp.ind - NotifyRespInd notifyRespInd; - try { - notifyRespInd = new NotifyRespInd( - PduHeaders.CURRENT_MMS_VERSION, - mNotificationInd.getTransactionId(), - STATUS_RETRIEVED); - - // Pack M-NotifyResp.ind and send it - if(com.android.mms.MmsConfig.getNotifyWapMMSC()) { - sendPdu(new PduComposer(mContext, notifyRespInd).make(), mContentLocation); - } else { - sendPdu(new PduComposer(mContext, notifyRespInd).make()); - } - } catch (MmsException e) { - Timber.e(e, "error"); - } - } - } - - private static class AcknowledgeIndTask extends CommonNotificationTask { - private final RetrieveConf mRetrieveConf; - - AcknowledgeIndTask(Context context, NotificationInd ind, TransactionSettings settings, RetrieveConf rc) { - super(context, settings, ind); - mRetrieveConf = rc; - } - - @Override - public void run() throws IOException { - // Send M-Acknowledge.ind to MMSC if required. - // If the Transaction-ID isn't set in the M-Retrieve.conf, it means - // the MMS proxy-relay doesn't require an ACK. - byte[] tranId = mRetrieveConf.getTransactionId(); - if (tranId != null) { - // Create M-Acknowledge.ind - com.google.android.mms.pdu_alt.AcknowledgeInd acknowledgeInd; - try { - acknowledgeInd = new com.google.android.mms.pdu_alt.AcknowledgeInd( - PduHeaders.CURRENT_MMS_VERSION, tranId); - - // insert the 'from' address per spec - String lineNumber = Utils.getMyPhoneNumber(mContext); - acknowledgeInd.setFrom(new EncodedStringValue(lineNumber)); - - // Pack M-Acknowledge.ind and send it - if(com.android.mms.MmsConfig.getNotifyWapMMSC()) { - sendPdu(new PduComposer(mContext, acknowledgeInd).make(), mContentLocation); - } else { - sendPdu(new PduComposer(mContext, acknowledgeInd).make()); - } - } catch (InvalidHeaderValueException e) { - Timber.e(e, "error"); - } catch (MmsException e) { - Timber.e(e, "error"); - } - } - } - } - - private static CommonNotificationTask getNotificationTask(Context context, Intent intent, byte[] response) { - if (response.length == 0) { - return null; - } - - final GenericPdu pdu = (new PduParser(response, new MmsConfig.Overridden(new MmsConfig(context), null). - getSupportMmsContentDisposition())).parse(); - if (!(pdu instanceof RetrieveConf)) { - Timber.e("MmsReceivedReceiver.sendNotification failed to parse pdu"); - return null; - } - - try { - NotificationInd ind = getNotificationInd(context, intent); - TransactionSettings transactionSettings = new TransactionSettings(context, null); - if (intent.getBooleanExtra(EXTRA_TRIGGER_PUSH, false)) { - return new NotifyRespTask(context, ind, transactionSettings); - } else { - return new AcknowledgeIndTask(context, ind, transactionSettings, (RetrieveConf) pdu); - } - } catch (MmsException e) { - Timber.e(e, "error"); - return null; - } - } - - private static void executeNotificationTask(CommonNotificationTask task) throws IOException { - if (task == null) { - return; - } - - try { - // need retry ? - task.run(); - } catch (IOException e) { - Timber.e(e, "MMS send received notification, io exception"); - throw e; - } - } -} -- GitLab From da28edc7829f0a27581cdb0ba7ff667b3001b43e Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sat, 27 Jul 2019 14:04:22 -0400 Subject: [PATCH 034/178] #1351 - Fix new conversation not being created on Huawei devices --- .../QKSMS/mapper/CursorToConversationImpl.kt | 4 +- .../com/moez/QKSMS/interactor/SendMessage.kt | 26 ++++--- .../moez/QKSMS/mapper/CursorToConversation.kt | 2 +- .../QKSMS/feature/compose/ComposeViewModel.kt | 68 ++++++++++--------- 4 files changed, 57 insertions(+), 43 deletions(-) diff --git a/data/src/main/java/com/moez/QKSMS/mapper/CursorToConversationImpl.kt b/data/src/main/java/com/moez/QKSMS/mapper/CursorToConversationImpl.kt index 9ee32c36b..304a45174 100644 --- a/data/src/main/java/com/moez/QKSMS/mapper/CursorToConversationImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/mapper/CursorToConversationImpl.kt @@ -66,9 +66,9 @@ class CursorToConversationImpl @Inject constructor( } } - override fun getConversationsCursor(lastSync: Long): Cursor? { + override fun getConversationsCursor(): Cursor? { return when (permissionManager.hasReadSms()) { - true -> context.contentResolver.query(URI, PROJECTION, "date > $lastSync", null, "date desc") + true -> context.contentResolver.query(URI, PROJECTION, null, null, "date desc") false -> null } } diff --git a/domain/src/main/java/com/moez/QKSMS/interactor/SendMessage.kt b/domain/src/main/java/com/moez/QKSMS/interactor/SendMessage.kt index 687a5f819..5a5b727d9 100644 --- a/domain/src/main/java/com/moez/QKSMS/interactor/SendMessage.kt +++ b/domain/src/main/java/com/moez/QKSMS/interactor/SendMessage.kt @@ -18,6 +18,9 @@ */ package com.moez.QKSMS.interactor +import android.content.Context +import com.moez.QKSMS.compat.TelephonyCompat +import com.moez.QKSMS.extensions.mapNotNull import com.moez.QKSMS.model.Attachment import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.MessageRepository @@ -25,6 +28,7 @@ import io.reactivex.Flowable import javax.inject.Inject class SendMessage @Inject constructor( + private val context: Context, private val conversationRepo: ConversationRepository, private val messageRepo: MessageRepository ) : Interactor() { @@ -41,16 +45,20 @@ class SendMessage @Inject constructor( override fun buildObservable(params: Params): Flowable<*> = Flowable.just(Unit) .filter { params.addresses.isNotEmpty() } .doOnNext { - messageRepo.sendMessage(params.subId, params.threadId, params.addresses, params.body, - params.attachments, params.delay) + // If a threadId isn't provided, try to obtain one + val threadId = when (params.threadId) { + 0L -> TelephonyCompat.getOrCreateThreadId(context, params.addresses.toSet()) + else -> params.threadId + } + messageRepo.sendMessage(params.subId, threadId, params.addresses, params.body, params.attachments, + params.delay) } - .map { - // On some manufacturers, we can't obtain a threadId for a new conversation. In - // this case, find the threadId manually now that it contains a message - if (params.threadId == 0L) { - conversationRepo.getOrCreateConversation(params.addresses)?.id ?: 0 - } else { - params.threadId + .mapNotNull { + // If the threadId wasn't provided, then it's probably because it doesn't exist in Realm. + // Sync it now and get the id + when (params.threadId) { + 0L -> conversationRepo.getOrCreateConversation(params.addresses)?.id + else -> params.threadId } } .doOnNext { threadId -> conversationRepo.updateConversations(threadId) } diff --git a/domain/src/main/java/com/moez/QKSMS/mapper/CursorToConversation.kt b/domain/src/main/java/com/moez/QKSMS/mapper/CursorToConversation.kt index fcbdeaa36..56f15e3eb 100644 --- a/domain/src/main/java/com/moez/QKSMS/mapper/CursorToConversation.kt +++ b/domain/src/main/java/com/moez/QKSMS/mapper/CursorToConversation.kt @@ -23,6 +23,6 @@ import com.moez.QKSMS.model.Conversation interface CursorToConversation : Mapper { - fun getConversationsCursor(lastSync: Long = 0): Cursor? + fun getConversationsCursor(): Cursor? } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt index bbef29b53..fb34d22a4 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt @@ -132,8 +132,7 @@ class ComposeViewModel @Inject constructor( .observeOn(AndroidSchedulers.mainThread()) .doOnNext { newState { copy(loading = false) } } .switchMap { (threadId, addresses) -> - - // If we already have this thread in realm, or were able to obtain it from the + // If we already have this thread in realm, or we're able to obtain it from the // system, just return that. threadId.takeIf { it > 0 }?.let { return@switchMap conversationRepo.getConversationAsync(threadId).asObservable() @@ -249,7 +248,8 @@ class ComposeViewModel @Inject constructor( // Update the list of contact suggestions based on the query input, while also filtering out any contacts // that have already been selected Observables - .combineLatest(view.queryChangedIntent, contacts, selectedContacts) { query, contacts, selectedContacts -> + .combineLatest(view.queryChangedIntent, contacts, selectedContacts) { query, contacts, + selectedContacts -> // Strip the accents from the query. This can be an expensive operation, so // cache the result instead of doing it for each contact @@ -375,7 +375,6 @@ class ComposeViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe { view.clearSelection() } - // Show the previous search result view.optionsItemIntent .filter { it == R.id.previous } @@ -388,7 +387,6 @@ class ComposeViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe(searchSelection) - // Show the next search result view.optionsItemIntent .filter { it == R.id.next } @@ -401,20 +399,17 @@ class ComposeViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe(searchSelection) - // Clear the search view.optionsItemIntent .filter { it == R.id.clear } .autoDisposable(view.scope()) .subscribe { newState { copy(query = "", searchSelectionId = -1) } } - // Toggle the group sending mode view.sendAsGroupIntent .autoDisposable(view.scope()) .subscribe { newState { copy(sendAsGroup = !sendAsGroup) } } - // Scroll to search position searchSelection .filter { id -> id != -1L } @@ -422,7 +417,6 @@ class ComposeViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe(view::scrollToMessage) - // Retry sending view.messageClickIntent .filter { message -> message.isFailedMessage() } @@ -443,20 +437,21 @@ class ComposeViewModel @Inject constructor( .subscribe { message -> cancelMessage.execute(message.id) } // Set the current conversation - Observables - .combineLatest( - view.activityVisibleIntent.distinctUntilChanged(), - conversation.mapNotNull { conversation -> conversation.takeIf { it.isValid }?.id }.distinctUntilChanged()) - { visible, threadId -> - when (visible) { - true -> { - activeConversationManager.setActiveConversation(threadId) - markRead.execute(listOf(threadId)) - } - - false -> activeConversationManager.setActiveConversation(null) - } + Observables.combineLatest( + view.activityVisibleIntent.distinctUntilChanged(), + conversation.mapNotNull { conversation -> + conversation.takeIf { it.isValid }?.id + }.distinctUntilChanged()) + { visible, threadId -> + when (visible) { + true -> { + activeConversationManager.setActiveConversation(threadId) + markRead.execute(listOf(threadId)) } + + false -> activeConversationManager.setActiveConversation(null) + } + } .autoDisposable(view.scope()) .subscribe() @@ -533,7 +528,7 @@ class ComposeViewModel @Inject constructor( // Contact was selected for attachment view.contactSelectedIntent .map { uri -> Attachment.Contact(getVCard(uri)!!) } - .withLatestFrom(attachments) { attachment, attachments -> attachments + attachment} + .withLatestFrom(attachments) { attachment, attachments -> attachments + attachment } .subscribeOn(Schedulers.io()) .autoDisposable(view.scope()) .subscribe(attachments::onNext) { error -> @@ -617,7 +612,8 @@ class ComposeViewModel @Inject constructor( .filter { permissionManager.hasSendSms().also { if (!it) view.requestSmsPermission() } } .withLatestFrom(view.textChangedIntent) { _, body -> body } .map { body -> body.toString() } - .withLatestFrom(state, attachments, conversation, selectedContacts) { body, state, attachments, conversation, contacts -> + .withLatestFrom(state, attachments, conversation, selectedContacts) { body, state, attachments, + conversation, contacts -> val subId = state.subscription?.subscriptionId ?: -1 val addresses = when (conversation.recipients.isNotEmpty()) { true -> conversation.recipients.map { it.address } @@ -634,15 +630,20 @@ class ComposeViewModel @Inject constructor( // Scheduling a message state.scheduled != 0L -> { newState { copy(scheduled = 0) } - val uris = attachments.mapNotNull { it as? Attachment.Image }.map { it.getUri() }.map { it.toString() } - val params = AddScheduledMessage.Params(state.scheduled, subId, addresses, state.sendAsGroup, body, uris) + val uris = attachments + .mapNotNull { it as? Attachment.Image } + .map { it.getUri() } + .map { it.toString() } + val params = AddScheduledMessage + .Params(state.scheduled, subId, addresses, state.sendAsGroup, body, uris) addScheduledMessage.execute(params) context.makeToast(R.string.compose_scheduled_toast) } // Sending a group message state.sendAsGroup -> { - sendMessage.execute(SendMessage.Params(subId, conversation.id, addresses, body, attachments, delay)) + sendMessage.execute(SendMessage + .Params(subId, conversation.id, addresses, body, attachments, delay)) } // Sending a message to an existing conversation with one recipient @@ -653,15 +654,20 @@ class ComposeViewModel @Inject constructor( // Create a new conversation with one address addresses.size == 1 -> { - sendMessage.execute(SendMessage.Params(subId, threadId, addresses, body, attachments, delay)) + sendMessage.execute(SendMessage + .Params(subId, threadId, addresses, body, attachments, delay)) } // Send a message to multiple addresses else -> { addresses.forEach { addr -> - val threadId = tryOrNull(false) { TelephonyCompat.getOrCreateThreadId(context, addr) } ?: 0 - val address = listOf(conversationRepo.getConversation(threadId)?.recipients?.firstOrNull()?.address ?: addr) - sendMessage.execute(SendMessage.Params(subId, threadId, address, body, attachments, delay)) + val threadId = tryOrNull(false) { + TelephonyCompat.getOrCreateThreadId(context, addr) + } ?: 0 + val address = listOf(conversationRepo + .getConversation(threadId)?.recipients?.firstOrNull()?.address ?: addr) + sendMessage.execute(SendMessage + .Params(subId, threadId, address, body, attachments, delay)) } } } -- GitLab From b8fb429ddaac2fd40c3e2e8aa91ace7bede6c9f6 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sat, 27 Jul 2019 22:54:50 -0400 Subject: [PATCH 035/178] #945 - Fix MMS reception for MIUI devices --- .../mms/service_alt/DownloadRequest.java | 55 +++++++++---------- .../android/mms/transaction/PushReceiver.java | 5 +- .../QKSMS/receiver/MmsReceivedReceiver.kt | 2 +- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/android-smsmms/src/main/java/com/android/mms/service_alt/DownloadRequest.java b/android-smsmms/src/main/java/com/android/mms/service_alt/DownloadRequest.java index 4ed6de7e7..8a556aee2 100755 --- a/android-smsmms/src/main/java/com/android/mms/service_alt/DownloadRequest.java +++ b/android-smsmms/src/main/java/com/android/mms/service_alt/DownloadRequest.java @@ -47,20 +47,20 @@ public class DownloadRequest extends MmsRequest { private static final String LOCATION_SELECTION = Telephony.Mms.MESSAGE_TYPE + "=? AND " + Telephony.Mms.CONTENT_LOCATION + " =?"; - static final String[] PROJECTION = new String[] { + static final String[] PROJECTION = new String[]{ Telephony.Mms.CONTENT_LOCATION }; // The indexes of the columns which must be consistent with above PROJECTION. - static final int COLUMN_CONTENT_LOCATION = 0; + static final int COLUMN_CONTENT_LOCATION = 0; private final String mLocationUrl; private final PendingIntent mDownloadedIntent; private final Uri mContentUri; public DownloadRequest(RequestManager manager, int subId, String locationUrl, - Uri contentUri, PendingIntent downloadedIntent, String creator, - Bundle configOverrides, Context context) throws MmsException { + Uri contentUri, PendingIntent downloadedIntent, String creator, + Bundle configOverrides, Context context) throws MmsException { super(manager, subId, creator, configOverrides); if (locationUrl == null) { @@ -167,16 +167,12 @@ public class DownloadRequest extends MmsRequest { // } // Store the downloaded message final PduPersister persister = PduPersister.getPduPersister(context); - final Uri messageUri = persister.persist( - pdu, - Telephony.Mms.Inbox.CONTENT_URI, - true/*createThreadId*/, - true/*groupMmsEnabled*/, - null/*preOpenedFiles*/); + final Uri messageUri = persister.persist(pdu, Telephony.Mms.Inbox.CONTENT_URI, true, true, null); if (messageUri == null) { Timber.e("DownloadRequest.persistIfRequired: can not persist message"); return null; } + // Update some of the properties of the message final ContentValues values = new ContentValues(); values.put(Telephony.Mms.DATE, System.currentTimeMillis() / 1000L); @@ -190,24 +186,23 @@ public class DownloadRequest extends MmsRequest { values.put(Telephony.Mms.SUBSCRIPTION_ID, subId); } - if (SqliteWrapper.update( - context, - context.getContentResolver(), - messageUri, - values, - null/*where*/, - null/*selectionArg*/) != 1) { - Timber.e("DownloadRequest.persistIfRequired: can not update message"); + try { + context.getContentResolver().update(messageUri, values, null, null); + } catch (SQLiteException e) { + // On MIUI and a couple other devices, the above call will fail and say `no such column: sub_id` + // If before making that call, we check to see if the sub_id column is available for messageUri, we will + // find that it is available, and yet the update call will still fail. So - there's no way we can know + // in advance that it will fail, and we have to just try again + if (values.containsKey(Telephony.Mms.SUBSCRIPTION_ID)) { + values.remove(Telephony.Mms.SUBSCRIPTION_ID); + context.getContentResolver().update(messageUri, values, null, null); + } else { + throw e; + } } // Delete the corresponding NotificationInd - SqliteWrapper.delete(context, - context.getContentResolver(), - Telephony.Mms.CONTENT_URI, - LOCATION_SELECTION, - new String[]{ - Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND), - locationUrl - }); + SqliteWrapper.delete(context, context.getContentResolver(), Telephony.Mms.CONTENT_URI, LOCATION_SELECTION, + new String[]{Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND), locationUrl}); return messageUri; } catch (MmsException e) { @@ -268,7 +263,7 @@ public class DownloadRequest extends MmsRequest { /** * Transfer the received response to the caller (for download requests write to content uri) * - * @param fillIn the intent that will be returned to the caller + * @param fillIn the intent that will be returned to the caller * @param response the pdu to transfer */ @Override @@ -284,7 +279,7 @@ public class DownloadRequest extends MmsRequest { /** * Try downloading via the carrier app. * - * @param context The context + * @param context The context * @param carrierMessagingServicePackage The carrier messaging service handling the download */ public void tryDownloadingByCarrierApp(Context context, String carrierMessagingServicePackage) { @@ -322,10 +317,10 @@ public class DownloadRequest extends MmsRequest { private static Long getId(Context context, String location) { String selection = Telephony.Mms.CONTENT_LOCATION + " = ?"; - String[] selectionArgs = new String[] { location }; + String[] selectionArgs = new String[]{location}; Cursor c = android.database.sqlite.SqliteWrapper.query( context, context.getContentResolver(), - Telephony.Mms.CONTENT_URI, new String[] { Telephony.Mms._ID }, + Telephony.Mms.CONTENT_URI, new String[]{Telephony.Mms._ID}, selection, selectionArgs, null); if (c != null) { try { diff --git a/android-smsmms/src/main/java/com/android/mms/transaction/PushReceiver.java b/android-smsmms/src/main/java/com/android/mms/transaction/PushReceiver.java index aaf964e2f..f8edc5aa7 100755 --- a/android-smsmms/src/main/java/com/android/mms/transaction/PushReceiver.java +++ b/android-smsmms/src/main/java/com/android/mms/transaction/PushReceiver.java @@ -131,10 +131,7 @@ public class PushReceiver extends BroadcastReceiver { // Save the pdu. If we can start downloading the real pdu immediately, // don't allow persist() to create a thread for the notificationInd // because it causes UI jank. - Uri uri = p.persist(pdu, Inbox.CONTENT_URI, - !NotificationTransaction.allowAutoDownload(mContext), - true, - null); + Uri uri = p.persist(pdu, Inbox.CONTENT_URI, true, true, null); String location = getContentLocation(mContext, uri); if (downloadedUrls.contains(location)) { diff --git a/data/src/main/java/com/moez/QKSMS/receiver/MmsReceivedReceiver.kt b/data/src/main/java/com/moez/QKSMS/receiver/MmsReceivedReceiver.kt index fecf096a6..9e340b084 100644 --- a/data/src/main/java/com/moez/QKSMS/receiver/MmsReceivedReceiver.kt +++ b/data/src/main/java/com/moez/QKSMS/receiver/MmsReceivedReceiver.kt @@ -42,4 +42,4 @@ class MmsReceivedReceiver : MmsReceivedReceiver() { } } -} \ No newline at end of file +} -- GitLab From 797f3597258d4dae763a53038e225ab75af4b017 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 28 Jul 2019 00:48:48 -0400 Subject: [PATCH 036/178] Catch error thrown while trying to send message, improve debugging --- .../android/send_message/MmsFileProvider.java | 3 +-- .../QKSMS/repository/MessageRepositoryImpl.kt | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsFileProvider.java b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsFileProvider.java index 9a6384cab..1f55738b5 100755 --- a/android-smsmms/src/main/java/com/klinker/android/send_message/MmsFileProvider.java +++ b/android-smsmms/src/main/java/com/klinker/android/send_message/MmsFileProvider.java @@ -33,8 +33,7 @@ public class MmsFileProvider extends ContentProvider { } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // Don't support queries. return null; } diff --git a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt index d22984605..b10ea6338 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt @@ -304,13 +304,18 @@ class MessageRepositoryImpl @Inject constructor( if (prefs.delivery.get()) pendingIntent else null } - smsManager.sendMultipartTextMessage( - message.address, - null, - parts, - ArrayList(sentIntents), - ArrayList(deliveredIntents) - ) + try { + smsManager.sendMultipartTextMessage( + message.address, + null, + parts, + ArrayList(sentIntents), + ArrayList(deliveredIntents) + ) + } catch (e: IllegalArgumentException) { + Timber.w(e, "Message body lengths: ${parts.map { it.length }}") + markFailed(message.id, Telephony.MmsSms.ERR_TYPE_GENERIC) + } } override fun cancelDelayedSms(id: Long) { -- GitLab From 88dc7840dde4d746a282e3273b426b103cab3b80 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 11 Aug 2019 18:06:34 +0200 Subject: [PATCH 037/178] #1414 - Fix visual glitch with input box in dark theme --- .../src/main/res/layout/compose_activity.xml | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/presentation/src/main/res/layout/compose_activity.xml b/presentation/src/main/res/layout/compose_activity.xml index cdbb3f759..fb2fe75bc 100644 --- a/presentation/src/main/res/layout/compose_activity.xml +++ b/presentation/src/main/res/layout/compose_activity.xml @@ -17,10 +17,10 @@ ~ You should have received a copy of the GNU General Public License ~ along with QKSMS. If not, see . --> - @@ -370,8 +371,8 @@ android:id="@+id/chips" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="4dp" android:layout_marginTop="4dp" + android:layout_marginBottom="4dp" android:scrollbars="vertical" tools:visibility="gone" /> @@ -436,8 +437,8 @@ android:backgroundTint="?attr/bubbleColor" android:elevation="4dp" android:gravity="center_vertical" - android:paddingEnd="8dp" android:paddingStart="8dp" + android:paddingEnd="8dp" android:text="@string/compose_contact_cd" android:textColor="?android:attr/textColorPrimary" app:layout_constraintBottom_toBottomOf="@id/contact" @@ -470,8 +471,8 @@ android:backgroundTint="?attr/bubbleColor" android:elevation="4dp" android:gravity="center_vertical" - android:paddingEnd="8dp" android:paddingStart="8dp" + android:paddingEnd="8dp" android:text="@string/compose_schedule_cd" android:textColor="?android:attr/textColorPrimary" app:layout_constraintBottom_toBottomOf="@id/schedule" @@ -504,8 +505,8 @@ android:backgroundTint="?attr/bubbleColor" android:elevation="4dp" android:gravity="center_vertical" - android:paddingEnd="8dp" android:paddingStart="8dp" + android:paddingEnd="8dp" android:text="@string/compose_gallery_cd" android:textColor="?android:attr/textColorPrimary" app:layout_constraintBottom_toBottomOf="@id/gallery" @@ -538,8 +539,8 @@ android:backgroundTint="?attr/bubbleColor" android:elevation="4dp" android:gravity="center_vertical" - android:paddingEnd="8dp" android:paddingStart="8dp" + android:paddingEnd="8dp" android:text="@string/compose_camera_cd" android:textColor="?android:attr/textColorPrimary" app:layout_constraintBottom_toBottomOf="@id/camera" @@ -550,8 +551,8 @@ android:id="@+id/attach" android:layout_width="44dp" android:layout_height="44dp" - android:layout_marginBottom="8dp" android:layout_marginStart="8dp" + android:layout_marginBottom="8dp" android:background="@drawable/circle" android:contentDescription="@string/compose_attach_cd" android:elevation="4dp" -- GitLab From c69d1b8c9048a740454ab38264ba9fd5b631259b Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 11 Aug 2019 19:36:46 +0200 Subject: [PATCH 038/178] Upgrade to latest Autodispose --- build.gradle | 2 +- presentation/build.gradle | 17 +- .../AndroidLifecycleScopeProvider.java | 166 ------------------ .../AutodisposeAndroidLifecycle.kt | 74 -------- .../LifecycleEventsObservable.java | 124 ------------- .../moez/QKSMS/common/base/QkController.kt | 13 +- .../com/moez/QKSMS/common/base/QkPresenter.kt | 3 +- .../QKSMS/common/base/QkThemedActivity.kt | 4 +- .../moez/QKSMS/common/base/QkViewContract.kt | 7 +- .../com/moez/QKSMS/common/base/QkViewModel.kt | 4 +- .../moez/QKSMS/common/widget/AvatarView.kt | 2 +- .../QKSMS/common/widget/PagerTitleView.kt | 2 +- .../QKSMS/feature/backup/BackupPresenter.kt | 3 +- .../QKSMS/feature/blocked/BlockedViewModel.kt | 4 +- .../QKSMS/feature/compose/ComposeActivity.kt | 4 +- .../QKSMS/feature/compose/ComposeViewModel.kt | 4 +- .../ConversationInfoController.kt | 3 +- .../ConversationInfoPresenter.kt | 3 +- .../ConversationItemTouchCallback.kt | 4 - .../QKSMS/feature/gallery/GalleryViewModel.kt | 4 +- .../moez/QKSMS/feature/main/MainActivity.kt | 9 +- .../moez/QKSMS/feature/main/MainViewModel.kt | 4 +- .../NotificationPrefsActivity.kt | 4 +- .../NotificationPrefsViewModel.kt | 4 +- .../moez/QKSMS/feature/plus/PlusViewModel.kt | 4 +- .../QKSMS/feature/qkreply/QkReplyViewModel.kt | 4 +- .../feature/scheduled/ScheduledViewModel.kt | 4 +- .../feature/settings/SettingsController.kt | 3 +- .../feature/settings/SettingsPresenter.kt | 3 +- .../feature/settings/about/AboutPresenter.kt | 3 +- .../settings/swipe/SwipeActionsController.kt | 3 +- .../settings/swipe/SwipeActionsPresenter.kt | 3 +- .../themepicker/ThemePickerPresenter.kt | 3 +- 33 files changed, 67 insertions(+), 431 deletions(-) delete mode 100644 presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AndroidLifecycleScopeProvider.java delete mode 100644 presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AutodisposeAndroidLifecycle.kt delete mode 100644 presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/LifecycleEventsObservable.java diff --git a/build.gradle b/build.gradle index 5b07340b6..80f55585f 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { ext.androidx_exifinterface_version = '1.0.0' ext.androidx_testrunner_version = '1.1.0-alpha3' ext.androidx_viewpager_version = '1.0.0-alpha01' - ext.autodispose_version = '0.7.0' + ext.autodispose_version = '1.3.0' ext.conductor_version = '2.1.5' ext.dagger_version = "2.16" ext.espresso_version = '3.1.0-alpha3' diff --git a/presentation/build.gradle b/presentation/build.gradle index 2d0140b3c..a09bd23ed 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -56,6 +56,10 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } + kotlinOptions { + jvmTarget = "1.8" + } + lintOptions { abortOnError false } @@ -99,7 +103,7 @@ dependencies { // conductor implementation "com.bluelinelabs:conductor:$conductor_version" - implementation "com.bluelinelabs:conductor-autodispose:$conductor_version" + implementation "com.bluelinelabs:conductor-archlifecycle:$conductor_version" // glide implementation "com.github.bumptech.glide:glide:$glide_version" @@ -116,10 +120,11 @@ dependencies { implementation "com.jakewharton.rxbinding2:rxbinding-support-v4-kotlin:$rxbinding_version" // autodispose - implementation "com.uber.autodispose:autodispose-android-archcomponents-kotlin:$autodispose_version" - implementation "com.uber.autodispose:autodispose-android-archcomponents-test-kotlin:$autodispose_version" - implementation "com.uber.autodispose:autodispose-android-kotlin:$autodispose_version" - implementation "com.uber.autodispose:autodispose-kotlin:$autodispose_version" + implementation "com.uber.autodispose:autodispose-android-archcomponents:$autodispose_version" + implementation "com.uber.autodispose:autodispose-android-archcomponents-test:$autodispose_version" + implementation "com.uber.autodispose:autodispose-android:$autodispose_version" + implementation "com.uber.autodispose:autodispose:$autodispose_version" + implementation "com.uber.autodispose:autodispose-lifecycle:$autodispose_version" // dagger implementation "com.google.dagger:dagger:$dagger_version" @@ -136,12 +141,12 @@ dependencies { }) // realm + implementation 'com.akaita.java:rxjava2-debug:1.2.2' implementation("io.realm:android-adapters:$realm_adapters_version") { transitive = false } kapt "io.realm:realm-annotations:$realm_version" kapt "io.realm:realm-annotations-processor:$realm_version" // rxjava - implementation 'com.akaita.java:rxjava2-debug:1.2.2' implementation "io.reactivex.rxjava2:rxandroid:$rxandroid_version" implementation "io.reactivex.rxjava2:rxjava:$rxjava_version" implementation "io.reactivex.rxjava2:rxkotlin:$rxkotlin_version" diff --git a/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AndroidLifecycleScopeProvider.java b/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AndroidLifecycleScopeProvider.java deleted file mode 100644 index 796927321..000000000 --- a/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AndroidLifecycleScopeProvider.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2017 Moez Bhatti - * - * This file is part of QKSMS. - * - * QKSMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QKSMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QKSMS. If not, see . - */ - -package com.moez.QKSMS.common.androidxcompat; - -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleOwner; -import com.uber.autodispose.LifecycleEndedException; -import com.uber.autodispose.LifecycleScopeProvider; -import io.reactivex.Observable; -import io.reactivex.functions.Function; - -/** - * A {@link LifecycleScopeProvider} that can provide scoping for Android {@link Lifecycle} and - * {@link LifecycleOwner} classes. - *

- *


- *   AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner))
- * 
- */ -public final class AndroidLifecycleScopeProvider - implements LifecycleScopeProvider { - - private static final Function DEFAULT_CORRESPONDING_EVENTS = - new Function() { - @Override public Lifecycle.Event apply(Lifecycle.Event lastEvent) throws Exception { - switch (lastEvent) { - case ON_CREATE: - return Lifecycle.Event.ON_DESTROY; - case ON_START: - return Lifecycle.Event.ON_STOP; - case ON_RESUME: - return Lifecycle.Event.ON_PAUSE; - case ON_PAUSE: - return Lifecycle.Event.ON_STOP; - case ON_STOP: - case ON_DESTROY: - default: - throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent); - } - } - }; - - private final Function boundaryResolver; - - /** - * Creates a {@link AndroidLifecycleScopeProvider} for Android LifecycleOwners. - * - * @param owner the owner to scope for. - * @return a {@link AndroidLifecycleScopeProvider} against this owner. - */ - public static AndroidLifecycleScopeProvider from(LifecycleOwner owner) { - return from(owner.getLifecycle()); - } - - /** - * Creates a {@link AndroidLifecycleScopeProvider} for Android LifecycleOwners. - * - * @param owner the owner to scope for. - * @param untilEvent the event until the scope is valid. - * @return a {@link AndroidLifecycleScopeProvider} against this owner. - */ - public static AndroidLifecycleScopeProvider from( - LifecycleOwner owner, - Lifecycle.Event untilEvent) { - return from(owner.getLifecycle(), untilEvent); - } - - /** - * Creates a {@link AndroidLifecycleScopeProvider} for Android Lifecycles. - * - * @param lifecycle the lifecycle to scope for. - * @return a {@link AndroidLifecycleScopeProvider} against this lifecycle. - */ - public static AndroidLifecycleScopeProvider from(Lifecycle lifecycle) { - return from(lifecycle, DEFAULT_CORRESPONDING_EVENTS); - } - - /** - * Creates a {@link AndroidLifecycleScopeProvider} for Android Lifecycles. - * - * @param lifecycle the lifecycle to scope for. - * @param untilEvent the event until the scope is valid. - * @return a {@link AndroidLifecycleScopeProvider} against this lifecycle. - */ - public static AndroidLifecycleScopeProvider from( - Lifecycle lifecycle, - Lifecycle.Event untilEvent) { - return from(lifecycle, new UntilEventFunction(untilEvent)); - } - - /** - * Creates a {@link AndroidLifecycleScopeProvider} for Android Lifecycles. - * - * @param owner the owner to scope for. - * @param boundaryResolver function that resolves the event boundary. - * @return a {@link AndroidLifecycleScopeProvider} against this owner. - */ - public static AndroidLifecycleScopeProvider from( - LifecycleOwner owner, - Function boundaryResolver) { - return from(owner.getLifecycle(), boundaryResolver); - } - - /** - * Creates a {@link AndroidLifecycleScopeProvider} for Android Lifecycles. - * - * @param lifecycle the lifecycle to scope for. - * @param boundaryResolver function that resolves the event boundary. - * @return a {@link AndroidLifecycleScopeProvider} against this lifecycle. - */ - public static AndroidLifecycleScopeProvider from( - Lifecycle lifecycle, - Function boundaryResolver) { - return new AndroidLifecycleScopeProvider(lifecycle, boundaryResolver); - } - - private final LifecycleEventsObservable lifecycleObservable; - - private AndroidLifecycleScopeProvider(Lifecycle lifecycle, - Function boundaryResolver) { - this.lifecycleObservable = new LifecycleEventsObservable(lifecycle); - this.boundaryResolver = boundaryResolver; - } - - @Override public Observable lifecycle() { - return lifecycleObservable; - } - - @Override public Function correspondingEvents() { - return boundaryResolver; - } - - @Override public Lifecycle.Event peekLifecycle() { - lifecycleObservable.backfillEvents(); - return lifecycleObservable.getValue(); - } - - private static class UntilEventFunction implements Function { - private final Lifecycle.Event untilEvent; - - UntilEventFunction(Lifecycle.Event untilEvent) { - this.untilEvent = untilEvent; - } - - @Override public Lifecycle.Event apply(Lifecycle.Event event) throws Exception { - return untilEvent; - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AutodisposeAndroidLifecycle.kt b/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AutodisposeAndroidLifecycle.kt deleted file mode 100644 index 49e05b7f1..000000000 --- a/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/AutodisposeAndroidLifecycle.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2017 Moez Bhatti - * - * This file is part of QKSMS. - * - * QKSMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QKSMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QKSMS. If not, see . - */ -package com.moez.QKSMS.common.androidxcompat - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.Lifecycle.Event -import androidx.lifecycle.LifecycleOwner -import com.uber.autodispose.LifecycleScopeProvider -import io.reactivex.annotations.CheckReturnValue -import io.reactivex.functions.Function - -/** - * Extension that returns a [LifecycleScopeProvider] for this [LifecycleOwner]. - */ -@CheckReturnValue -inline fun LifecycleOwner.scope(): LifecycleScopeProvider<*> = AndroidLifecycleScopeProvider.from(this) - -/** - * Extension that returns a [LifecycleScopeProvider] for this [LifecycleOwner]. - * - * @param untilEvent the event until the scope is valid. - */ -@CheckReturnValue -inline fun LifecycleOwner.scope(untilEvent: Lifecycle.Event): LifecycleScopeProvider<*> = - AndroidLifecycleScopeProvider.from(this, untilEvent) - -/** - * Extension that returns a [LifecycleScopeProvider] for this [LifecycleOwner]. - * - * @param boundaryResolver function that resolves the event boundary. - */ -@CheckReturnValue -inline fun LifecycleOwner.scope(boundaryResolver: Function): LifecycleScopeProvider<*> = - AndroidLifecycleScopeProvider.from(this, boundaryResolver) - -/** - * Extension that returns a [LifecycleScopeProvider] for this [Lifecycle]. - */ -@CheckReturnValue -inline fun Lifecycle.scope(): LifecycleScopeProvider<*> = AndroidLifecycleScopeProvider.from(this) - -/** - * Extension that returns a [LifecycleScopeProvider] for this [Lifecycle]. - * - * @param untilEvent the event until the scope is valid. - */ -@CheckReturnValue -inline fun Lifecycle.scope(untilEvent: Lifecycle.Event): LifecycleScopeProvider<*> = - AndroidLifecycleScopeProvider.from(this, untilEvent) - -/** - * Extension that returns a [LifecycleScopeProvider] for this [Lifecycle]. - * - * @param boundaryResolver function that resolves the event boundary. - */ -@CheckReturnValue -inline fun Lifecycle.scope(boundaryResolver: Function): LifecycleScopeProvider<*> = - AndroidLifecycleScopeProvider.from(this, boundaryResolver) \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/LifecycleEventsObservable.java b/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/LifecycleEventsObservable.java deleted file mode 100644 index c11ca095b..000000000 --- a/presentation/src/main/java/com/moez/QKSMS/common/androidxcompat/LifecycleEventsObservable.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2017 Moez Bhatti - * - * This file is part of QKSMS. - * - * QKSMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QKSMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QKSMS. If not, see . - */ - -package com.moez.QKSMS.common.androidxcompat; - -import androidx.annotation.Nullable; -import androidx.annotation.RestrictTo; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.Lifecycle.Event; -import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.OnLifecycleEvent; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.android.MainThreadDisposable; -import io.reactivex.subjects.BehaviorSubject; - -import static androidx.annotation.RestrictTo.Scope.LIBRARY; -import static androidx.lifecycle.Lifecycle.Event.ON_CREATE; -import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY; -import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; -import static androidx.lifecycle.Lifecycle.Event.ON_START; -import static com.uber.autodispose.android.internal.AutoDisposeAndroidUtil.isMainThread; - -@RestrictTo(LIBRARY) class LifecycleEventsObservable extends Observable { - - private final Lifecycle lifecycle; - private final BehaviorSubject eventsObservable = BehaviorSubject.create(); - - @SuppressWarnings("CheckReturnValue") LifecycleEventsObservable(Lifecycle lifecycle) { - this.lifecycle = lifecycle; - } - - Event getValue() { - return eventsObservable.getValue(); - } - - /** - * Backfill if already created for boundary checking. We do a trick here for corresponding events - * where we pretend something is created upon initialized state so that it assumes the - * corresponding event is DESTROY. - */ - void backfillEvents() { - @Nullable Lifecycle.Event correspondingEvent; - switch (lifecycle.getCurrentState()) { - case INITIALIZED: - correspondingEvent = ON_CREATE; - break; - case CREATED: - correspondingEvent = ON_START; - break; - case STARTED: - case RESUMED: - correspondingEvent = ON_RESUME; - break; - case DESTROYED: - default: - correspondingEvent = ON_DESTROY; - break; - } - eventsObservable.onNext(correspondingEvent); - } - - @Override protected void subscribeActual(Observer observer) { - ArchLifecycleObserver archObserver = - new ArchLifecycleObserver(lifecycle, observer, eventsObservable); - observer.onSubscribe(archObserver); - if (!isMainThread()) { - observer.onError( - new IllegalStateException("Lifecycles can only be bound to on the main thread!")); - return; - } - lifecycle.addObserver(archObserver); - if (archObserver.isDisposed()) { - lifecycle.removeObserver(archObserver); - } - } - - static final class ArchLifecycleObserver extends MainThreadDisposable - implements LifecycleObserver { - private final Lifecycle lifecycle; - private final Observer observer; - private final BehaviorSubject eventsObservable; - - ArchLifecycleObserver(Lifecycle lifecycle, Observer observer, - BehaviorSubject eventsObservable) { - this.lifecycle = lifecycle; - this.observer = observer; - this.eventsObservable = eventsObservable; - } - - @Override protected void onDispose() { - lifecycle.removeObserver(this); - } - - @OnLifecycleEvent(Event.ON_ANY) - void onStateChange(@SuppressWarnings("unused") LifecycleOwner owner, Event event) { - if (!isDisposed()) { - if (!(event == ON_CREATE && eventsObservable.getValue() == event)) { - // Due to the INITIALIZED->ON_CREATE mapping trick we do in backfill(), - // we fire this conditionally to avoid duplicate CREATE events. - eventsObservable.onNext(event); - } - observer.onNext(event); - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/common/base/QkController.kt b/presentation/src/main/java/com/moez/QKSMS/common/base/QkController.kt index 9c56f119c..deefa8e21 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/base/QkController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/base/QkController.kt @@ -24,15 +24,12 @@ import android.view.ViewGroup import androidx.annotation.LayoutRes import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity -import com.bluelinelabs.conductor.Controller -import com.bluelinelabs.conductor.autodispose.ControllerEvent -import com.bluelinelabs.conductor.autodispose.ControllerScopeProvider -import com.uber.autodispose.LifecycleScopeProvider +import com.bluelinelabs.conductor.archlifecycle.LifecycleController import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.* import kotlinx.android.synthetic.main.toolbar.view.* -abstract class QkController, State, Presenter : QkPresenter> : Controller(), LayoutContainer { +abstract class QkController, State, Presenter : QkPresenter> : LifecycleController(), LayoutContainer { abstract var presenter: Presenter @@ -80,8 +77,4 @@ abstract class QkController, State, Present presenter.onCleared() } - fun scope(): LifecycleScopeProvider { - return ControllerScopeProvider.from(this) - } - -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/moez/QKSMS/common/base/QkPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/common/base/QkPresenter.kt index d2b64c460..7d152ffee 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/base/QkPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/base/QkPresenter.kt @@ -19,7 +19,8 @@ package com.moez.QKSMS.common.base import androidx.annotation.CallSuper -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.subjects.BehaviorSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt b/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt index 122355e20..5a4a2ad27 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt @@ -27,11 +27,11 @@ import android.view.View import androidx.core.view.iterator import androidx.lifecycle.Lifecycle import com.moez.QKSMS.R -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.common.util.extensions.resolveThemeColor import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.rxkotlin.Observables import io.reactivex.subjects.BehaviorSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewContract.kt b/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewContract.kt index f50bb95c7..19ade510c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewContract.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewContract.kt @@ -18,13 +18,10 @@ */ package com.moez.QKSMS.common.base -import com.bluelinelabs.conductor.autodispose.ControllerEvent -import com.uber.autodispose.LifecycleScopeProvider +import androidx.lifecycle.LifecycleOwner -interface QkViewContract { +interface QkViewContract: LifecycleOwner { fun render(state: State) - fun scope(): LifecycleScopeProvider - } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewModel.kt index e73b4a251..c59e75afd 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/base/QkViewModel.kt @@ -20,8 +20,8 @@ package com.moez.QKSMS.common.base import androidx.annotation.CallSuper import androidx.lifecycle.ViewModel -import com.moez.QKSMS.common.androidxcompat.scope -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.subjects.BehaviorSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/AvatarView.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/AvatarView.kt index 1f12c5575..9345d53b5 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/widget/AvatarView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/AvatarView.kt @@ -36,7 +36,7 @@ import com.moez.QKSMS.model.Contact import com.moez.QKSMS.model.Recipient import com.moez.QKSMS.util.GlideApp import com.uber.autodispose.android.ViewScopeProvider -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.autoDisposable import kotlinx.android.synthetic.main.avatar_view.view.* import javax.inject.Inject diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/PagerTitleView.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/PagerTitleView.kt index 870752b46..3f2ff65fe 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/widget/PagerTitleView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/PagerTitleView.kt @@ -31,7 +31,7 @@ import com.moez.QKSMS.common.util.extensions.forEach import com.moez.QKSMS.common.util.extensions.resolveThemeColor import com.moez.QKSMS.injection.appComponent import com.uber.autodispose.android.ViewScopeProvider -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.autoDisposable import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.Subject import kotlinx.android.synthetic.main.tab_view.view.* diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/backup/BackupPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/backup/BackupPresenter.kt index efa479783..3f0174a1a 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/backup/BackupPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/backup/BackupPresenter.kt @@ -28,7 +28,8 @@ import com.moez.QKSMS.common.util.extensions.makeToast import com.moez.QKSMS.interactor.PerformBackup import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.repository.BackupRepository -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import io.reactivex.subjects.BehaviorSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt index d8396c474..7cbc516f0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt @@ -20,14 +20,14 @@ package com.moez.QKSMS.feature.blocked import android.content.Context import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.interactor.MarkUnblocked import com.moez.QKSMS.manager.AnalyticsManager import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.util.Preferences import com.moez.QKSMS.util.tryOrNull -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import javax.inject.Inject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt index 20307ba6d..9ef6f2386 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt @@ -43,7 +43,6 @@ import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding2.view.clicks import com.jakewharton.rxbinding2.widget.textChanges import com.moez.QKSMS.R -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkThemedActivity import com.moez.QKSMS.common.util.DateFormatter import com.moez.QKSMS.common.util.extensions.autoScrollToStart @@ -56,7 +55,8 @@ import com.moez.QKSMS.common.util.extensions.showKeyboard import com.moez.QKSMS.model.Attachment import com.moez.QKSMS.model.Contact import com.moez.QKSMS.model.Message -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import dagger.android.AndroidInjection import io.reactivex.Observable import io.reactivex.subjects.PublishSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt index fb34d22a4..47bddb3d0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt @@ -26,7 +26,6 @@ import android.telephony.SmsMessage import android.view.inputmethod.EditorInfo import com.moez.QKSMS.R import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.BillingManager import com.moez.QKSMS.common.util.ClipboardUtils @@ -60,7 +59,8 @@ import com.moez.QKSMS.repository.MessageRepository import com.moez.QKSMS.util.ActiveSubscriptionObservable import com.moez.QKSMS.util.Preferences import com.moez.QKSMS.util.tryOrNull -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.Observables diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt index f5140e88c..f0de025e6 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt @@ -33,7 +33,8 @@ import com.moez.QKSMS.common.widget.FieldDialog import com.moez.QKSMS.feature.conversationinfo.injection.ConversationInfoModule import com.moez.QKSMS.feature.themepicker.ThemePickerController import com.moez.QKSMS.injection.appComponent -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt index 749a548f4..57c3999e6 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt @@ -30,7 +30,8 @@ import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.model.Conversation import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.MessageRepository -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import io.reactivex.subjects.BehaviorSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationItemTouchCallback.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationItemTouchCallback.kt index 5979ec96c..58f3b0874 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationItemTouchCallback.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversations/ConversationItemTouchCallback.kt @@ -23,15 +23,12 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Paint import androidx.core.graphics.drawable.toBitmap -import androidx.lifecycle.Lifecycle import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.moez.QKSMS.R -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.common.util.extensions.dpToPx import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable import io.reactivex.disposables.CompositeDisposable import io.reactivex.rxkotlin.Observables import io.reactivex.rxkotlin.plusAssign @@ -40,7 +37,6 @@ import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject import javax.inject.Inject - class ConversationItemTouchCallback @Inject constructor( colors: Colors, disposables: CompositeDisposable, diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt index 68033caa9..9d72c07da 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/gallery/GalleryViewModel.kt @@ -20,7 +20,6 @@ package com.moez.QKSMS.feature.gallery import android.content.Context import com.moez.QKSMS.R -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.extensions.makeToast import com.moez.QKSMS.extensions.mapNotNull @@ -28,7 +27,8 @@ import com.moez.QKSMS.interactor.SaveImage import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.MessageRepository -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Flowable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt index 3d58ec996..e08bbbe0e 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt @@ -31,7 +31,6 @@ import android.view.ViewStub import androidx.appcompat.app.ActionBarDrawerToggle import androidx.core.app.ActivityCompat import androidx.core.view.GravityCompat -import androidx.core.view.accessibility.AccessibilityEventCompat.setAction import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders @@ -43,7 +42,6 @@ import com.jakewharton.rxbinding2.widget.textChanges import com.moez.QKSMS.R import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.androidxcompat.drawerOpen -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkThemedActivity import com.moez.QKSMS.common.util.extensions.autoScrollToStart import com.moez.QKSMS.common.util.extensions.dismissKeyboard @@ -56,7 +54,8 @@ import com.moez.QKSMS.feature.changelog.ChangelogDialog import com.moez.QKSMS.feature.conversations.ConversationItemTouchCallback import com.moez.QKSMS.feature.conversations.ConversationsAdapter import com.moez.QKSMS.repository.SyncRepository -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import dagger.android.AndroidInjection import io.reactivex.Observable import io.reactivex.disposables.CompositeDisposable @@ -131,7 +130,7 @@ class MainActivity : QkThemedActivity(), MainView { viewModel.bindView(this) (snackbar as? ViewStub)?.setOnInflateListener { _, _ -> - snackbarButton.clicks().subscribe(snackbarButtonIntent) + snackbarButton.clicks().autoDisposable(scope()).subscribe(snackbarButtonIntent) } (syncing as? ViewStub)?.setOnInflateListener { _, _ -> @@ -149,7 +148,7 @@ class MainActivity : QkThemedActivity(), MainView { recyclerView.layoutManager = LinearLayoutManager(this) // Don't allow clicks to pass through the drawer layout - drawer.clicks().subscribe() + drawer.clicks().autoDisposable(scope()).subscribe() // Set the theme color tint to the recyclerView, progressbar, and FAB theme diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index e3bcb3e1c..f4df70ba0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -21,7 +21,6 @@ package com.moez.QKSMS.feature.main import androidx.recyclerview.widget.ItemTouchHelper import com.moez.QKSMS.R import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.BillingManager import com.moez.QKSMS.extensions.removeAccents @@ -43,7 +42,8 @@ import com.moez.QKSMS.model.SyncLog import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.SyncRepository import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.plusAssign diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsActivity.kt index 4131b87b1..7f2d794ac 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsActivity.kt @@ -30,12 +30,12 @@ import androidx.lifecycle.ViewModelProviders import com.jakewharton.rxbinding2.view.clicks import com.moez.QKSMS.R import com.moez.QKSMS.common.QkDialog -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkThemedActivity import com.moez.QKSMS.common.util.extensions.animateLayoutChanges import com.moez.QKSMS.common.util.extensions.setVisible import com.moez.QKSMS.common.widget.PreferenceView -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import dagger.android.AndroidInjection import io.reactivex.Observable import io.reactivex.subjects.PublishSubject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsViewModel.kt index 4bfbeb44f..6639d4f70 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/notificationprefs/NotificationPrefsViewModel.kt @@ -23,12 +23,12 @@ import android.media.RingtoneManager import android.net.Uri import com.moez.QKSMS.R import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.extensions.mapNotNull import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Flowable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt index eb70e508f..a3475822d 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/plus/PlusViewModel.kt @@ -19,11 +19,11 @@ package com.moez.QKSMS.feature.plus import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.BillingManager import com.moez.QKSMS.manager.AnalyticsManager -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.rxkotlin.plusAssign import javax.inject.Inject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyViewModel.kt index f3dadd6c4..d29c2068c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyViewModel.kt @@ -21,7 +21,6 @@ package com.moez.QKSMS.feature.qkreply import android.telephony.SmsMessage import com.moez.QKSMS.R import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.compat.SubscriptionManagerCompat import com.moez.QKSMS.extensions.asObservable @@ -33,7 +32,8 @@ import com.moez.QKSMS.model.Message import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.repository.MessageRepository import com.moez.QKSMS.util.ActiveSubscriptionObservable -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.Observables import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/scheduled/ScheduledViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/scheduled/ScheduledViewModel.kt index 92bf7dfb9..529c21a60 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/scheduled/ScheduledViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/scheduled/ScheduledViewModel.kt @@ -19,12 +19,12 @@ package com.moez.QKSMS.feature.scheduled import com.moez.QKSMS.common.Navigator -import com.moez.QKSMS.common.androidxcompat.scope import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.BillingManager import com.moez.QKSMS.interactor.SendScheduledMessage import com.moez.QKSMS.repository.ScheduledMessageRepository -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import javax.inject.Inject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt index ffa8f1dd1..0b19f7449 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt @@ -45,7 +45,8 @@ import com.moez.QKSMS.feature.themepicker.ThemePickerController import com.moez.QKSMS.injection.appComponent import com.moez.QKSMS.repository.SyncRepository import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt index 71364159f..208059a4d 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt @@ -30,7 +30,8 @@ import com.moez.QKSMS.interactor.SyncMessages import com.moez.QKSMS.repository.SyncRepository import com.moez.QKSMS.util.NightModeManager import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import timber.log.Timber diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/about/AboutPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/about/AboutPresenter.kt index ab231f71f..9ebc9b689 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/about/AboutPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/about/AboutPresenter.kt @@ -21,7 +21,8 @@ package com.moez.QKSMS.feature.settings.about import com.moez.QKSMS.R import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.base.QkPresenter -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import javax.inject.Inject class AboutPresenter @Inject constructor( diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsController.kt index a93174cbb..8121ad443 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsController.kt @@ -29,7 +29,8 @@ import com.moez.QKSMS.common.util.extensions.animateLayoutChanges import com.moez.QKSMS.common.util.extensions.setBackgroundTint import com.moez.QKSMS.common.util.extensions.setTint import com.moez.QKSMS.injection.appComponent -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.Observable import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsPresenter.kt index 1883e097f..f895b5ae5 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsPresenter.kt @@ -23,7 +23,8 @@ import androidx.annotation.DrawableRes import com.moez.QKSMS.R import com.moez.QKSMS.common.base.QkPresenter import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom import javax.inject.Inject diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/themepicker/ThemePickerPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/themepicker/ThemePickerPresenter.kt index 66ad9b6eb..546380e8d 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/themepicker/ThemePickerPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/themepicker/ThemePickerPresenter.kt @@ -25,7 +25,8 @@ import com.moez.QKSMS.common.util.BillingManager import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.manager.WidgetManager import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.kotlin.autoDisposable +import com.uber.autodispose.android.lifecycle.scope +import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.Observables import io.reactivex.rxkotlin.withLatestFrom import javax.inject.Inject -- GitLab From b7e78b79aafca83355be27b852c12d0f375b8e2b Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 11 Aug 2019 19:37:45 +0200 Subject: [PATCH 039/178] Swap RxJava2Debug for RxDogTag --- build.gradle | 1 + presentation/build.gradle | 4 +++- .../src/main/java/com/moez/QKSMS/common/QKApplication.kt | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 80f55585f..d3ef50861 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,7 @@ buildscript { ext.realm_version = '5.8.0' ext.realm_adapters_version = '3.1.0' ext.rxandroid_version = '2.0.1' + ext.rxdogtag_version = '0.2.0' ext.rxbinding_version = '2.0.0' ext.rxjava_version = '2.1.4' ext.rxkotlin_version = '2.1.0' diff --git a/presentation/build.gradle b/presentation/build.gradle index a09bd23ed..ede264ece 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -141,7 +141,6 @@ dependencies { }) // realm - implementation 'com.akaita.java:rxjava2-debug:1.2.2' implementation("io.realm:android-adapters:$realm_adapters_version") { transitive = false } kapt "io.realm:realm-annotations:$realm_version" kapt "io.realm:realm-annotations-processor:$realm_version" @@ -150,6 +149,9 @@ dependencies { implementation "io.reactivex.rxjava2:rxandroid:$rxandroid_version" implementation "io.reactivex.rxjava2:rxjava:$rxjava_version" implementation "io.reactivex.rxjava2:rxkotlin:$rxkotlin_version" + implementation "com.uber.rxdogtag:rxdogtag:$rxdogtag_version" + implementation "com.uber.rxdogtag:rxdogtag-autodispose:$rxdogtag_version" + // testing androidTestImplementation("androidx.test.espresso:espresso-core:$espresso_version", { diff --git a/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt b/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt index 4c1b8256b..cc9f4f977 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/QKApplication.kt @@ -25,7 +25,6 @@ import android.content.BroadcastReceiver import androidx.core.provider.FontRequest import androidx.emoji.text.EmojiCompat import androidx.emoji.text.FontRequestEmojiCompatConfig -import com.akaita.java.rxjava2debug.RxJava2Debug import com.bugsnag.android.Bugsnag import com.bugsnag.android.Configuration import com.moez.QKSMS.BuildConfig @@ -38,6 +37,8 @@ import com.moez.QKSMS.injection.appComponent import com.moez.QKSMS.manager.AnalyticsManager import com.moez.QKSMS.migration.QkRealmMigration import com.moez.QKSMS.util.NightModeManager +import com.uber.rxdogtag.RxDogTag +import com.uber.rxdogtag.autodispose.AutoDisposeConfigurer import dagger.android.AndroidInjector import dagger.android.DispatchingAndroidInjector import dagger.android.HasActivityInjector @@ -98,7 +99,9 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn Timber.plant(Timber.DebugTree(), BugsnagTree(), CrashlyticsTree(), fileLoggingTree) - RxJava2Debug.enableRxJava2AssemblyTracking(arrayOf("com.moez.QKSMS")) + RxDogTag.builder() + .configureWith(AutoDisposeConfigurer::configure) + .install() } override fun activityInjector(): AndroidInjector { -- GitLab From f5bf212c76ac9517a96998800bfd10ffa7a74697 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 11 Aug 2019 20:33:13 +0200 Subject: [PATCH 040/178] Apply text color directly from theme attr --- .../moez/QKSMS/common/util/TextViewStyler.kt | 20 +++------- .../src/main/res/layout/changelog_dialog.xml | 5 +-- .../main/res/layout/changelog_list_item.xml | 5 +-- .../main/res/layout/chip_input_list_item.xml | 5 +-- .../src/main/res/layout/compose_activity.xml | 9 ++--- .../src/main/res/layout/contact_chip.xml | 9 ++--- .../src/main/res/layout/contact_list_item.xml | 9 ++--- .../res/layout/contact_number_list_item.xml | 5 +-- .../src/main/res/layout/drawer_view.xml | 37 +++++++++---------- .../main/res/layout/main_permission_hint.xml | 7 ++-- .../main/res/layout/message_list_item_in.xml | 15 ++++---- .../main/res/layout/message_list_item_out.xml | 17 ++++----- .../src/main/res/layout/qkreply_activity.xml | 5 +-- .../main/res/layout/qksms_plus_activity.xml | 33 ++++++++--------- .../main/res/layout/scheduled_activity.xml | 15 ++++---- .../src/main/res/layout/search_list_item.xml | 10 ++--- .../src/main/res/layout/theme_picker_hsv.xml | 9 ++--- presentation/src/main/res/values/attrs.xml | 11 ++---- presentation/src/main/res/values/styles.xml | 10 ++--- 19 files changed, 104 insertions(+), 132 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt b/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt index 4ad25a186..cd701a305 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/util/TextViewStyler.kt @@ -27,7 +27,6 @@ import com.moez.QKSMS.common.util.TextViewStyler.Companion.SIZE_SECONDARY import com.moez.QKSMS.common.util.TextViewStyler.Companion.SIZE_TERTIARY import com.moez.QKSMS.common.util.TextViewStyler.Companion.SIZE_TOOLBAR import com.moez.QKSMS.common.util.extensions.getColorCompat -import com.moez.QKSMS.common.util.extensions.resolveThemeColor import com.moez.QKSMS.common.widget.QkEditText import com.moez.QKSMS.common.widget.QkTextView import com.moez.QKSMS.util.Preferences @@ -40,13 +39,10 @@ class TextViewStyler @Inject constructor( ) { companion object { - const val COLOR_PRIMARY = 0 - const val COLOR_SECONDARY = 1 - const val COLOR_TERTIARY = 2 - const val COLOR_PRIMARY_ON_THEME = 3 - const val COLOR_SECONDARY_ON_THEME = 4 - const val COLOR_TERTIARY_ON_THEME = 5 - const val COLOR_THEME = 6 + const val COLOR_THEME = 0 + const val COLOR_PRIMARY_ON_THEME = 1 + const val COLOR_SECONDARY_ON_THEME = 2 + const val COLOR_TERTIARY_ON_THEME = 3 const val SIZE_PRIMARY = 0 const val SIZE_SECONDARY = 1 @@ -75,9 +71,6 @@ class TextViewStyler @Inject constructor( else -> return } setTextColor(when (colorAttr) { - COLOR_PRIMARY -> context.getColorCompat(R.color.textPrimary) - COLOR_SECONDARY -> context.getColorCompat(R.color.textSecondary) - COLOR_TERTIARY -> context.getColorCompat(R.color.textTertiary) COLOR_PRIMARY_ON_THEME -> context.getColorCompat(R.color.textPrimaryDark) COLOR_SECONDARY_ON_THEME -> context.getColorCompat(R.color.textSecondaryDark) COLOR_TERTIARY_ON_THEME -> context.getColorCompat(R.color.textTertiaryDark) @@ -125,13 +118,10 @@ class TextViewStyler @Inject constructor( } setTextColor(when (colorAttr) { - COLOR_PRIMARY -> context.resolveThemeColor(android.R.attr.textColorPrimary) - COLOR_SECONDARY -> context.resolveThemeColor(android.R.attr.textColorSecondary) - COLOR_TERTIARY -> context.resolveThemeColor(android.R.attr.textColorTertiary) + COLOR_THEME -> colors.theme().theme COLOR_PRIMARY_ON_THEME -> colors.theme().textPrimary COLOR_SECONDARY_ON_THEME -> colors.theme().textSecondary COLOR_TERTIARY_ON_THEME -> colors.theme().textTertiary - COLOR_THEME -> colors.theme().theme else -> currentTextColor }) diff --git a/presentation/src/main/res/layout/changelog_dialog.xml b/presentation/src/main/res/layout/changelog_dialog.xml index d0c4e556c..1d24f5bbf 100644 --- a/presentation/src/main/res/layout/changelog_dialog.xml +++ b/presentation/src/main/res/layout/changelog_dialog.xml @@ -1,5 +1,4 @@ - - - @@ -45,8 +44,8 @@ android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" android:layout_marginRight="12dp" + android:textColor="?android:attr/textColorPrimary" android:textStyle="bold" - app:textColor="primary" app:textSize="secondary" tools:text="Moez Bhatti" /> diff --git a/presentation/src/main/res/layout/contact_list_item.xml b/presentation/src/main/res/layout/contact_list_item.xml index 2e0d7dedd..bc6703d2b 100644 --- a/presentation/src/main/res/layout/contact_list_item.xml +++ b/presentation/src/main/res/layout/contact_list_item.xml @@ -1,5 +1,4 @@ - - - - + + diff --git a/presentation/src/main/res/drawable/ic_archive_black_24dp.xml b/presentation/src/main/res/drawable/ic_archive_black_24dp.xml index c5e78c454..53346afd0 100644 --- a/presentation/src/main/res/drawable/ic_archive_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_archive_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 -0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 -0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z" /> diff --git a/presentation/src/main/res/drawable/ic_av_timer_black_24dp.xml b/presentation/src/main/res/drawable/ic_av_timer_black_24dp.xml index 59f377935..e1787230e 100644 --- a/presentation/src/main/res/drawable/ic_av_timer_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_av_timer_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M11,17c0,0.55 0.45,1 1,1s1,-0.45 1,-1 -0.45,-1 -1,-1 -1,0.45 -1,1zM11,3v4h2L13,5.08c3.39,0.49 6,3.39 6,6.92 0,3.87 -3.13,7 -7,7s-7,-3.13 -7,-7c0,-1.68 0.59,-3.22 1.58,-4.42L12,13l1.41,-1.41 -6.8,-6.8v0.02C4.42,6.45 3,9.05 3,12c0,4.97 4.02,9 9,9 4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9h-1zM18,12c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1 0.45,1 1,1 1,-0.45 1,-1zM6,12c0,0.55 0.45,1 1,1s1,-0.45 1,-1 -0.45,-1 -1,-1 -1,0.45 -1,1z" /> diff --git a/presentation/src/main/res/drawable/ic_backup_black_24dp.xml b/presentation/src/main/res/drawable/ic_backup_black_24dp.xml index 2ad4a6dd5..6ed84e448 100644 --- a/presentation/src/main/res/drawable/ic_backup_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_backup_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM14,13v4h-4v-4H7l5,-5 5,5h-3z" /> diff --git a/presentation/src/main/res/drawable/ic_block_black_24dp.xml b/presentation/src/main/res/drawable/ic_block_black_24dp.xml index ce43c792b..c3f491ef7 100644 --- a/presentation/src/main/res/drawable/ic_block_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_block_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4,12c0,-4.42 3.58,-8 8,-8 1.85,0 3.55,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4,13.85 4,12zM12,20c-1.85,0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20,10.15 20,12c0,4.42 -3.58,8 -8,8z" /> diff --git a/presentation/src/main/res/drawable/ic_call_white_24dp.xml b/presentation/src/main/res/drawable/ic_call_white_24dp.xml index aa7bbb8ee..d37e9f4e5 100644 --- a/presentation/src/main/res/drawable/ic_call_white_24dp.xml +++ b/presentation/src/main/res/drawable/ic_call_white_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z" /> diff --git a/presentation/src/main/res/drawable/ic_camera_alt_black_24dp.xml b/presentation/src/main/res/drawable/ic_camera_alt_black_24dp.xml index 5809569a8..4f84c3c74 100644 --- a/presentation/src/main/res/drawable/ic_camera_alt_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_camera_alt_black_24dp.xml @@ -1,5 +1,5 @@ - - - + + + diff --git a/presentation/src/main/res/drawable/ic_cancel_black_24dp.xml b/presentation/src/main/res/drawable/ic_cancel_black_24dp.xml index ef873d4bf..b05db58dd 100755 --- a/presentation/src/main/res/drawable/ic_cancel_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_cancel_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" /> diff --git a/presentation/src/main/res/drawable/ic_chevron_right_black_24dp.xml b/presentation/src/main/res/drawable/ic_chevron_right_black_24dp.xml index d01ba1042..2891855b5 100644 --- a/presentation/src/main/res/drawable/ic_chevron_right_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_chevron_right_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" /> diff --git a/presentation/src/main/res/drawable/ic_clear_all_black_24dp.xml b/presentation/src/main/res/drawable/ic_clear_all_black_24dp.xml index 341c6cb8a..a9c72ce6f 100644 --- a/presentation/src/main/res/drawable/ic_clear_all_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_clear_all_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M5,13h14v-2L5,11v2zM3,17h14v-2L3,15v2zM7,7v2h14L21,7L7,7z" /> diff --git a/presentation/src/main/res/drawable/ic_clear_black_24dp.xml b/presentation/src/main/res/drawable/ic_clear_black_24dp.xml index 68809bc27..2ec0059a6 100644 --- a/presentation/src/main/res/drawable/ic_clear_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_clear_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" /> diff --git a/presentation/src/main/res/drawable/ic_close_black_24dp.xml b/presentation/src/main/res/drawable/ic_close_black_24dp.xml index 68809bc27..2ec0059a6 100644 --- a/presentation/src/main/res/drawable/ic_close_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_close_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" /> diff --git a/presentation/src/main/res/drawable/ic_color_lens_black_24dp.xml b/presentation/src/main/res/drawable/ic_color_lens_black_24dp.xml index 88343a0c1..2979b3a06 100644 --- a/presentation/src/main/res/drawable/ic_color_lens_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_color_lens_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5L16,16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5s1.5,0.67 1.5,1.5S10.33,8 9.5,8zM14.5,8c-0.83,0 -1.5,-0.67 -1.5,-1.5S13.67,5 14.5,5s1.5,0.67 1.5,1.5S15.33,8 14.5,8zM17.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S16.67,9 17.5,9s1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z" /> diff --git a/presentation/src/main/res/drawable/ic_content_copy_black_24dp.xml b/presentation/src/main/res/drawable/ic_content_copy_black_24dp.xml index 5cb4570e7..c4fa4e0c2 100644 --- a/presentation/src/main/res/drawable/ic_content_copy_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_content_copy_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z" /> diff --git a/presentation/src/main/res/drawable/ic_delete_white_24dp.xml b/presentation/src/main/res/drawable/ic_delete_white_24dp.xml index 1ffbab9fd..ca0a7d594 100644 --- a/presentation/src/main/res/drawable/ic_delete_white_24dp.xml +++ b/presentation/src/main/res/drawable/ic_delete_white_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" /> diff --git a/presentation/src/main/res/drawable/ic_drafts_black_24dp.xml b/presentation/src/main/res/drawable/ic_drafts_black_24dp.xml index 7751006e4..c945e2f24 100644 --- a/presentation/src/main/res/drawable/ic_drafts_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_drafts_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M21.99,8c0,-0.72 -0.37,-1.35 -0.94,-1.7L12,1 2.95,6.3C2.38,6.65 2,7.28 2,8v10c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2l-0.01,-10zM12,13L3.74,7.84 12,3l8.26,4.84L12,13z" /> diff --git a/presentation/src/main/res/drawable/ic_event_black_24dp.xml b/presentation/src/main/res/drawable/ic_event_black_24dp.xml index 59a77a5a1..b39e17542 100644 --- a/presentation/src/main/res/drawable/ic_event_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_event_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M17,12h-5v5h5v-5zM16,1v2L8,3L8,1L6,1v2L5,3c-1.11,0 -1.99,0.9 -1.99,2L3,19c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2h-1L18,1h-2zM19,19L5,19L5,8h14v11z" /> diff --git a/presentation/src/main/res/drawable/ic_favorite_black_24dp.xml b/presentation/src/main/res/drawable/ic_favorite_black_24dp.xml index d26c91de6..f66dbb9f9 100644 --- a/presentation/src/main/res/drawable/ic_favorite_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_favorite_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z" /> diff --git a/presentation/src/main/res/drawable/ic_file_download_black_24dp.xml b/presentation/src/main/res/drawable/ic_file_download_black_24dp.xml index 7e5961d34..edc7894e0 100644 --- a/presentation/src/main/res/drawable/ic_file_download_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_file_download_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" /> diff --git a/presentation/src/main/res/drawable/ic_file_upload_black_24dp.xml b/presentation/src/main/res/drawable/ic_file_upload_black_24dp.xml index cd7e004b3..1e7ce2fa3 100644 --- a/presentation/src/main/res/drawable/ic_file_upload_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_file_upload_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M9,16h6v-6h4l-7,-7 -7,7h4zM5,18h14v2L5,20z" /> diff --git a/presentation/src/main/res/drawable/ic_format_size_black_24dp.xml b/presentation/src/main/res/drawable/ic_format_size_black_24dp.xml index 0d3f3ffab..82c4792ac 100644 --- a/presentation/src/main/res/drawable/ic_format_size_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_format_size_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M9,4v3h5v12h3L17,7h5L22,4L9,4zM3,12h3v7h3v-7h3L12,9L3,9v3z" /> diff --git a/presentation/src/main/res/drawable/ic_help_black_24dp.xml b/presentation/src/main/res/drawable/ic_help_black_24dp.xml index 37600c05f..e01b214f3 100644 --- a/presentation/src/main/res/drawable/ic_help_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_help_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z" /> diff --git a/presentation/src/main/res/drawable/ic_history_black_24dp.xml b/presentation/src/main/res/drawable/ic_history_black_24dp.xml index b69690ca1..82a978944 100644 --- a/presentation/src/main/res/drawable/ic_history_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_history_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" /> diff --git a/presentation/src/main/res/drawable/ic_import_export_black_24dp.xml b/presentation/src/main/res/drawable/ic_import_export_black_24dp.xml index 881a526b8..820ba7bc3 100644 --- a/presentation/src/main/res/drawable/ic_import_export_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_import_export_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M9,3L5,6.99h3L8,14h2L10,6.99h3L9,3zM16,17.01L16,10h-2v7.01h-3L15,21l4,-3.99h-3z" /> diff --git a/presentation/src/main/res/drawable/ic_inbox_black_24dp.xml b/presentation/src/main/res/drawable/ic_inbox_black_24dp.xml index 9b18469a1..f0272cdb4 100644 --- a/presentation/src/main/res/drawable/ic_inbox_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_inbox_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,3L4.99,3c-1.11,0 -1.98,0.89 -1.98,2L3,19c0,1.1 0.88,2 1.99,2L19,21c1.1,0 2,-0.9 2,-2L21,5c0,-1.11 -0.9,-2 -2,-2zM19,15h-4c0,1.66 -1.35,3 -3,3s-3,-1.34 -3,-3L4.99,15L4.99,5L19,5v10z" /> diff --git a/presentation/src/main/res/drawable/ic_info_black_24dp.xml b/presentation/src/main/res/drawable/ic_info_black_24dp.xml index 14cd2474d..36ed4eaf4 100644 --- a/presentation/src/main/res/drawable/ic_info_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_info_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z" /> diff --git a/presentation/src/main/res/drawable/ic_insert_photo_black_24dp.xml b/presentation/src/main/res/drawable/ic_insert_photo_black_24dp.xml index 001cb2428..c2a21b5dd 100644 --- a/presentation/src/main/res/drawable/ic_insert_photo_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_insert_photo_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" /> diff --git a/presentation/src/main/res/drawable/ic_invert_colors_black_24dp.xml b/presentation/src/main/res/drawable/ic_invert_colors_black_24dp.xml index b64ef5778..c3bc64e3a 100644 --- a/presentation/src/main/res/drawable/ic_invert_colors_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_invert_colors_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M17.66,7.93L12,2.27 6.34,7.93c-3.12,3.12 -3.12,8.19 0,11.31C7.9,20.8 9.95,21.58 12,21.58c2.05,0 4.1,-0.78 5.66,-2.34 3.12,-3.12 3.12,-8.19 0,-11.31zM12,19.59c-1.6,0 -3.11,-0.62 -4.24,-1.76C6.62,16.69 6,15.19 6,13.59s0.62,-3.11 1.76,-4.24L12,5.1v14.49z" /> diff --git a/presentation/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml b/presentation/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml index 0ac71ea83..7a6065d77 100644 --- a/presentation/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M7.41,7.84L12,12.42l4.59,-4.58L18,9.25l-6,6 -6,-6z" /> diff --git a/presentation/src/main/res/drawable/ic_keyboard_arrow_up_black_24dp.xml b/presentation/src/main/res/drawable/ic_keyboard_arrow_up_black_24dp.xml index 610345625..7a625c27f 100644 --- a/presentation/src/main/res/drawable/ic_keyboard_arrow_up_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_keyboard_arrow_up_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z" /> diff --git a/presentation/src/main/res/drawable/ic_markunread_black_24dp.xml b/presentation/src/main/res/drawable/ic_markunread_black_24dp.xml index dfccf44ab..783b4ee31 100644 --- a/presentation/src/main/res/drawable/ic_markunread_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_markunread_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z" /> diff --git a/presentation/src/main/res/drawable/ic_more_horiz_black_24dp.xml b/presentation/src/main/res/drawable/ic_more_horiz_black_24dp.xml index 090f162f1..797ea991d 100644 --- a/presentation/src/main/res/drawable/ic_more_horiz_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_more_horiz_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" /> diff --git a/presentation/src/main/res/drawable/ic_more_vert_black_24dp.xml b/presentation/src/main/res/drawable/ic_more_vert_black_24dp.xml index f0b30a854..f738148ff 100644 --- a/presentation/src/main/res/drawable/ic_more_vert_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_more_vert_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" /> diff --git a/presentation/src/main/res/drawable/ic_notifications_black_24dp.xml b/presentation/src/main/res/drawable/ic_notifications_black_24dp.xml index 123ac29f0..fcc373d06 100644 --- a/presentation/src/main/res/drawable/ic_notifications_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" /> diff --git a/presentation/src/main/res/drawable/ic_palette_black_24dp.xml b/presentation/src/main/res/drawable/ic_palette_black_24dp.xml index 88343a0c1..2979b3a06 100644 --- a/presentation/src/main/res/drawable/ic_palette_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_palette_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5L16,16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5s1.5,0.67 1.5,1.5S10.33,8 9.5,8zM14.5,8c-0.83,0 -1.5,-0.67 -1.5,-1.5S13.67,5 14.5,5s1.5,0.67 1.5,1.5S15.33,8 14.5,8zM17.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S16.67,9 17.5,9s1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z" /> diff --git a/presentation/src/main/res/drawable/ic_people_black_24dp.xml b/presentation/src/main/res/drawable/ic_people_black_24dp.xml index 0f4e3b15a..91306539f 100644 --- a/presentation/src/main/res/drawable/ic_people_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_people_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z" /> diff --git a/presentation/src/main/res/drawable/ic_person_add_black_24dp.xml b/presentation/src/main/res/drawable/ic_person_add_black_24dp.xml index 3aaf1bfde..78aea7745 100644 --- a/presentation/src/main/res/drawable/ic_person_add_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_person_add_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M15,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM6,10L6,7L4,7v3L1,10v2h3v3h2v-3h3v-2L6,10zM15,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z" /> diff --git a/presentation/src/main/res/drawable/ic_person_black_24dp.xml b/presentation/src/main/res/drawable/ic_person_black_24dp.xml index 9d8f5fbbc..87586bebc 100644 --- a/presentation/src/main/res/drawable/ic_person_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_person_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z" /> diff --git a/presentation/src/main/res/drawable/ic_photo_size_select_actual_black_24dp.xml b/presentation/src/main/res/drawable/ic_photo_size_select_actual_black_24dp.xml index 9ab525056..d7c900379 100644 --- a/presentation/src/main/res/drawable/ic_photo_size_select_actual_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_photo_size_select_actual_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M21,3H3C2,3 1,4 1,5v14c0,1.1 0.9,2 2,2h18c1,0 2,-1 2,-2V5c0,-1 -1,-2 -2,-2zM5,17l3.5,-4.5 2.5,3.01L14.5,11l4.5,6H5z" /> diff --git a/presentation/src/main/res/drawable/ic_pin_black_24dp.xml b/presentation/src/main/res/drawable/ic_pin_black_24dp.xml index 15a783ae3..3602d9d2a 100644 --- a/presentation/src/main/res/drawable/ic_pin_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_pin_black_24dp.xml @@ -1,5 +1,5 @@ - - + + diff --git a/presentation/src/main/res/drawable/ic_radio_button_checked_black_24dp.xml b/presentation/src/main/res/drawable/ic_radio_button_checked_black_24dp.xml index 16a334e99..d4692685e 100644 --- a/presentation/src/main/res/drawable/ic_radio_button_checked_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_radio_button_checked_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" /> diff --git a/presentation/src/main/res/drawable/ic_radio_button_unchecked_black_24dp.xml b/presentation/src/main/res/drawable/ic_radio_button_unchecked_black_24dp.xml index bd4622d73..4225a079c 100644 --- a/presentation/src/main/res/drawable/ic_radio_button_unchecked_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_radio_button_unchecked_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" /> diff --git a/presentation/src/main/res/drawable/ic_reply_white_24dp.xml b/presentation/src/main/res/drawable/ic_reply_white_24dp.xml index c5527cfc7..649cc2b08 100644 --- a/presentation/src/main/res/drawable/ic_reply_white_24dp.xml +++ b/presentation/src/main/res/drawable/ic_reply_white_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z" /> diff --git a/presentation/src/main/res/drawable/ic_send_black_24dp.xml b/presentation/src/main/res/drawable/ic_send_black_24dp.xml index 2ac692601..7cbdd66bf 100644 --- a/presentation/src/main/res/drawable/ic_send_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_send_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" /> diff --git a/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml b/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml index 11c24c5a3..cc092d480 100644 --- a/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_short_text_black_24dp.xml @@ -1,9 +1,27 @@ + + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M4,9h16v2L4,11zM4,13h10v2L4,15z" /> diff --git a/presentation/src/main/res/drawable/ic_sim_card_black_24dp.xml b/presentation/src/main/res/drawable/ic_sim_card_black_24dp.xml index 20daeffd1..862ac6a96 100644 --- a/presentation/src/main/res/drawable/ic_sim_card_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_sim_card_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM14,8h" /> diff --git a/presentation/src/main/res/drawable/ic_smartphone_black_24dp.xml b/presentation/src/main/res/drawable/ic_smartphone_black_24dp.xml index ceb1e5ccd..821a72449 100644 --- a/presentation/src/main/res/drawable/ic_smartphone_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_smartphone_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19H7V5h10v14z" /> diff --git a/presentation/src/main/res/drawable/ic_star_black_24dp.xml b/presentation/src/main/res/drawable/ic_star_black_24dp.xml index 32d8ee49b..a1b975f41 100644 --- a/presentation/src/main/res/drawable/ic_star_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_star_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z" /> diff --git a/presentation/src/main/res/drawable/ic_sync_black_24dp.xml b/presentation/src/main/res/drawable/ic_sync_black_24dp.xml index f1cef21a2..b6347f01d 100644 --- a/presentation/src/main/res/drawable/ic_sync_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_sync_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z" /> diff --git a/presentation/src/main/res/drawable/ic_title_black_24dp.xml b/presentation/src/main/res/drawable/ic_title_black_24dp.xml index dc7ec5d3d..6db01c458 100644 --- a/presentation/src/main/res/drawable/ic_title_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_title_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M5,4v3h5.5v12h3V7H19V4z" /> diff --git a/presentation/src/main/res/drawable/ic_unfold_less_black_24dp.xml b/presentation/src/main/res/drawable/ic_unfold_less_black_24dp.xml index f65d57f36..92ab6b508 100644 --- a/presentation/src/main/res/drawable/ic_unfold_less_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_unfold_less_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M7.41,18.59L8.83,20 12,16.83 15.17,20l1.41,-1.41L12,14l-4.59,4.59zM16.59,5.41L15.17,4 12,7.17 8.83,4 7.41,5.41 12,10l4.59,-4.59z" /> diff --git a/presentation/src/main/res/drawable/ic_unfold_more_black_24dp.xml b/presentation/src/main/res/drawable/ic_unfold_more_black_24dp.xml index d540e6c6d..8aa8c0cd3 100644 --- a/presentation/src/main/res/drawable/ic_unfold_more_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_unfold_more_black_24dp.xml @@ -1,5 +1,5 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M12,5.83L15.17,9l1.41,-1.41L12,3 7.41,7.59 8.83,9 12,5.83zM12,18.17L8.83,15l-1.41,1.41L12,21l4.59,-4.59L15.17,15 12,18.17z" /> diff --git a/presentation/src/main/res/drawable/message_in_first.xml b/presentation/src/main/res/drawable/message_in_first.xml index b3f83bf25..d153c256e 100644 --- a/presentation/src/main/res/drawable/message_in_first.xml +++ b/presentation/src/main/res/drawable/message_in_first.xml @@ -1,6 +1,5 @@ - - - + app:fontProviderAuthority="com.google.android.gms.fonts" + app:fontProviderCerts="@array/com_google_android_gms_fonts_certs" + app:fontProviderPackage="com.google.android.gms" + app:fontProviderQuery="Lato"> diff --git a/presentation/src/main/res/layout/about_controller.xml b/presentation/src/main/res/layout/about_controller.xml index 1c15ce29f..7b7abcb4e 100644 --- a/presentation/src/main/res/layout/about_controller.xml +++ b/presentation/src/main/res/layout/about_controller.xml @@ -1,5 +1,5 @@ - + android:scaleType="centerCrop" + tools:src="@tools:sample/avatars" /> \ No newline at end of file diff --git a/presentation/src/main/res/layout/backup_controller.xml b/presentation/src/main/res/layout/backup_controller.xml index ccda7ae12..6cd2b0b55 100644 --- a/presentation/src/main/res/layout/backup_controller.xml +++ b/presentation/src/main/res/layout/backup_controller.xml @@ -1,6 +1,5 @@ - - - diff --git a/presentation/src/main/res/layout/compose_activity.xml b/presentation/src/main/res/layout/compose_activity.xml index 3286c6473..72021eba0 100644 --- a/presentation/src/main/res/layout/compose_activity.xml +++ b/presentation/src/main/res/layout/compose_activity.xml @@ -1,5 +1,5 @@ - - @@ -97,8 +95,8 @@ - - - - diff --git a/presentation/src/main/res/layout/gallery_image_page.xml b/presentation/src/main/res/layout/gallery_image_page.xml index 625f92a21..3d7a57a50 100644 --- a/presentation/src/main/res/layout/gallery_image_page.xml +++ b/presentation/src/main/res/layout/gallery_image_page.xml @@ -1,6 +1,5 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/layout/gallery_invalid_page.xml b/presentation/src/main/res/layout/gallery_invalid_page.xml index 47f5461a5..82f7c6d6b 100644 --- a/presentation/src/main/res/layout/gallery_invalid_page.xml +++ b/presentation/src/main/res/layout/gallery_invalid_page.xml @@ -1,6 +1,5 @@ - - - - - \ No newline at end of file diff --git a/presentation/src/main/res/layout/group_avatar_view.xml b/presentation/src/main/res/layout/group_avatar_view.xml index ecf6d70d2..9eefbd7f8 100644 --- a/presentation/src/main/res/layout/group_avatar_view.xml +++ b/presentation/src/main/res/layout/group_avatar_view.xml @@ -1,6 +1,5 @@ - - - @@ -81,8 +80,8 @@ android:layout_height="0dp" android:clipChildren="false" android:clipToPadding="false" - android:paddingBottom="8dp" android:paddingTop="8dp" + android:paddingBottom="8dp" app:layout_constraintBottom_toTopOf="@id/bottom" app:layout_constraintTop_toBottomOf="@id/toolbar" tools:listitem="@layout/conversation_list_item" /> diff --git a/presentation/src/main/res/layout/main_permission_hint.xml b/presentation/src/main/res/layout/main_permission_hint.xml index d328da8bb..eaae651d0 100644 --- a/presentation/src/main/res/layout/main_permission_hint.xml +++ b/presentation/src/main/res/layout/main_permission_hint.xml @@ -1,5 +1,5 @@ - @@ -30,8 +29,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingBottom="8dp" - android:paddingTop="8dp"> + android:paddingTop="8dp" + android:paddingBottom="8dp"> diff --git a/presentation/src/main/res/layout/settings_switch_widget.xml b/presentation/src/main/res/layout/settings_switch_widget.xml index 67d21372b..249a457c2 100644 --- a/presentation/src/main/res/layout/settings_switch_widget.xml +++ b/presentation/src/main/res/layout/settings_switch_widget.xml @@ -1,6 +1,5 @@ - - - - - @@ -41,9 +39,9 @@ android:id="@+id/rightTitle" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="16dp" android:layout_marginStart="24dp" android:layout_marginTop="24dp" + android:layout_marginEnd="16dp" android:text="@string/settings_swipe_actions_right" android:textColor="?android:attr/textColorPrimary" app:layout_constraintEnd_toStartOf="@id/rightChange" @@ -80,10 +78,10 @@ android:id="@+id/rightBackground" android:layout_width="match_parent" android:layout_height="84dp" - android:layout_marginBottom="16dp" - android:layout_marginEnd="16dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" android:alpha="0.1" android:background="@drawable/rounded_rectangle_outline_4dp" android:backgroundTint="?android:attr/textColorPrimary" @@ -97,10 +95,10 @@ android:layout_width="96dp" android:layout_height="84dp" android:background="@drawable/rounded_rectangle_left_4dp" - android:paddingBottom="30dp" - android:paddingEnd="48dp" android:paddingStart="24dp" android:paddingTop="30dp" + android:paddingEnd="48dp" + android:paddingBottom="30dp" app:layout_constraintBottom_toBottomOf="@id/rightBackground" app:layout_constraintStart_toStartOf="@id/rightBackground" app:layout_constraintTop_toTopOf="@id/rightBackground" @@ -162,9 +160,9 @@ android:id="@+id/leftTitle" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="16dp" android:layout_marginStart="24dp" android:layout_marginTop="24dp" + android:layout_marginEnd="16dp" android:text="@string/settings_swipe_actions_left" android:textColor="?android:attr/textColorPrimary" app:layout_constraintEnd_toStartOf="@id/leftChange" @@ -201,10 +199,10 @@ android:id="@+id/leftBackground" android:layout_width="match_parent" android:layout_height="84dp" - android:layout_marginBottom="16dp" - android:layout_marginEnd="16dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" android:alpha="0.1" android:background="@drawable/rounded_rectangle_outline_4dp" android:backgroundTint="?android:attr/textColorPrimary" @@ -218,10 +216,10 @@ android:layout_width="96dp" android:layout_height="84dp" android:background="@drawable/rounded_rectangle_right_4dp" - android:paddingBottom="30dp" - android:paddingEnd="24dp" android:paddingStart="48dp" android:paddingTop="30dp" + android:paddingEnd="24dp" + android:paddingBottom="30dp" app:layout_constraintBottom_toBottomOf="@id/leftBackground" app:layout_constraintEnd_toEndOf="@id/leftBackground" app:layout_constraintTop_toTopOf="@id/leftBackground" diff --git a/presentation/src/main/res/layout/tab_view.xml b/presentation/src/main/res/layout/tab_view.xml index 66c546d40..8a15ece3d 100644 --- a/presentation/src/main/res/layout/tab_view.xml +++ b/presentation/src/main/res/layout/tab_view.xml @@ -1,6 +1,5 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/layout/theme_list_item.xml b/presentation/src/main/res/layout/theme_list_item.xml index 346141702..59a67d286 100644 --- a/presentation/src/main/res/layout/theme_list_item.xml +++ b/presentation/src/main/res/layout/theme_list_item.xml @@ -1,6 +1,5 @@ - - - diff --git a/presentation/src/main/res/layout/theme_picker_controller.xml b/presentation/src/main/res/layout/theme_picker_controller.xml index 7b3d7ec70..08ae0b12e 100644 --- a/presentation/src/main/res/layout/theme_picker_controller.xml +++ b/presentation/src/main/res/layout/theme_picker_controller.xml @@ -1,6 +1,5 @@ - - - + android:paddingStart="12dp" + android:paddingEnd="12dp" /> - + - - @@ -41,14 +39,14 @@ android:id="@+id/title" android:layout_width="0dp" android:layout_height="0dp" + android:layout_alignTop="@id/toolbar" android:layout_alignBottom="@id/toolbar" android:layout_alignParentStart="true" - android:layout_alignTop="@id/toolbar" android:layout_toStartOf="@id/compose" android:background="@drawable/ripple" android:gravity="center_vertical" - android:paddingEnd="16dp" android:paddingStart="16dp" + android:paddingEnd="16dp" android:text="@string/app_name" android:textSize="18sp" tools:textColor="@color/textPrimary" /> @@ -57,9 +55,9 @@ android:id="@+id/compose" android:layout_width="48dp" android:layout_height="0dp" + android:layout_alignTop="@id/toolbar" android:layout_alignBottom="@id/toolbar" android:layout_alignParentEnd="true" - android:layout_alignTop="@id/toolbar" android:background="@drawable/ripple" android:padding="12dp" android:src="@drawable/ic_add_black_24dp" @@ -69,15 +67,15 @@ android:id="@+id/conversations" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_alignParentBottom="true" android:layout_below="@id/toolbar" + android:layout_alignParentBottom="true" android:cacheColorHint="#00000000" android:clipChildren="false" android:clipToPadding="false" android:divider="@null" android:dividerHeight="0dp" - android:paddingBottom="8dp" android:paddingTop="8dp" + android:paddingBottom="8dp" tools:listitem="@layout/widget_list_item" /> diff --git a/presentation/src/main/res/layout/widget_list_item.xml b/presentation/src/main/res/layout/widget_list_item.xml index 2d8693bda..2cdaf088a 100755 --- a/presentation/src/main/res/layout/widget_list_item.xml +++ b/presentation/src/main/res/layout/widget_list_item.xml @@ -1,7 +1,7 @@ - + android:paddingBottom="12dp"> @@ -99,8 +98,8 @@ android:id="@+id/snippet" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentStart="true" android:layout_below="@id/name" + android:layout_alignParentStart="true" android:lines="1" android:singleLine="true" android:textSize="14sp" diff --git a/presentation/src/main/res/layout/widget_loading.xml b/presentation/src/main/res/layout/widget_loading.xml index ef5625764..865ef498d 100755 --- a/presentation/src/main/res/layout/widget_loading.xml +++ b/presentation/src/main/res/layout/widget_loading.xml @@ -1,6 +1,5 @@ - - - diff --git a/presentation/src/main/res/menu/compose.xml b/presentation/src/main/res/menu/compose.xml index eeeffebb8..d8782749d 100644 --- a/presentation/src/main/res/menu/compose.xml +++ b/presentation/src/main/res/menu/compose.xml @@ -1,5 +1,5 @@ Date: Sun, 11 Aug 2019 22:57:34 +0200 Subject: [PATCH 042/178] Fix theme not updating when going back to settings --- .../moez/QKSMS/feature/settings/SettingsPresenter.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt index 208059a4d..dd5d6bbdc 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt @@ -40,19 +40,20 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject class SettingsPresenter @Inject constructor( + colors: Colors, + syncRepo: SyncRepository, private val context: Context, private val billingManager: BillingManager, - private val colors: Colors, private val dateFormatter: DateFormatter, private val navigator: Navigator, private val nightModeManager: NightModeManager, private val prefs: Preferences, - private val syncMessages: SyncMessages, - private val syncRepo: SyncRepository -) : QkPresenter(SettingsState(theme = colors.theme().theme)) { + private val syncMessages: SyncMessages +) : QkPresenter(SettingsState()) { init { - newState { copy(theme = colors.theme().theme) } + disposables += colors.themeObservable() + .subscribe { theme -> newState { copy(theme = theme.theme) } } val nightModeLabels = context.resources.getStringArray(R.array.night_modes) disposables += prefs.nightMode.asObservable() -- GitLab From be20f19c828a19377d5f0c566161b0286b47f4f9 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 12 Aug 2019 01:21:03 +0200 Subject: [PATCH 043/178] #1425 - Add support for system dark mode on Android Q --- .../com/moez/QKSMS/util/NightModeManager.kt | 43 +++++++-- .../java/com/moez/QKSMS/util/Preferences.kt | 26 ++++- presentation/src/main/AndroidManifest.xml | 6 +- .../QKSMS/common/base/QkThemedActivity.kt | 32 ++----- .../com/moez/QKSMS/common/widget/QkSwitch.kt | 29 ++---- .../QKSMS/feature/qkreply/QkReplyActivity.kt | 7 +- .../feature/settings/SettingsController.kt | 9 +- .../feature/settings/SettingsPresenter.kt | 4 +- .../src/main/res/values-night-v23/themes.xml | 27 ++++++ .../src/main/res/values-night-v27/themes.xml | 28 ++++++ .../src/main/res/values-night/themes.xml | 88 +++++++++++++++++ .../src/main/res/values-v23/themes.xml | 4 +- .../src/main/res/values-v27/themes.xml | 4 +- presentation/src/main/res/values/strings.xml | 1 + presentation/src/main/res/values/themes.xml | 96 ++++++------------- 15 files changed, 266 insertions(+), 138 deletions(-) create mode 100644 presentation/src/main/res/values-night-v23/themes.xml create mode 100644 presentation/src/main/res/values-night-v27/themes.xml create mode 100644 presentation/src/main/res/values-night/themes.xml diff --git a/data/src/main/java/com/moez/QKSMS/util/NightModeManager.kt b/data/src/main/java/com/moez/QKSMS/util/NightModeManager.kt index 4ecaa1ebd..243bfb53c 100644 --- a/data/src/main/java/com/moez/QKSMS/util/NightModeManager.kt +++ b/data/src/main/java/com/moez/QKSMS/util/NightModeManager.kt @@ -22,6 +22,7 @@ import android.app.AlarmManager import android.app.PendingIntent import android.content.Context import android.content.Intent +import androidx.appcompat.app.AppCompatDelegate import com.moez.QKSMS.manager.WidgetManager import com.moez.QKSMS.receiver.NightModeReceiver import java.text.SimpleDateFormat @@ -38,17 +39,33 @@ class NightModeManager @Inject constructor( ) { fun updateCurrentTheme() { - // If night mode is not on auto, then there's nothing to do here - if (prefs.nightMode.get() != Preferences.NIGHT_MODE_AUTO) { - return + when (prefs.nightMode.get()) { + Preferences.NIGHT_MODE_SYSTEM -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) + } + + Preferences.NIGHT_MODE_OFF -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + } + + Preferences.NIGHT_MODE_ON -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + } + + Preferences.NIGHT_MODE_AUTO -> { + val nightStartTime = getPreviousInstanceOfTime(prefs.nightStart.get()) + val nightEndTime = getPreviousInstanceOfTime(prefs.nightEnd.get()) + + // If the last nightStart was more recent than the last nightEnd, then it's night time + val night = nightStartTime > nightEndTime + prefs.night.set(night) + AppCompatDelegate.setDefaultNightMode(when (night) { + true -> AppCompatDelegate.MODE_NIGHT_YES + false -> AppCompatDelegate.MODE_NIGHT_NO + }) + widgetManager.updateTheme() + } } - - val nightStartTime = getPreviousInstanceOfTime(prefs.nightStart.get()) - val nightEndTime = getPreviousInstanceOfTime(prefs.nightEnd.get()) - - // If the last nightStart was more recent than the last nightEnd, then it's night time - prefs.night.set(nightStartTime > nightEndTime) - widgetManager.updateTheme() } fun updateNightMode(mode: Int) { @@ -57,6 +74,12 @@ class NightModeManager @Inject constructor( // If it's not on auto mode, set the appropriate night mode if (mode != Preferences.NIGHT_MODE_AUTO) { prefs.night.set(mode == Preferences.NIGHT_MODE_ON) + AppCompatDelegate.setDefaultNightMode(when (mode) { + Preferences.NIGHT_MODE_OFF -> AppCompatDelegate.MODE_NIGHT_NO + Preferences.NIGHT_MODE_ON -> AppCompatDelegate.MODE_NIGHT_YES + Preferences.NIGHT_MODE_SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM + else -> AppCompatDelegate.MODE_NIGHT_NO + }) widgetManager.updateTheme() } diff --git a/data/src/main/java/com/moez/QKSMS/util/Preferences.kt b/data/src/main/java/com/moez/QKSMS/util/Preferences.kt index 53437b2d7..68a0d42dc 100644 --- a/data/src/main/java/com/moez/QKSMS/util/Preferences.kt +++ b/data/src/main/java/com/moez/QKSMS/util/Preferences.kt @@ -29,9 +29,10 @@ import javax.inject.Singleton class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) { companion object { - const val NIGHT_MODE_OFF = 0 - const val NIGHT_MODE_ON = 1 - const val NIGHT_MODE_AUTO = 2 + const val NIGHT_MODE_SYSTEM = 0 + const val NIGHT_MODE_OFF = 1 + const val NIGHT_MODE_ON = 2 + const val NIGHT_MODE_AUTO = 3 const val TEXT_SIZE_SMALL = 0 const val TEXT_SIZE_NORMAL = 1 @@ -66,7 +67,10 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) val canUseSubId = rxPrefs.getBoolean("canUseSubId", true) // User configurable - val nightMode = rxPrefs.getInteger("nightModeSummary", NIGHT_MODE_OFF) + val nightMode = rxPrefs.getInteger("nightMode", when (Build.VERSION.SDK_INT >= 29) { + true -> NIGHT_MODE_SYSTEM + false -> NIGHT_MODE_OFF + }) val nightStart = rxPrefs.getString("nightStart", "18:00") val nightEnd = rxPrefs.getString("nightEnd", "6:00") val black = rxPrefs.getBoolean("black", false) @@ -90,6 +94,20 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) val logging = rxPrefs.getBoolean("logging", false) val version = rxPrefs.getInteger("version", 0) + init { + // Migrate from old night mode preference to new one, now that we support android Q night mode + val nightModeSummary = rxPrefs.getInteger("nightModeSummary") + if (nightModeSummary.isSet) { + nightMode.set(when (nightModeSummary.get()) { + 0 -> NIGHT_MODE_OFF + 1 -> NIGHT_MODE_ON + 2 -> NIGHT_MODE_AUTO + else -> NIGHT_MODE_OFF + }) + nightModeSummary.delete() + } + } + fun theme(threadId: Long = 0): Preference { val default = rxPrefs.getInteger("theme", 0xFF0097A7.toInt()) diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index 8f164b003..7b183e5e2 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -41,7 +41,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" - android:theme="@style/AppThemeDark"> + android:theme="@style/AppLaunchTheme"> + android:theme="@style/AppTheme" /> @@ -104,7 +104,7 @@ android:name=".feature.qkreply.QkReplyActivity" android:excludeFromRecents="true" android:taskAffinity="" - android:theme="@style/AppThemeLightDialog" + android:theme="@style/AppThemeDialog" android:windowSoftInputMode="adjustResize" /> diff --git a/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt b/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt index 5a4a2ad27..da9890fef 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/base/QkThemedActivity.kt @@ -23,7 +23,6 @@ import android.app.ActivityManager import android.graphics.BitmapFactory import android.os.Build import android.os.Bundle -import android.view.View import androidx.core.view.iterator import androidx.lifecycle.Lifecycle import com.moez.QKSMS.R @@ -33,10 +32,12 @@ import com.moez.QKSMS.util.Preferences import com.uber.autodispose.android.lifecycle.scope import com.uber.autodispose.autoDisposable import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.Observables import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.Subject import kotlinx.android.synthetic.main.toolbar.* +import java.util.concurrent.TimeUnit import javax.inject.Inject /** @@ -65,29 +66,17 @@ abstract class QkThemedActivity : QkActivity() { @SuppressLint("InlinedApi") override fun onCreate(savedInstanceState: Bundle?) { - - val night = prefs.night.get() - val black = prefs.black.get() - setTheme(getActivityThemeRes(night, black)) - + setTheme(getActivityThemeRes(prefs.black.get())) super.onCreate(savedInstanceState) // When certain preferences change, we need to recreate the activity - Observable.merge( - listOf(prefs.night, prefs.black, prefs.textSize, prefs.systemFont).map { it.asObservable().skip(1) }) + val triggers = listOf(prefs.nightMode, prefs.night, prefs.black, prefs.textSize, prefs.systemFont) + Observable.merge(triggers.map { it.asObservable().skip(1) }) + .debounce(400, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) .autoDisposable(scope()) .subscribe { recreate() } - // Set the color for the status bar icons - // If night mode, or no dark icons supported, use light icons - // If night mode and only dark status icons supported, use dark status icons - // If night mode and all dark icons supported, use all dark icons - window.decorView.systemUiVisibility = when { - night || Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> 0 - Build.VERSION.SDK_INT < Build.VERSION_CODES.O -> View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR - else -> View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR - } - // Some devices don't let you modify android.R.attr.navigationBarColor if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { window.navigationBarColor = resolveThemeColor(android.R.attr.windowBackground) @@ -127,10 +116,9 @@ abstract class QkThemedActivity : QkActivity() { /** * This can be overridden in case an activity does not want to use the default themes */ - open fun getActivityThemeRes(night: Boolean, black: Boolean) = when { - night && black -> R.style.AppThemeBlack - night && !black -> R.style.AppThemeDark - else -> R.style.AppThemeLight + open fun getActivityThemeRes(black: Boolean) = when { + black -> R.style.AppTheme_Black + else -> R.style.AppTheme } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/QkSwitch.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/QkSwitch.kt index e58a7bf00..500377d84 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/widget/QkSwitch.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/QkSwitch.kt @@ -24,7 +24,7 @@ import android.util.AttributeSet import androidx.appcompat.widget.SwitchCompat import com.moez.QKSMS.R import com.moez.QKSMS.common.util.Colors -import com.moez.QKSMS.common.util.extensions.getColorCompat +import com.moez.QKSMS.common.util.extensions.resolveThemeColor import com.moez.QKSMS.common.util.extensions.withAlpha import com.moez.QKSMS.injection.appComponent import com.moez.QKSMS.util.Preferences @@ -50,26 +50,15 @@ class QkSwitch @JvmOverloads constructor(context: Context, attrs: AttributeSet? intArrayOf(android.R.attr.state_checked), intArrayOf()) - val themeColor = colors.theme().theme + thumbTintList = ColorStateList(states, intArrayOf( + context.resolveThemeColor(R.attr.switchThumbDisabled), + colors.theme().theme, + context.resolveThemeColor(R.attr.switchThumbEnabled))) - val switchThumbEnabled: Int = prefs.night.get() - .let { night -> if (night) R.color.switchThumbEnabledDark else R.color.switchThumbEnabledLight } - .let { res -> context.getColorCompat(res) } - - val switchThumbDisabled: Int = prefs.night.get() - .let { night -> if (night) R.color.switchThumbDisabledDark else R.color.switchThumbDisabledLight } - .let { res -> context.getColorCompat(res) } - - val switchTrackEnabled: Int = prefs.night.get() - .let { night -> if (night) R.color.switchTrackEnabledDark else R.color.switchTrackEnabledLight } - .let { res -> context.getColorCompat(res) } - - val switchTrackDisabled: Int = prefs.night.get() - .let { night -> if (night) R.color.switchTrackDisabledDark else R.color.switchTrackDisabledLight } - .let { res -> context.getColorCompat(res) } - - thumbTintList = ColorStateList(states, intArrayOf(switchThumbDisabled, themeColor, switchThumbEnabled)) - trackTintList = ColorStateList(states, intArrayOf(switchTrackDisabled, themeColor.withAlpha(0x4D), switchTrackEnabled)) + trackTintList = ColorStateList(states, intArrayOf( + context.resolveThemeColor(R.attr.switchTrackDisabled), + colors.theme().theme.withAlpha(0x4D), + context.resolveThemeColor(R.attr.switchTrackEnabled))) } } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyActivity.kt index f141efcef..ead2fe26e 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/qkreply/QkReplyActivity.kt @@ -123,10 +123,9 @@ class QkReplyActivity : QkThemedActivity(), QkReplyView { return true } - override fun getActivityThemeRes(night: Boolean, black: Boolean) = when { - night && black -> R.style.AppThemeBlackDialog - night && !black -> R.style.AppThemeDarkDialog - else -> R.style.AppThemeLightDialog + override fun getActivityThemeRes(black: Boolean) = when { + black -> R.style.AppThemeDialog_Black + else -> R.style.AppThemeDialog } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt index 0b19f7449..8f8bd6994 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsController.kt @@ -21,6 +21,7 @@ package com.moez.QKSMS.feature.settings import android.animation.ObjectAnimator import android.app.TimePickerDialog import android.content.Context +import android.os.Build import android.text.format.DateFormat import android.view.View import androidx.core.view.isVisible @@ -30,6 +31,7 @@ import com.jakewharton.rxbinding2.view.clicks import com.jakewharton.rxbinding2.view.longClicks import com.moez.QKSMS.BuildConfig import com.moez.QKSMS.R +import com.moez.QKSMS.common.MenuItem import com.moez.QKSMS.common.QkChangeHandler import com.moez.QKSMS.common.QkDialog import com.moez.QKSMS.common.base.QkController @@ -91,7 +93,12 @@ class SettingsController : QkController= 29) { + true -> nightModeDialog.adapter.setData(R.array.night_modes) + false -> nightModeDialog.adapter.data = context.resources.getStringArray(R.array.night_modes) + .mapIndexed { index, title -> MenuItem(title, index) } + .drop(1) + } textSizeDialog.adapter.setData(R.array.text_sizes) sendDelayDialog.adapter.setData(R.array.delayed_sending_labels) mmsSizeDialog.adapter.setData(R.array.mms_sizes, R.array.mms_sizes_ids) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt index dd5d6bbdc..eb25fc33c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/SettingsPresenter.kt @@ -49,7 +49,9 @@ class SettingsPresenter @Inject constructor( private val nightModeManager: NightModeManager, private val prefs: Preferences, private val syncMessages: SyncMessages -) : QkPresenter(SettingsState()) { +) : QkPresenter(SettingsState( + nightModeId = prefs.nightMode.get() +)) { init { disposables += colors.themeObservable() diff --git a/presentation/src/main/res/values-night-v23/themes.xml b/presentation/src/main/res/values-night-v23/themes.xml new file mode 100644 index 000000000..3adbc7c01 --- /dev/null +++ b/presentation/src/main/res/values-night-v23/themes.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/presentation/src/main/res/values-night-v27/themes.xml b/presentation/src/main/res/values-night-v27/themes.xml new file mode 100644 index 000000000..b9c409bd8 --- /dev/null +++ b/presentation/src/main/res/values-night-v27/themes.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/presentation/src/main/res/values-night/themes.xml b/presentation/src/main/res/values-night/themes.xml new file mode 100644 index 000000000..97e52ecc6 --- /dev/null +++ b/presentation/src/main/res/values-night/themes.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/values-v23/themes.xml b/presentation/src/main/res/values-v23/themes.xml index 6ce2d43ce..505f8f30c 100644 --- a/presentation/src/main/res/values-v23/themes.xml +++ b/presentation/src/main/res/values-v23/themes.xml @@ -19,9 +19,9 @@ - - \ No newline at end of file +
diff --git a/presentation/src/main/res/values-v27/themes.xml b/presentation/src/main/res/values-v27/themes.xml index 368088327..7ba93f2ed 100644 --- a/presentation/src/main/res/values-v27/themes.xml +++ b/presentation/src/main/res/values-v27/themes.xml @@ -19,11 +19,11 @@ - - \ No newline at end of file + diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 9af96628b..1b28344d1 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -343,6 +343,7 @@ The message to %s failed to send + System Disabled Always on Automatic diff --git a/presentation/src/main/res/values/themes.xml b/presentation/src/main/res/values/themes.xml index d897b24d6..7a2a5a65d 100644 --- a/presentation/src/main/res/values/themes.xml +++ b/presentation/src/main/res/values/themes.xml @@ -1,4 +1,5 @@ - - - - - - - - - - - - - - - - - + + - -