diff --git a/data/src/main/java/com/moez/QKSMS/migration/QkRealmMigration.kt b/data/src/main/java/com/moez/QKSMS/migration/QkRealmMigration.kt index 74f3ad66..c8dc96b9 100644 --- a/data/src/main/java/com/moez/QKSMS/migration/QkRealmMigration.kt +++ b/data/src/main/java/com/moez/QKSMS/migration/QkRealmMigration.kt @@ -36,7 +36,7 @@ class QkRealmMigration @Inject constructor( ) : RealmMigration { companion object { - const val SchemaVersion: Long = 9 + const val SchemaVersion: Long = 10 } @SuppressLint("ApplySharedPref") @@ -193,6 +193,36 @@ class QkRealmMigration @Inject constructor( version++ } + if (version == 9L) { + val migrateNotificationAction = { pref: Int -> + when (pref) { + 1 -> Preferences.NOTIFICATION_ACTION_READ + 2 -> Preferences.NOTIFICATION_ACTION_REPLY + 3 -> Preferences.NOTIFICATION_ACTION_CALL + 4 -> Preferences.NOTIFICATION_ACTION_DELETE + else -> pref + } + } + + val migrateSwipeAction = { pref: Int -> + when (pref) { + 2 -> Preferences.SWIPE_ACTION_DELETE + 3 -> Preferences.SWIPE_ACTION_CALL + 4 -> Preferences.SWIPE_ACTION_READ + 5 -> Preferences.SWIPE_ACTION_UNREAD + else -> pref + } + } + + if (prefs.notifAction1.isSet) prefs.notifAction1.set(migrateNotificationAction(prefs.notifAction1.get())) + if (prefs.notifAction2.isSet) prefs.notifAction2.set(migrateNotificationAction(prefs.notifAction2.get())) + if (prefs.notifAction3.isSet) prefs.notifAction3.set(migrateNotificationAction(prefs.notifAction3.get())) + if (prefs.swipeLeft.isSet) prefs.swipeLeft.set(migrateSwipeAction(prefs.swipeLeft.get())) + if (prefs.swipeRight.isSet) prefs.swipeRight.set(migrateSwipeAction(prefs.swipeRight.get())) + + version++ + } + check(version >= newVersion) { "Migration missing from v$oldVersion to v$newVersion" } } diff --git a/data/src/main/java/com/moez/QKSMS/receiver/BlockThreadReceiver.kt b/data/src/main/java/com/moez/QKSMS/receiver/BlockThreadReceiver.kt new file mode 100644 index 00000000..68143ed8 --- /dev/null +++ b/data/src/main/java/com/moez/QKSMS/receiver/BlockThreadReceiver.kt @@ -0,0 +1,52 @@ +/* + * 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.receiver + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import com.moez.QKSMS.blocking.BlockingClient +import com.moez.QKSMS.interactor.MarkBlocked +import com.moez.QKSMS.repository.ConversationRepository +import com.moez.QKSMS.util.Preferences +import dagger.android.AndroidInjection +import javax.inject.Inject + +class BlockThreadReceiver : BroadcastReceiver() { + + @Inject lateinit var blockingClient: BlockingClient + @Inject lateinit var conversationRepo: ConversationRepository + @Inject lateinit var markBlocked: MarkBlocked + @Inject lateinit var prefs: Preferences + + override fun onReceive(context: Context, intent: Intent) { + AndroidInjection.inject(this, context) + + val pendingResult = goAsync() + val threadId = intent.getLongExtra("threadId", 0) + val conversation = conversationRepo.getConversation(threadId)!! + val blockingManager = prefs.blockingManager.get() + + blockingClient + .block(conversation.recipients.map { it.address }) + .andThen(markBlocked.buildObservable(MarkBlocked.Params(listOf(threadId), blockingManager, null))) + .subscribe { pendingResult.finish() } + } + +} diff --git a/data/src/main/java/com/moez/QKSMS/receiver/MarkArchivedReceiver.kt b/data/src/main/java/com/moez/QKSMS/receiver/MarkArchivedReceiver.kt new file mode 100644 index 00000000..55fdf232 --- /dev/null +++ b/data/src/main/java/com/moez/QKSMS/receiver/MarkArchivedReceiver.kt @@ -0,0 +1,40 @@ +/* + * 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.receiver + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import com.moez.QKSMS.interactor.MarkArchived +import dagger.android.AndroidInjection +import javax.inject.Inject + +class MarkArchivedReceiver : BroadcastReceiver() { + + @Inject lateinit var markArchived: MarkArchived + + override fun onReceive(context: Context, intent: Intent) { + AndroidInjection.inject(this, context) + + val pendingResult = goAsync() + val threadId = intent.getLongExtra("threadId", 0) + markArchived.execute(listOf(threadId)) { pendingResult.finish() } + } + +} \ No newline at end of file diff --git a/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt b/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt index 070884ad..92794caf 100644 --- a/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt +++ b/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt @@ -52,10 +52,12 @@ class Preferences @Inject constructor( const val NOTIFICATION_PREVIEWS_NONE = 2 const val NOTIFICATION_ACTION_NONE = 0 - const val NOTIFICATION_ACTION_READ = 1 - const val NOTIFICATION_ACTION_REPLY = 2 - const val NOTIFICATION_ACTION_CALL = 3 - const val NOTIFICATION_ACTION_DELETE = 4 + const val NOTIFICATION_ACTION_ARCHIVE = 1 + const val NOTIFICATION_ACTION_DELETE = 2 + const val NOTIFICATION_ACTION_BLOCK = 3 + const val NOTIFICATION_ACTION_CALL = 4 + const val NOTIFICATION_ACTION_READ = 5 + const val NOTIFICATION_ACTION_REPLY = 6 const val SEND_DELAY_NONE = 0 const val SEND_DELAY_SHORT = 1 @@ -65,9 +67,10 @@ class Preferences @Inject constructor( const val SWIPE_ACTION_NONE = 0 const val SWIPE_ACTION_ARCHIVE = 1 const val SWIPE_ACTION_DELETE = 2 - const val SWIPE_ACTION_CALL = 3 - const val SWIPE_ACTION_READ = 4 - const val SWIPE_ACTION_UNREAD = 5 + const val SWIPE_ACTION_BLOCK = 3 + const val SWIPE_ACTION_CALL = 4 + const val SWIPE_ACTION_READ = 5 + const val SWIPE_ACTION_UNREAD = 6 const val BLOCKING_MANAGER_QKSMS = 0 const val BLOCKING_MANAGER_CC = 1 diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index b082c22f..5813bec9 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -149,6 +149,8 @@ + + diff --git a/presentation/src/main/java/com/moez/QKSMS/common/util/NotificationManagerImpl.kt b/presentation/src/main/java/com/moez/QKSMS/common/util/NotificationManagerImpl.kt index 1ba84dac..5687eee0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/util/NotificationManagerImpl.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/util/NotificationManagerImpl.kt @@ -45,7 +45,9 @@ import com.moez.QKSMS.feature.compose.ComposeActivity import com.moez.QKSMS.feature.qkreply.QkReplyActivity import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.mapper.CursorToPartImpl +import com.moez.QKSMS.receiver.BlockThreadReceiver import com.moez.QKSMS.receiver.DeleteMessagesReceiver +import com.moez.QKSMS.receiver.MarkArchivedReceiver import com.moez.QKSMS.receiver.MarkReadReceiver import com.moez.QKSMS.receiver.MarkSeenReceiver import com.moez.QKSMS.receiver.RemoteMessagingReceiver @@ -227,9 +229,36 @@ class NotificationManagerImpl @Inject constructor( .distinct() .mapNotNull { action -> when (action) { + Preferences.NOTIFICATION_ACTION_ARCHIVE -> { + val intent = Intent(context, MarkArchivedReceiver::class.java).putExtra("threadId", threadId) + val pi = PendingIntent.getBroadcast(context, threadId.toInt() + 30000, intent, + PendingIntent.FLAG_UPDATE_CURRENT) + NotificationCompat.Action.Builder(R.drawable.ic_archive_white_24dp, actionLabels[action], pi) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE).build() + } + + Preferences.NOTIFICATION_ACTION_DELETE -> { + val messageIds = messages.map { it.id }.toLongArray() + val intent = Intent(context, DeleteMessagesReceiver::class.java) + .putExtra("threadId", threadId) + .putExtra("messageIds", messageIds) + val pi = PendingIntent.getBroadcast(context, threadId.toInt() + 40000, intent, + PendingIntent.FLAG_UPDATE_CURRENT) + NotificationCompat.Action.Builder(R.drawable.ic_delete_white_24dp, actionLabels[action], pi) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_DELETE).build() + } + + Preferences.NOTIFICATION_ACTION_BLOCK -> { + val intent = Intent(context, BlockThreadReceiver::class.java).putExtra("threadId", threadId) + val pi = PendingIntent.getBroadcast(context, threadId.toInt() + 50000, intent, + PendingIntent.FLAG_UPDATE_CURRENT) + NotificationCompat.Action.Builder(R.drawable.ic_block_white_24dp, actionLabels[action], pi) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MUTE).build() + } + Preferences.NOTIFICATION_ACTION_READ -> { val intent = Intent(context, MarkReadReceiver::class.java).putExtra("threadId", threadId) - val pi = PendingIntent.getBroadcast(context, threadId.toInt() + 30000, intent, + val pi = PendingIntent.getBroadcast(context, threadId.toInt() + 60000, intent, PendingIntent.FLAG_UPDATE_CURRENT) NotificationCompat.Action.Builder(R.drawable.ic_check_white_24dp, actionLabels[action], pi) .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ).build() @@ -240,7 +269,7 @@ class NotificationManagerImpl @Inject constructor( getReplyAction(threadId) } else { val intent = Intent(context, QkReplyActivity::class.java).putExtra("threadId", threadId) - val pi = PendingIntent.getActivity(context, threadId.toInt() + 40000, intent, + val pi = PendingIntent.getActivity(context, threadId.toInt() + 70000, intent, PendingIntent.FLAG_UPDATE_CURRENT) NotificationCompat.Action .Builder(R.drawable.ic_reply_white_24dp, actionLabels[action], pi) @@ -252,23 +281,12 @@ class NotificationManagerImpl @Inject constructor( val address = conversation.recipients[0]?.address val intentAction = if (permissions.hasCalling()) Intent.ACTION_CALL else Intent.ACTION_DIAL val intent = Intent(intentAction, Uri.parse("tel:$address")) - val pi = PendingIntent.getActivity(context, threadId.toInt() + 50000, intent, + val pi = PendingIntent.getActivity(context, threadId.toInt() + 80000, intent, PendingIntent.FLAG_UPDATE_CURRENT) NotificationCompat.Action.Builder(R.drawable.ic_call_white_24dp, actionLabels[action], pi) .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_CALL).build() } - Preferences.NOTIFICATION_ACTION_DELETE -> { - val messageIds = messages.map { it.id }.toLongArray() - val intent = Intent(context, DeleteMessagesReceiver::class.java) - .putExtra("threadId", threadId) - .putExtra("messageIds", messageIds) - val pi = PendingIntent.getBroadcast(context, threadId.toInt() + 60000, intent, - PendingIntent.FLAG_UPDATE_CURRENT) - NotificationCompat.Action.Builder(R.drawable.ic_delete_white_24dp, actionLabels[action], pi) - .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_DELETE).build() - } - else -> null } } 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 301bbc02..cb06c213 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 @@ -147,8 +147,9 @@ class ConversationItemTouchCallback @Inject constructor( private fun iconForAction(action: Int, tint: Int): Bitmap? { val res = when (action) { - Preferences.SWIPE_ACTION_ARCHIVE -> R.drawable.ic_archive_black_24dp + Preferences.SWIPE_ACTION_ARCHIVE -> R.drawable.ic_archive_white_24dp Preferences.SWIPE_ACTION_DELETE -> R.drawable.ic_delete_white_24dp + Preferences.SWIPE_ACTION_BLOCK -> R.drawable.ic_block_white_24dp Preferences.SWIPE_ACTION_CALL -> R.drawable.ic_call_white_24dp Preferences.SWIPE_ACTION_READ -> R.drawable.ic_check_white_24dp Preferences.SWIPE_ACTION_UNREAD -> R.drawable.ic_markunread_black_24dp 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 a1e27f93..ac483a77 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 @@ -423,6 +423,7 @@ class MainViewModel @Inject constructor( when (action) { Preferences.SWIPE_ACTION_ARCHIVE -> markArchived.execute(listOf(threadId)) { view.showArchivedSnackbar() } Preferences.SWIPE_ACTION_DELETE -> view.showDeleteDialog(listOf(threadId)) + Preferences.SWIPE_ACTION_BLOCK -> view.showBlockingDialog(listOf(threadId), true) Preferences.SWIPE_ACTION_CALL -> conversationRepo.getConversation(threadId)?.recipients?.firstOrNull()?.address?.let(navigator::makePhoneCall) Preferences.SWIPE_ACTION_READ -> markRead.execute(listOf(threadId)) Preferences.SWIPE_ACTION_UNREAD -> markUnread.execute(listOf(threadId)) 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 f895b5ae..ca02aac6 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 @@ -70,8 +70,9 @@ class SwipeActionsPresenter @Inject constructor( @DrawableRes private fun iconForAction(action: Int) = when (action) { - Preferences.SWIPE_ACTION_ARCHIVE -> R.drawable.ic_archive_black_24dp + Preferences.SWIPE_ACTION_ARCHIVE -> R.drawable.ic_archive_white_24dp Preferences.SWIPE_ACTION_DELETE -> R.drawable.ic_delete_white_24dp + Preferences.SWIPE_ACTION_BLOCK -> R.drawable.ic_block_white_24dp Preferences.SWIPE_ACTION_CALL -> R.drawable.ic_call_white_24dp Preferences.SWIPE_ACTION_READ -> R.drawable.ic_check_white_24dp Preferences.SWIPE_ACTION_UNREAD -> R.drawable.ic_markunread_black_24dp diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsState.kt b/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsState.kt index 37e6c61c..cc7d14ba 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsState.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/settings/swipe/SwipeActionsState.kt @@ -22,9 +22,9 @@ import androidx.annotation.DrawableRes import com.moez.QKSMS.R data class SwipeActionsState( - @DrawableRes val rightIcon: Int = R.drawable.ic_archive_black_24dp, + @DrawableRes val rightIcon: Int = R.drawable.ic_archive_white_24dp, val rightLabel: String = "", - @DrawableRes val leftIcon: Int = R.drawable.ic_archive_black_24dp, + @DrawableRes val leftIcon: Int = R.drawable.ic_archive_white_24dp, val leftLabel: String = "" ) \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/injection/android/BroadcastReceiverBuilderModule.kt b/presentation/src/main/java/com/moez/QKSMS/injection/android/BroadcastReceiverBuilderModule.kt index 7392b44f..77cf2228 100644 --- a/presentation/src/main/java/com/moez/QKSMS/injection/android/BroadcastReceiverBuilderModule.kt +++ b/presentation/src/main/java/com/moez/QKSMS/injection/android/BroadcastReceiverBuilderModule.kt @@ -20,9 +20,11 @@ package com.moez.QKSMS.injection.android import com.moez.QKSMS.feature.widget.WidgetProvider import com.moez.QKSMS.injection.scope.ActivityScope +import com.moez.QKSMS.receiver.BlockThreadReceiver import com.moez.QKSMS.receiver.BootReceiver import com.moez.QKSMS.receiver.DefaultSmsChangedReceiver import com.moez.QKSMS.receiver.DeleteMessagesReceiver +import com.moez.QKSMS.receiver.MarkArchivedReceiver import com.moez.QKSMS.receiver.MarkReadReceiver import com.moez.QKSMS.receiver.MarkSeenReceiver import com.moez.QKSMS.receiver.MmsReceivedReceiver @@ -42,6 +44,10 @@ import dagger.android.ContributesAndroidInjector @Module abstract class BroadcastReceiverBuilderModule { + @ActivityScope + @ContributesAndroidInjector() + abstract fun bindBlockThreadReceiver(): BlockThreadReceiver + @ActivityScope @ContributesAndroidInjector() abstract fun bindBootReceiver(): BootReceiver @@ -54,6 +60,10 @@ abstract class BroadcastReceiverBuilderModule { @ContributesAndroidInjector() abstract fun bindDeleteMessagesReceiver(): DeleteMessagesReceiver + @ActivityScope + @ContributesAndroidInjector + abstract fun bindMarkArchivedReceiver(): MarkArchivedReceiver + @ActivityScope @ContributesAndroidInjector() abstract fun bindMarkReadReceiver(): MarkReadReceiver diff --git a/presentation/src/main/res/drawable/ic_archive_black_24dp.xml b/presentation/src/main/res/drawable/ic_archive_white_24dp.xml similarity index 97% rename from presentation/src/main/res/drawable/ic_archive_black_24dp.xml rename to presentation/src/main/res/drawable/ic_archive_white_24dp.xml index 53346afd..9a621d28 100644 --- a/presentation/src/main/res/drawable/ic_archive_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_archive_white_24dp.xml @@ -22,6 +22,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_block_black_24dp.xml b/presentation/src/main/res/drawable/ic_block_white_24dp.xml similarity index 97% rename from presentation/src/main/res/drawable/ic_block_black_24dp.xml rename to presentation/src/main/res/drawable/ic_block_white_24dp.xml index c3f491ef..82499c84 100644 --- a/presentation/src/main/res/drawable/ic_block_black_24dp.xml +++ b/presentation/src/main/res/drawable/ic_block_white_24dp.xml @@ -22,6 +22,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/layout/conversation_info_settings.xml b/presentation/src/main/res/layout/conversation_info_settings.xml index 50d5903a..9fc371aa 100644 --- a/presentation/src/main/res/layout/conversation_info_settings.xml +++ b/presentation/src/main/res/layout/conversation_info_settings.xml @@ -48,14 +48,14 @@ android:id="@+id/archive" android:layout_width="match_parent" android:layout_height="wrap_content" - app:icon="@drawable/ic_archive_black_24dp" + app:icon="@drawable/ic_archive_white_24dp" app:title="@string/info_archive" /> diff --git a/presentation/src/main/res/layout/swipe_actions_controller.xml b/presentation/src/main/res/layout/swipe_actions_controller.xml index 7be0191b..a5b70680 100644 --- a/presentation/src/main/res/layout/swipe_actions_controller.xml +++ b/presentation/src/main/res/layout/swipe_actions_controller.xml @@ -104,7 +104,7 @@ app:layout_constraintStart_toStartOf="@id/rightBackground" app:layout_constraintTop_toTopOf="@id/rightBackground" tools:backgroundTint="@color/tools_theme" - tools:src="@drawable/ic_archive_black_24dp" + tools:src="@drawable/ic_archive_white_24dp" tools:tint="@color/textPrimaryDark" /> diff --git a/presentation/src/main/res/menu/main.xml b/presentation/src/main/res/menu/main.xml index 557b1ccf..579d60ab 100644 --- a/presentation/src/main/res/menu/main.xml +++ b/presentation/src/main/res/menu/main.xml @@ -22,7 +22,7 @@ @@ -78,7 +78,7 @@ diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 00956fec..9953bcfb 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -243,6 +243,7 @@ None Archive Delete + Block Call Mark read Mark unread @@ -379,10 +380,12 @@ None + Archive + Delete + Block + Call Mark read Reply - Call - Delete Yes