diff --git a/.editorconfig b/.editorconfig index 1606d61f..697c8a67 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,3 @@ -# Copying and distribution of this file, with or without modification, -# are permitted in any medium without royalty provided this notice is -# preserved. This file is offered as-is, without any warranty. -# Names of contributors must not be used to endorse or promote products -# derived from this file without specific prior written permission. - # EditorConfig # http://EditorConfig.org @@ -17,7 +11,12 @@ insert_final_newline = true charset = utf-8 indent_style = space indent_size = 4 -continuation_indent_size = 8 +continuation_indent_size = 4 +max_line_length = 160 [*.xml] continuation_indent_size = 4 + +[*.kt] +ij_kotlin_name_count_to_use_star_import = 5 +ij_kotlin_name_count_to_use_star_import_for_members = 5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6830fd49..0f7b11cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,56 @@ Changelog ========== +Version 5.9.4 *(2021-05-23)* +---------------------------- + + * Adding some UX, stability and translation improvements + +Version 5.9.3 *(2021-04-15)* +---------------------------- + + * Fixed a glitch with current conversation not being updated correctly at incoming messages + * Couple other stability, translation and bugfixes + +Version 5.9.2 *(2021-03-22)* +---------------------------- + + * Fixed an error message wrongly popping up in some cases + * Some stabiliy and translation improvements + +Version 5.9.1 *(2021-03-15)* +---------------------------- + + * Improved search + * Properly handle sending messages from notification Reply action + * Some design, stability and translation improvements + +Version 5.9.0 *(2021-02-16)* +---------------------------- + + * Added Search + * Added a White theme with special handling + * Some stability and translation improvements + +Version 5.8.3 *(2021-01-27)* +---------------------------- + + * Adding some stability and translation improvements + +Version 5.8.2 *(2021-01-18)* +---------------------------- + + * Fixed a glitch with inability to send messages in empty conversations + * Adding a settings item for quickly getting into notification settings + * Some stability and translation improvements + +Version 5.8.1 *(2021-01-11)* +---------------------------- + + * Fixed a glitch with "Sending..." stuck at messages + * Allow selecting a phone numbers at contacts with multiple ones + * Some translation and stability improvements + Version 5.8.0 *(2021-01-02)* ---------------------------- diff --git a/README.md b/README.md index 6ab5c2c8..34019b8a 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,21 @@ It comes with material design and dark theme by default, provides great user exp Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors. -Check out the full suite of Simple Tools here: +Check out the full suite of Simple Tools here: https://www.simplemobiletools.com -Facebook: +Facebook: https://www.facebook.com/simplemobiletools -Reddit: +Reddit: https://www.reddit.com/r/SimpleMobileTools Get it on Google Play Get it on F-Droid
-App image -App image +App image +App image +App image
diff --git a/app/build.gradle b/app/build.gradle index 91ee3631..d6947337 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.simplemobiletools.smsmessenger" minSdkVersion 22 targetSdkVersion 30 - versionCode 25 - versionName "5.8.0" + versionCode 34 + versionName "5.9.4" setProperty("archivesBaseName", "sms-messenger") } @@ -56,14 +56,14 @@ android { } dependencies { - implementation 'com.simplemobiletools:commons:5.32.20' + implementation 'com.github.SimpleMobileTools:Simple-Commons:203ed6018e' implementation 'org.greenrobot:eventbus:3.2.0' implementation 'com.klinkerapps:android-smsmms:5.2.6' - implementation 'com.github.tibbi:IndicatorFastScroll:08f512858a' + implementation 'com.github.tibbi:IndicatorFastScroll:c3de1d040a' implementation "me.leolin:ShortcutBadger:1.1.22" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - kapt "androidx.room:room-compiler:2.2.6" - implementation "androidx.room:room-runtime:2.2.6" - annotationProcessor "androidx.room:room-compiler:2.2.6" + kapt "androidx.room:room-compiler:2.3.0" + implementation "androidx.room:room-runtime:2.3.0" + annotationProcessor "androidx.room:room-compiler:2.3.0" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2e542b99..a40d3d85 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,11 +13,20 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt index 58550850..513e50ac 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt @@ -100,11 +100,13 @@ class MainActivity : SimpleActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) + updateMenuItemColors(menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { + R.id.search -> launchSearch() R.id.settings -> launchSettings() R.id.about -> launchAbout() else -> return super.onOptionsItemSelected(item) @@ -182,7 +184,7 @@ class MainActivity : SimpleActivity() { } private fun getNewConversations(cachedConversations: ArrayList) { - val privateCursor = getMyContactsCursor()?.loadInBackground() + val privateCursor = getMyContactsCursor(false, true)?.loadInBackground() ensureBackgroundThread { val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor) val conversations = getConversations(privateContacts = privateContacts) @@ -245,6 +247,7 @@ class MainActivity : SimpleActivity() { conversations_list.adapter = this } + conversations_list.scheduleLayoutAnimation() conversations_fastscroller.setViews(conversations_list) { val listItem = (conversations_list.adapter as? ConversationsAdapter)?.conversations?.getOrNull(it) conversations_fastscroller.updateBubbleText(listItem?.title ?: "") @@ -295,6 +298,10 @@ class MainActivity : SimpleActivity() { .build() } + private fun launchSearch() { + startActivity(Intent(applicationContext, SearchActivity::class.java)) + } + private fun launchSettings() { startActivity(Intent(applicationContext, SettingsActivity::class.java)) } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/NewConversationActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/NewConversationActivity.kt index ae831c2e..4b226365 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/NewConversationActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/NewConversationActivity.kt @@ -7,8 +7,10 @@ import android.view.Menu import android.view.WindowManager import com.google.gson.Gson import com.reddit.indicatorfastscroll.FastScrollItemIndicator +import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* +import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.SimpleContact import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.adapters.ContactsAdapter @@ -62,7 +64,10 @@ class NewConversationActivity : SimpleActivity() { val searchString = it val filteredContacts = ArrayList() allContacts.forEach { - if (it.phoneNumbers.any { it.contains(searchString, true) } || it.name.contains(searchString, true)) { + if (it.phoneNumbers.any { it.contains(searchString, true) } || + it.name.contains(searchString, true) || + it.name.contains(searchString.normalizeString(), true) || + it.name.normalizeString().contains(searchString, true)) { filteredContacts.add(it) } } @@ -87,9 +92,12 @@ class NewConversationActivity : SimpleActivity() { } } + val adjustedPrimaryColor = getAdjustedPrimaryColor() contacts_letter_fastscroller.textColor = config.textColor.getColorStateList() + contacts_letter_fastscroller.pressedTextColor = adjustedPrimaryColor contacts_letter_fastscroller_thumb.setupWithFastScroller(contacts_letter_fastscroller) - contacts_letter_fastscroller_thumb.textColor = config.primaryColor.getContrastColor() + contacts_letter_fastscroller_thumb?.textColor = adjustedPrimaryColor.getContrastColor() + contacts_letter_fastscroller_thumb?.thumbColor = adjustedPrimaryColor.getColorStateList() } private fun isThirdPartyIntent(): Boolean { @@ -130,18 +138,38 @@ class NewConversationActivity : SimpleActivity() { no_contacts_placeholder.text = getString(placeholderText) } - ContactsAdapter(this, contacts, contacts_list, null) { - hideKeyboard() - launchThreadActivity((it as SimpleContact).phoneNumbers.first(), it.name) - }.apply { - contacts_list.adapter = this + val currAdapter = contacts_list.adapter + if (currAdapter == null) { + ContactsAdapter(this, contacts, contacts_list, null) { + hideKeyboard() + val contact = it as SimpleContact + val phoneNumbers = contact.phoneNumbers + if (phoneNumbers.size > 1) { + val items = ArrayList() + phoneNumbers.forEachIndexed { index, phoneNumber -> + items.add(RadioItem(index, phoneNumber, phoneNumber)) + } + + RadioGroupDialog(this, items) { + launchThreadActivity(it as String, contact.name) + } + } else { + launchThreadActivity(phoneNumbers.first(), contact.name) + } + }.apply { + contacts_list.adapter = this + } + + contacts_list.scheduleLayoutAnimation() + } else { + (currAdapter as ContactsAdapter).updateContacts(contacts) } setupLetterFastscroller(contacts) } private fun fillSuggestedContacts(callback: () -> Unit) { - val privateCursor = getMyContactsCursor()?.loadInBackground() + val privateCursor = getMyContactsCursor(false, true)?.loadInBackground() ensureBackgroundThread { privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor) val suggestions = getSuggestedContacts(privateContacts) @@ -179,7 +207,7 @@ class NewConversationActivity : SimpleActivity() { try { val name = contacts[position].name val character = if (name.isNotEmpty()) name.substring(0, 1) else "" - FastScrollItemIndicator.Text(character.toUpperCase(Locale.getDefault())) + FastScrollItemIndicator.Text(character.toUpperCase(Locale.getDefault()).normalizeString()) } catch (e: Exception) { FastScrollItemIndicator.Text("") } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SearchActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SearchActivity.kt new file mode 100644 index 00000000..a3ea9ad5 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SearchActivity.kt @@ -0,0 +1,146 @@ +package com.simplemobiletools.smsmessenger.activities + +import android.annotation.SuppressLint +import android.app.SearchManager +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.text.TextUtils +import android.util.TypedValue +import android.view.Menu +import android.view.MenuItem +import androidx.appcompat.widget.SearchView +import androidx.core.view.MenuItemCompat +import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.smsmessenger.R +import com.simplemobiletools.smsmessenger.adapters.SearchResultsAdapter +import com.simplemobiletools.smsmessenger.extensions.conversationsDB +import com.simplemobiletools.smsmessenger.extensions.messagesDB +import com.simplemobiletools.smsmessenger.helpers.SEARCHED_MESSAGE_ID +import com.simplemobiletools.smsmessenger.helpers.THREAD_ID +import com.simplemobiletools.smsmessenger.helpers.THREAD_TITLE +import com.simplemobiletools.smsmessenger.models.Conversation +import com.simplemobiletools.smsmessenger.models.Message +import com.simplemobiletools.smsmessenger.models.SearchResult +import kotlinx.android.synthetic.main.activity_search.* + +class SearchActivity : SimpleActivity() { + private var mIsSearchOpen = false + private var mLastSearchedText = "" + private var mSearchMenuItem: MenuItem? = null + + @SuppressLint("InlinedApi") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_search) + updateTextColors(search_holder) + search_placeholder.setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize()) + search_placeholder_2.setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize()) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_search, menu) + setupSearch(menu) + return true + } + + private fun setupSearch(menu: Menu) { + val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager + mSearchMenuItem = menu.findItem(R.id.search) + + MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, object : MenuItemCompat.OnActionExpandListener { + override fun onMenuItemActionExpand(item: MenuItem?): Boolean { + mIsSearchOpen = true + return true + } + + // this triggers on device rotation too, avoid doing anything + override fun onMenuItemActionCollapse(item: MenuItem?): Boolean { + if (mIsSearchOpen) { + mIsSearchOpen = false + mLastSearchedText = "" + finish() + } + return true + } + }) + + mSearchMenuItem?.expandActionView() + (mSearchMenuItem?.actionView as? SearchView)?.apply { + setSearchableInfo(searchManager.getSearchableInfo(componentName)) + isSubmitButtonEnabled = false + setOnQueryTextListener(object : SearchView.OnQueryTextListener { + override fun onQueryTextSubmit(query: String) = false + + override fun onQueryTextChange(newText: String): Boolean { + if (mIsSearchOpen) { + mLastSearchedText = newText + textChanged(newText) + } + return true + } + }) + } + } + + private fun textChanged(text: String) { + search_placeholder_2.beGoneIf(text.length >= 2) + if (text.length >= 2) { + ensureBackgroundThread { + val searchQuery = "%$text%" + val messages = messagesDB.getMessagesWithText(searchQuery) + val conversations = conversationsDB.getConversationsWithText(searchQuery) + if (text == mLastSearchedText) { + showSearchResults(messages, conversations, text) + + } + } + } else { + search_placeholder.beVisible() + search_results_list.beGone() + } + } + + private fun showSearchResults(messages: List, conversations: List, searchedText: String) { + val searchResults = ArrayList() + conversations.forEach { conversation -> + val date = conversation.date.formatDateOrTime(this, true, true) + val searchResult = SearchResult(-1, conversation.title, conversation.phoneNumber, date, conversation.threadId, conversation.photoUri) + searchResults.add(searchResult) + } + + messages.forEach { message -> + var recipient = message.senderName + if (recipient.isEmpty() && message.participants.isNotEmpty()) { + val participantNames = message.participants.map { it.name } + recipient = TextUtils.join(", ", participantNames) + } + + val date = message.date.formatDateOrTime(this, true, true) + val searchResult = SearchResult(message.id, recipient, message.body, date, message.threadId, message.senderPhotoUri) + searchResults.add(searchResult) + } + + runOnUiThread { + search_results_list.beVisibleIf(searchResults.isNotEmpty()) + search_placeholder.beVisibleIf(searchResults.isEmpty()) + + val currAdapter = search_results_list.adapter + if (currAdapter == null) { + SearchResultsAdapter(this, searchResults, search_results_list, searchedText) { + Intent(this, ThreadActivity::class.java).apply { + putExtra(THREAD_ID, (it as SearchResult).threadId) + putExtra(THREAD_TITLE, it.title) + putExtra(SEARCHED_MESSAGE_ID, it.messageId) + startActivity(this) + } + }.apply { + search_results_list.adapter = this + } + } else { + (currAdapter as SearchResultsAdapter).updateItems(searchResults, searchedText) + } + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SettingsActivity.kt index b421f16d..9617b5a1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/SettingsActivity.kt @@ -34,6 +34,7 @@ class SettingsActivity : SimpleActivity() { setupPurchaseThankYou() setupCustomizeColors() + setupCustomizeNotifications() setupUseEnglish() setupManageBlockedNumbers() setupChangeDateTimeFormat() @@ -71,6 +72,13 @@ class SettingsActivity : SimpleActivity() { } } + private fun setupCustomizeNotifications() { + settings_customize_notifications_holder.beVisibleIf(isOreoPlus()) + settings_customize_notifications_holder.setOnClickListener { + launchCustomizeNotificationsIntent() + } + } + private fun setupUseEnglish() { settings_use_english_holder.beVisibleIf(config.wasUseEnglishToggled || Locale.getDefault().language != "en") settings_use_english.isChecked = config.useEnglish diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt index 881af882..5e601968 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt @@ -5,6 +5,7 @@ import android.app.Activity import android.content.Intent import android.graphics.BitmapFactory import android.graphics.drawable.Drawable +import android.graphics.drawable.LayerDrawable import android.media.MediaMetadataRetriever import android.net.Uri import android.os.Bundle @@ -88,6 +89,15 @@ class ThreadActivity : SimpleActivity() { if (it) { setupButtons() setupCachedMessages { + val searchedMessageId = intent.getLongExtra(SEARCHED_MESSAGE_ID, -1L) + intent.removeExtra(SEARCHED_MESSAGE_ID) + if (searchedMessageId != -1L) { + val index = threadItems.indexOfFirst { (it as? Message)?.id == searchedMessageId } + if (index != -1) { + thread_messages_list.smoothScrollToPosition(index) + } + } + setupThread() } } else { @@ -106,13 +116,83 @@ class ThreadActivity : SimpleActivity() { isActivityVisible = false } - private fun setupThread() { - val privateCursor = getMyContactsCursor()?.loadInBackground() + override fun onDestroy() { + super.onDestroy() + bus?.unregister(this) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_thread, menu) + menu.apply { + findItem(R.id.delete).isVisible = threadItems.isNotEmpty() + findItem(R.id.block_number).isVisible = isNougatPlus() + } + + updateMenuItemColors(menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (participants.isEmpty()) { + return true + } + + when (item.itemId) { + R.id.block_number -> blockNumber() + R.id.delete -> askConfirmDelete() + R.id.manage_people -> managePeople() + R.id.mark_as_unread -> markAsUnread() + else -> return super.onOptionsItemSelected(item) + } + return true + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { + super.onActivityResult(requestCode, resultCode, resultData) + if (requestCode == PICK_ATTACHMENT_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) { + addAttachment(resultData.data!!) + } + } + + private fun setupCachedMessages(callback: () -> Unit) { ensureBackgroundThread { - val cachedMessagesCode = messages.hashCode() + messages = try { + messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList + } catch (e: Exception) { + ArrayList() + } + + setupParticipants() + setupAdapter() + + runOnUiThread { + if (messages.isEmpty()) { + window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + thread_type_message.requestFocus() + } + + setupThreadTitle() + setupSIMSelector() + callback() + } + } + } + + private fun setupThread() { + val privateCursor = getMyContactsCursor(false, true)?.loadInBackground() + ensureBackgroundThread { + val cachedMessagesCode = messages.clone().hashCode() messages = getMessages(threadId) - if (messages.hashCode() == cachedMessagesCode) { - return@ensureBackgroundThread + + val hasParticipantWithoutName = participants.any { + it.phoneNumbers.contains(it.name) + } + + try { + if (participants.isNotEmpty() && messages.hashCode() == cachedMessagesCode && !hasParticipantWithoutName) { + return@ensureBackgroundThread + } + } catch (ignored: Exception) { } setupParticipants() @@ -162,63 +242,6 @@ class ThreadActivity : SimpleActivity() { } } - override fun onDestroy() { - super.onDestroy() - bus?.unregister(this) - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.menu_thread, menu) - menu.apply { - findItem(R.id.delete).isVisible = threadItems.isNotEmpty() - findItem(R.id.block_number).isVisible = isNougatPlus() - } - - updateMenuItemColors(menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (participants.isEmpty()) { - return true - } - - when (item.itemId) { - R.id.block_number -> blockNumber() - R.id.delete -> askConfirmDelete() - R.id.manage_people -> managePeople() - R.id.mark_as_unread -> markAsUnread() - else -> return super.onOptionsItemSelected(item) - } - return true - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { - super.onActivityResult(requestCode, resultCode, resultData) - if (requestCode == PICK_ATTACHMENT_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) { - addAttachment(resultData.data!!) - } - } - - private fun setupCachedMessages(callback: () -> Unit) { - ensureBackgroundThread { - messages = messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList - setupParticipants() - setupAdapter() - - runOnUiThread { - if (messages.isEmpty()) { - window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - thread_type_message.requestFocus() - } - - setupThreadTitle() - setupSIMSelector() - callback() - } - } - } - private fun setupAdapter() { threadItems = getThreadItems() invalidateOptionsMenu() @@ -458,11 +481,20 @@ class ThreadActivity : SimpleActivity() { } private fun showSelectedContacts() { + val adjustedColor = getAdjustedPrimaryColor() + val views = ArrayList() participants.forEach { val contact = it layoutInflater.inflate(R.layout.item_selected_contact, null).apply { + val selectedContactBg = resources.getDrawable(R.drawable.item_selected_contact_background) + (selectedContactBg as LayerDrawable).findDrawableByLayerId(R.id.selected_contact_bg).applyColorFilter(adjustedColor) + selected_contact_holder.background = selectedContactBg + selected_contact_name.text = contact.name + selected_contact_name.setTextColor(adjustedColor.getContrastColor()) + selected_contact_remove.applyColorFilter(adjustedColor.getContrastColor()) + selected_contact_remove.setOnClickListener { if (contact.rawId != participants.first().rawId) { removeSelectedContact(contact.rawId) @@ -514,7 +546,7 @@ class ThreadActivity : SimpleActivity() { var hadUnreadItems = false val cnt = messages.size for (i in 0 until cnt) { - val message = messages[i] + val message = messages.getOrNull(i) ?: continue // do not show the date/time above every message, only if the difference between the 2 messages is at least MIN_DATE_TIME_DIFF_SECS if (message.date - prevDateTime > MIN_DATE_TIME_DIFF_SECS) { val simCardID = subscriptionIdToSimId[message.subscriptionId] ?: "?" diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/AutoCompleteTextViewAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/AutoCompleteTextViewAdapter.kt index 445c8294..13199da6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/AutoCompleteTextViewAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/AutoCompleteTextViewAdapter.kt @@ -5,35 +5,46 @@ import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.Filter +import android.widget.RelativeLayout import android.widget.TextView +import com.simplemobiletools.commons.extensions.darkenColor +import com.simplemobiletools.commons.extensions.getContrastColor import com.simplemobiletools.commons.extensions.normalizeString import com.simplemobiletools.commons.helpers.SimpleContactsHelper import com.simplemobiletools.commons.models.SimpleContact import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.activities.SimpleActivity +import com.simplemobiletools.smsmessenger.extensions.config class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: ArrayList) : ArrayAdapter(activity, 0, contacts) { var resultList = ArrayList() override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - val contact = resultList[position] + val contact = resultList.getOrNull(position) var listItem = convertView - if (listItem == null || listItem.tag != contact.name.isNotEmpty()) { + if (listItem == null || listItem.tag != contact?.name?.isNotEmpty()) { listItem = LayoutInflater.from(activity).inflate(R.layout.item_contact_with_number, parent, false) } listItem!!.apply { - tag = contact.name.isNotEmpty() + tag = contact?.name?.isNotEmpty() // clickable and focusable properties seem to break Autocomplete clicking, so remove them findViewById(R.id.item_contact_frame).apply { isClickable = false isFocusable = false } - findViewById(R.id.item_contact_name).text = contact.name - findViewById(R.id.item_contact_number).text = contact.phoneNumbers.first() + val backgroundColor = activity.config.backgroundColor + findViewById(R.id.item_contact_holder).setBackgroundColor(backgroundColor.darkenColor()) - SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name) + findViewById(R.id.item_contact_name).setTextColor(backgroundColor.getContrastColor()) + findViewById(R.id.item_contact_number).setTextColor(backgroundColor.getContrastColor()) + + if (contact != null) { + findViewById(R.id.item_contact_name).text = contact.name + findViewById(R.id.item_contact_number).text = contact.phoneNumbers.first() + SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name) + } } return listItem diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ContactsAdapter.kt index b6d41b29..1f48eb53 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ContactsAdapter.kt @@ -17,8 +17,10 @@ import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.activities.SimpleActivity import java.util.* -class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller?, - itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) { +class ContactsAdapter( + activity: SimpleActivity, var contacts: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller?, + itemClick: (Any) -> Unit +) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) { private var fontSize = activity.getTextSize() override fun getActionMenuId() = 0 @@ -51,10 +53,12 @@ class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList(R.id.item_contact_image)) + fun updateContacts(newContacts: ArrayList) { + val oldHashCode = contacts.hashCode() + val newHashCode = newContacts.hashCode() + if (newHashCode != oldHashCode) { + contacts = newContacts + notifyDataSetChanged() } } @@ -75,4 +79,11 @@ class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList(R.id.item_contact_image)) + } + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt index 8b1de0ca..c895ea85 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt @@ -1,5 +1,6 @@ package com.simplemobiletools.smsmessenger.adapters +import android.content.ActivityNotFoundException import android.content.Intent import android.graphics.Typeface import android.net.Uri @@ -26,8 +27,10 @@ import com.simplemobiletools.smsmessenger.helpers.refreshMessages import com.simplemobiletools.smsmessenger.models.Conversation import kotlinx.android.synthetic.main.item_conversation.view.* -class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller, - itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) { +class ConversationsAdapter( + activity: SimpleActivity, var conversations: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller, + itemClick: (Any) -> Unit +) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) { private var fontSize = activity.getTextSize() init { @@ -120,11 +123,13 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis Intent(Intent.ACTION_DIAL).apply { data = Uri.fromParts("tel", conversation.phoneNumber, null) - if (resolveActivity(activity.packageManager) != null) { + try { activity.startActivity(this) finishActMode() - } else { + } catch (e: ActivityNotFoundException) { activity.toast(R.string.no_app_found) + } catch (e: Exception) { + activity.showErrorToast(e) } } } @@ -185,12 +190,7 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis action = Intent.ACTION_INSERT_OR_EDIT type = "vnd.android.cursor.item/contact" putExtra(KEY_PHONE, conversation.phoneNumber) - - if (resolveActivity(activity.packageManager) != null) { - activity.startActivity(this) - } else { - activity.toast(R.string.no_app_found) - } + activity.launchActivityIntent(this) } } @@ -209,10 +209,11 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis } fun updateConversations(newConversations: ArrayList) { + val latestConversations = newConversations.clone() as ArrayList val oldHashCode = conversations.hashCode() - val newHashCode = newConversations.hashCode() + val newHashCode = latestConversations.hashCode() if (newHashCode != oldHashCode) { - conversations = newConversations + conversations = latestConversations notifyDataSetChanged() } } @@ -232,7 +233,7 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis } conversation_date.apply { - text = conversation.date.formatDateOrTime(context, true) + text = conversation.date.formatDateOrTime(context, true, false) setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.8f) } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/SearchResultsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/SearchResultsAdapter.kt new file mode 100644 index 00000000..01df81e2 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/SearchResultsAdapter.kt @@ -0,0 +1,96 @@ +package com.simplemobiletools.smsmessenger.adapters + +import android.util.TypedValue +import android.view.Menu +import android.view.View +import android.view.ViewGroup +import com.bumptech.glide.Glide +import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter +import com.simplemobiletools.commons.extensions.getTextSize +import com.simplemobiletools.commons.extensions.highlightTextPart +import com.simplemobiletools.commons.helpers.SimpleContactsHelper +import com.simplemobiletools.commons.views.MyRecyclerView +import com.simplemobiletools.smsmessenger.R +import com.simplemobiletools.smsmessenger.activities.SimpleActivity +import com.simplemobiletools.smsmessenger.models.SearchResult +import kotlinx.android.synthetic.main.item_search_result.view.* +import java.util.* + +class SearchResultsAdapter( + activity: SimpleActivity, var searchResults: ArrayList, recyclerView: MyRecyclerView, highlightText: String, itemClick: (Any) -> Unit +) : MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) { + + private var fontSize = activity.getTextSize() + private var textToHighlight = highlightText + + override fun getActionMenuId() = 0 + + override fun prepareActionMode(menu: Menu) {} + + override fun actionItemPressed(id: Int) {} + + override fun getSelectableItemCount() = searchResults.size + + override fun getIsItemSelectable(position: Int) = false + + override fun getItemSelectionKey(position: Int) = searchResults.getOrNull(position)?.hashCode() + + override fun getItemKeyPosition(key: Int) = searchResults.indexOfFirst { it.hashCode() == key } + + override fun onActionModeCreated() {} + + override fun onActionModeDestroyed() {} + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_search_result, parent) + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val searchResult = searchResults[position] + holder.bindView(searchResult, true, false) { itemView, layoutPosition -> + setupView(itemView, searchResult) + } + bindViewHolder(holder) + } + + override fun getItemCount() = searchResults.size + + fun updateItems(newItems: ArrayList, highlightText: String = "") { + if (newItems.hashCode() != searchResults.hashCode()) { + searchResults = newItems.clone() as ArrayList + textToHighlight = highlightText + notifyDataSetChanged() + } else if (textToHighlight != highlightText) { + textToHighlight = highlightText + notifyDataSetChanged() + } + } + + private fun setupView(view: View, searchResult: SearchResult) { + view.apply { + search_result_title.apply { + text = searchResult.title.highlightTextPart(textToHighlight, adjustedPrimaryColor) + setTextColor(textColor) + setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 1.2f) + } + + search_result_snippet.apply { + text = searchResult.snippet.highlightTextPart(textToHighlight, adjustedPrimaryColor) + setTextColor(textColor) + setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.9f) + } + + search_result_date.apply { + text = searchResult.date + setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.8f) + } + + SimpleContactsHelper(context).loadContactImage(searchResult.photoUri, search_result_image, searchResult.title) + } + } + + override fun onViewRecycled(holder: ViewHolder) { + super.onViewRecycled(holder) + if (!activity.isDestroyed && !activity.isFinishing && holder.itemView.search_result_image != null) { + Glide.with(activity).clear(holder.itemView.search_result_image) + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt index 8c6ae60b..63b0abac 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.smsmessenger.adapters import android.annotation.SuppressLint +import android.content.ActivityNotFoundException import android.content.Intent import android.graphics.drawable.Drawable import android.net.Uri @@ -42,8 +43,10 @@ import kotlinx.android.synthetic.main.item_thread_error.view.* import kotlinx.android.synthetic.main.item_thread_sending.view.* import kotlinx.android.synthetic.main.item_thread_success.view.* -class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller, - itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) { +class ThreadAdapter( + activity: SimpleActivity, var messages: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller, + itemClick: (Any) -> Unit +) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) { private val roundedCornersRadius = resources.getDimension(R.dimen.normal_margin).toInt() private var fontSize = activity.getTextSize() @@ -134,17 +137,17 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList) { + val latestMessages = newMessages.clone() as ArrayList val oldHashCode = messages.hashCode() - val newHashCode = newMessages.hashCode() + val newHashCode = latestMessages.hashCode() if (newHashCode != oldHashCode) { - messages = newMessages + messages = latestMessages notifyDataSetChanged() recyclerView.scrollToPosition(messages.size - 1) } @@ -224,7 +228,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList): Long { } fun Context.showReceivedMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?) { - val privateCursor = getMyContactsCursor()?.loadInBackground() + val privateCursor = getMyContactsCursor(false, true)?.loadInBackground() ensureBackgroundThread { val senderName = getNameFromAddress(address, privateCursor) @@ -709,37 +712,41 @@ fun Context.showMessageNotification(address: String, body: String, threadId: Lon val builder = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL).apply { when (config.notificationSetting) { CONFIGURE_NAME_AND_MESSAGE -> { - this.setContentTitle(sender) - this.setLargeIcon(largeIcon) - this.setContentText(body) + setContentTitle(sender) + setLargeIcon(largeIcon) + setContentText(body) } CONFIGURE_NAME -> { - this.setContentTitle(sender) - this.setLargeIcon(largeIcon) + setContentTitle(sender) + setLargeIcon(largeIcon) } } - this.color = config.primaryColor - this.setSmallIcon(R.drawable.ic_messenger) - this.setStyle(NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body)) - this.setContentIntent(pendingIntent) - this.priority = NotificationCompat.PRIORITY_MAX - this.setDefaults(Notification.DEFAULT_LIGHTS) - this.setCategory(Notification.CATEGORY_MESSAGE) - this.setAutoCancel(true) - this.setSound(soundUri, AudioManager.STREAM_NOTIFICATION) + + color = getAdjustedPrimaryColor() + setSmallIcon(R.drawable.ic_messenger) + setStyle(NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body)) + setContentIntent(pendingIntent) + priority = NotificationCompat.PRIORITY_MAX + setDefaults(Notification.DEFAULT_LIGHTS) + setCategory(Notification.CATEGORY_MESSAGE) + setAutoCancel(true) + setSound(soundUri, AudioManager.STREAM_NOTIFICATION) } if (replyAction != null && config.notificationSetting == CONFIGURE_NAME_AND_MESSAGE) { builder.addAction(replyAction) } + builder.addAction(R.drawable.ic_check_vector, getString(R.string.mark_as_read), markAsReadPendingIntent) .setChannelId(NOTIFICATION_CHANNEL) notificationManager.notify(threadId.hashCode(), builder.build()) } -fun Context.getConfigurationText(type: Int) = getString(when (type) { - CONFIGURE_NAME_AND_MESSAGE -> R.string.configure_name_and_message - CONFIGURE_NAME -> R.string.configure_name - else -> R.string.configure_no_details -}) +fun Context.getConfigurationText(type: Int) = getString( + when (type) { + CONFIGURE_NAME_AND_MESSAGE -> R.string.sender_and_message + CONFIGURE_NAME -> R.string.sender_only + else -> R.string.nothing + } +) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt index 11425c0a..ca72c64a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt @@ -9,6 +9,7 @@ const val THREAD_TEXT = "thread_text" const val THREAD_NUMBER = "thread_number" const val THREAD_ATTACHMENT_URI = "thread_attachment_uri" const val THREAD_ATTACHMENT_URIS = "thread_attachment_uris" +const val SEARCHED_MESSAGE_ID = "searched_message_id" const val USE_SIM_ID_PREFIX = "use_sim_id_" const val NOTIFICATION_CHANNEL = "simple_sms_messenger" const val SHOW_CHARACTER_COUNTER = "show_character_counter" diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/ConversationsDao.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/ConversationsDao.kt index 8980593d..534cdc1f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/ConversationsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/ConversationsDao.kt @@ -17,6 +17,9 @@ interface ConversationsDao { @Query("SELECT * FROM conversations WHERE read = 0") fun getUnreadConversations(): List + @Query("SELECT * FROM conversations WHERE title LIKE :text") + fun getConversationsWithText(text: String): List + @Query("UPDATE conversations SET read = 1 WHERE thread_id = :threadId") fun markRead(threadId: Long) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt index c3dc8d71..c4689b4d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt @@ -23,6 +23,9 @@ interface MessagesDao { @Query("SELECT * FROM messages WHERE thread_id = :threadId") fun getThreadMessages(threadId: Long): List + @Query("SELECT * FROM messages WHERE body LIKE :text") + fun getMessagesWithText(text: String): List + @Query("UPDATE messages SET read = 1 WHERE id = :id") fun markRead(id: Long) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/SearchResult.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/SearchResult.kt new file mode 100644 index 00000000..e6fd47ed --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/SearchResult.kt @@ -0,0 +1,3 @@ +package com.simplemobiletools.smsmessenger.models + +data class SearchResult(val messageId: Long, val title: String, val snippet: String, val date: String, val threadId: Long, var photoUri: String) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt index d4148c86..8a4ee30c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt @@ -3,17 +3,14 @@ package com.simplemobiletools.smsmessenger.receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import androidx.core.app.NotificationCompat import androidx.core.app.RemoteInput import com.klinker.android.send_message.Settings import com.klinker.android.send_message.Transaction import com.simplemobiletools.commons.extensions.notificationManager import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.helpers.ensureBackgroundThread -import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.extensions.conversationsDB import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead -import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL import com.simplemobiletools.smsmessenger.helpers.REPLY import com.simplemobiletools.smsmessenger.helpers.THREAD_ID import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER @@ -22,26 +19,28 @@ class DirectReplyReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val address = intent.getStringExtra(THREAD_NUMBER) val threadId = intent.getLongExtra(THREAD_ID, 0L) - val msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY).toString() + val msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return val settings = Settings() settings.useSystemSending = true + settings.deliveryReports = true val transaction = Transaction(context, settings) val message = com.klinker.android.send_message.Message(msg, address) try { + val smsSentIntent = Intent(context, SmsStatusSentReceiver::class.java) + val deliveredIntent = Intent(context, SmsStatusDeliveredReceiver::class.java) + + transaction.setExplicitBroadcastForSentSms(smsSentIntent) + transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent) + transaction.sendNewMessage(message, threadId) } catch (e: Exception) { context.showErrorToast(e) } - val repliedNotification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL) - .setSmallIcon(R.drawable.ic_messenger) - .setContentText(msg) - .build() - - context.notificationManager.notify(threadId.hashCode(), repliedNotification) + context.notificationManager.cancel(threadId.hashCode()) ensureBackgroundThread { context.markThreadMessagesRead(threadId) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt index cc2efb88..f431cac9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt @@ -40,17 +40,21 @@ class SmsReceiver : BroadcastReceiver() { val newMessageId = context.insertNewSMS(address, subject, body, date, read, threadId, type, subscriptionId) val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread - context.conversationsDB.insertOrUpdate(conversation) - context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations()) + try { + context.conversationsDB.insertOrUpdate(conversation) + } catch (ignored: Exception) { + } + context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations()) val participant = SimpleContact(0, 0, address, "", arrayListOf(address), ArrayList(), ArrayList()) - val message = Message(newMessageId, body, type, arrayListOf(participant), (date / 1000).toInt(), false, threadId, - false, null, address, "", subscriptionId) + val participants = arrayListOf(participant) + val messageDate = (date / 1000).toInt() + val message = Message(newMessageId, body, type, participants, messageDate, false, threadId, false, null, address, "", subscriptionId) context.messagesDB.insertOrUpdate(message) + refreshMessages() } context.showReceivedMessageNotification(address, body, threadId, null) - refreshMessages() } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt index b7aa5593..b4c805e5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt @@ -1,20 +1,20 @@ package com.simplemobiletools.smsmessenger.receivers -import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.net.Uri import android.os.Handler import android.os.Looper import android.provider.Telephony +import com.klinker.android.send_message.DeliveredReceiver import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.smsmessenger.extensions.messagesDB import com.simplemobiletools.smsmessenger.extensions.updateMessageType import com.simplemobiletools.smsmessenger.helpers.refreshMessages -class SmsStatusDeliveredReceiver : BroadcastReceiver() { +class SmsStatusDeliveredReceiver : DeliveredReceiver() { - override fun onReceive(context: Context, intent: Intent) { + override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) { if (intent.extras?.containsKey("message_uri") == true) { val uri = Uri.parse(intent.getStringExtra("message_uri")) val messageId = uri?.lastPathSegment?.toLong() ?: 0L diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt index 6f7451f6..f128ac9e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt @@ -5,7 +5,6 @@ import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent -import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.media.AudioAttributes @@ -16,6 +15,8 @@ import android.os.Handler import android.os.Looper import android.provider.Telephony import androidx.core.app.NotificationCompat +import com.klinker.android.send_message.SentReceiver +import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor import com.simplemobiletools.commons.extensions.getMyContactsCursor import com.simplemobiletools.commons.helpers.SimpleContactsHelper import com.simplemobiletools.commons.helpers.ensureBackgroundThread @@ -27,9 +28,9 @@ import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL import com.simplemobiletools.smsmessenger.helpers.THREAD_ID import com.simplemobiletools.smsmessenger.helpers.refreshMessages -class SmsStatusSentReceiver : BroadcastReceiver() { +class SmsStatusSentReceiver : SentReceiver() { - override fun onReceive(context: Context, intent: Intent) { + override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) { if (intent.extras?.containsKey("message_uri") == true) { val uri = Uri.parse(intent.getStringExtra("message_uri")) val messageId = uri?.lastPathSegment?.toLong() ?: 0L @@ -40,6 +41,7 @@ class SmsStatusSentReceiver : BroadcastReceiver() { } else { Telephony.Sms.MESSAGE_TYPE_OUTBOX } + context.updateMessageType(messageId, type) context.messagesDB.updateType(messageId, type) refreshMessages() @@ -49,7 +51,7 @@ class SmsStatusSentReceiver : BroadcastReceiver() { private fun showSendingFailedNotification(context: Context, messageId: Long) { Handler(Looper.getMainLooper()).post { - val privateCursor = context.getMyContactsCursor()?.loadInBackground() + val privateCursor = context.getMyContactsCursor(false, true)?.loadInBackground() ensureBackgroundThread { val address = context.getMessageRecipientAddress(messageId) val threadId = context.getThreadId(address) @@ -92,7 +94,7 @@ class SmsStatusSentReceiver : BroadcastReceiver() { val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL) .setContentTitle(context.getString(R.string.message_not_sent_short)) .setContentText(summaryText) - .setColor(context.config.primaryColor) + .setColor(context.getAdjustedPrimaryColor()) .setSmallIcon(R.drawable.ic_messenger) .setLargeIcon(largeIcon) .setStyle(NotificationCompat.BigTextStyle().bigText(summaryText)) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/services/HeadlessSmsSendService.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/services/HeadlessSmsSendService.kt index eaeba8fb..de6df798 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/services/HeadlessSmsSendService.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/services/HeadlessSmsSendService.kt @@ -6,6 +6,8 @@ import android.net.Uri import com.klinker.android.send_message.Settings import com.klinker.android.send_message.Transaction import com.simplemobiletools.smsmessenger.extensions.getThreadId +import com.simplemobiletools.smsmessenger.receivers.SmsStatusDeliveredReceiver +import com.simplemobiletools.smsmessenger.receivers.SmsStatusSentReceiver class HeadlessSmsSendService : Service() { override fun onBind(intent: Intent?) = null @@ -20,8 +22,17 @@ class HeadlessSmsSendService : Service() { val text = intent.getStringExtra(Intent.EXTRA_TEXT) val settings = Settings() settings.useSystemSending = true + settings.deliveryReports = true + val transaction = Transaction(this, settings) val message = com.klinker.android.send_message.Message(text, number) + + val smsSentIntent = Intent(this, SmsStatusSentReceiver::class.java) + val deliveredIntent = Intent(this, SmsStatusDeliveredReceiver::class.java) + + transaction.setExplicitBroadcastForSentSms(smsSentIntent) + transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent) + transaction.sendNewMessage(message, getThreadId(number)) } catch (ignored: Exception) { } diff --git a/app/src/main/res/drawable/item_selected_contact_background.xml b/app/src/main/res/drawable/item_selected_contact_background.xml index f55fbc8f..f0d2b728 100644 --- a/app/src/main/res/drawable/item_selected_contact_background.xml +++ b/app/src/main/res/drawable/item_selected_contact_background.xml @@ -1,9 +1,12 @@ - + + + - + - + - + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index aaa99efc..911f9b31 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -43,6 +43,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" + android:layoutAnimation="@anim/layout_animation" android:overScrollMode="ifContentScrolls" android:scrollbars="none" app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" /> diff --git a/app/src/main/res/layout/activity_new_conversation.xml b/app/src/main/res/layout/activity_new_conversation.xml index aaf95c05..7279f684 100644 --- a/app/src/main/res/layout/activity_new_conversation.xml +++ b/app/src/main/res/layout/activity_new_conversation.xml @@ -101,6 +101,7 @@ android:layout_height="match_parent" android:layout_below="@+id/suggestions_scrollview" android:clipToPadding="false" + android:layoutAnimation="@anim/layout_animation" android:overScrollMode="ifContentScrolls" android:scrollbars="none" app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" /> diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml new file mode 100644 index 00000000..a8e2fe2d --- /dev/null +++ b/app/src/main/res/layout/activity_search.xml @@ -0,0 +1,46 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 73b74258..a54f0241 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -53,6 +53,27 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_suggested_contact.xml b/app/src/main/res/layout/item_suggested_contact.xml index 7535748b..6851fb13 100644 --- a/app/src/main/res/layout/item_suggested_contact.xml +++ b/app/src/main/res/layout/item_suggested_contact.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/suggested_contact_holder" android:layout_width="wrap_content" - android:background="?selectableItemBackground" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:background="?selectableItemBackground"> + app:showAsAction="always" /> - + app:showAsAction="always" /> + + app:showAsAction="always" /> + app:showAsAction="always" /> + - + + + + diff --git a/app/src/main/res/menu/menu_thread.xml b/app/src/main/res/menu/menu_thread.xml index 2a1ecf93..dd4d0bd2 100644 --- a/app/src/main/res/menu/menu_thread.xml +++ b/app/src/main/res/menu/menu_thread.xml @@ -13,7 +13,6 @@ app:showAsAction="ifRoom" /> + Simple SMS Messenger + SMS Messenger + Napište zprávu… + Zpráva nebyla odeslána + Nebylo odesláno. Klepnutím to zkuste znovu. + Vaše zpráva pro \'%s\' nebyla odeslána + Přidat osobu + Příloha + Nebyly nalezeny žádné uložené konverzace + Zahajte konverzaci + Odpověď + Zobrazit počítadlo znaků při psaní zpráv + Načítání zpráv… + Odesílatel nepodporuje odpovědi + Návrh + Odesílá se… + Export zpráv + Import zpráv + + + Nová konverzace + Přidejte kontakt nebo číslo… + Návrhy + + + Přijaté SMS + Nová zpráva + Označit jako přečtené + Označit jako nepřečtené + + + Opravdu chcete smazat všechny zprávy z této konverzace? + + + + %d conversation + %d conversations + + + + + %d message + %d messages + + + + Proč aplikace vyžaduje přístup k internetu? + Je smutné, že je to nutné pro odesílání příloh MMS. Nebýt schopen posílat MMS by byla opravdu obrovská nevýhoda ve srovnání s jinými aplikacemi, proto jsme se rozhodli jít touto cestou. + Jako obvykle však neexistují žádné reklamy, sledování ani analytika, internet se používá pouze k odesílání MMS. + + + + Simple SMS Messenger - Snadná správa zpráv + + Snadný a rychlý způsob správy SMS a MMS zpráv bez reklam. + + Skvělý způsob, jak zůstat v kontaktu se svými příbuznými, a to zasíláním zpráv SMS i MMS. Aplikace správně zpracovává i skupinové zprávy, stejně jako blokování čísel z Androidu 7+. + + Nabízí mnoho formátů data, ze kterých si můžete vybrat, abyste se při jejich používání cítili pohodlně. Můžete také přepínat mezi 12 a 24 hodinovým formátem času. + + Ve srovnání s konkurencí má opravdu malou velikost aplikace, takže je stahování opravdu rychlé. + + Ve výchozím nastavení je dodáván s materiálovým designem a tmavým motivem a poskytuje skvělé uživatelské prostředí pro snadné použití. Nedostatek přístupu k internetu vám poskytuje více soukromí, zabezpečení a stability než jiné aplikace. + + Neobsahuje žádné reklamy ani zbytečná oprávnění. Je plně opensource a poskytuje přizpůsobitelné barvy. + Check out the full suite of Simple Tools here: + https://www.simplemobiletools.com + + Facebook: + https://www.facebook.com/simplemobiletools + + Reddit: + https://www.reddit.com/r/SimpleMobileTools + + + + diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml new file mode 100644 index 00000000..007b7205 --- /dev/null +++ b/app/src/main/res/values-da/strings.xml @@ -0,0 +1,82 @@ + + Enkel SMS Beskeder + Beskeder + Skriv en besked… + Beskeden blev ikke sendt + Blev ikke sendt, tryk for at gensende + Din besked til \'%s\' blev ikke sendt + Tilføj Person + Vedhæftning + Ingen gemte samtaler er fundet + Start en samtale + Svar + Vis en karaktertæller ved skrivning af beskeder + Henter beskeder… + Afsender understøtter ikke svar + Udkast + Sender… + Eksporter beskeder + Importer beskeder + + + Ny Samtale + Tilføj kontakt eller nummer… + Forslag + + + Modtag SMS + Ny Besked + Marker som læst + Marker som ulæst + + + Er du sikker på, at du vil slette alle beskeder i denne samtale? + + + + %d samtale + %d samtaler + + + + + %d besked + %d beskeder + + + + Hvorfor kræver appen adgang til internettet? + Desværre er det nødvendigt for at sende MMS-vedhæftede filer. Ikke at kunne være i stand til at sende MMS ville være en virkelig stor ulempe i forhold til andre apps, så vi besluttede at gå denne vej. + Men som normalt er der ingen annoncer, sporing eller analyse overhovedet, internettet bruges kun til at sende MMS. + + + + Simple SMS beskeder - Administrer dine smser nemt + + En nem og hurtig måde at administrere SMS og MMS-beskeder uden annoncer på. + + En fantastisk måde at holde kontakten med dine pårørende på, ved at sende både SMS- og MMS-beskeder. Appen håndterer også gruppemeddelelser korrekt, ligesom at blokere numre fra Android 7+. + + Appen tilbyder mange datoformater at vælge imellem, så du kan føle dig godt tilpas ved at bruge den. Du kan også skifte mellem 12 og 24 timers tidsformat. + + Det har en virkelig lille appstørrelse sammenlignet med konkurrencen, hvilket gør det virkelig hurtigt at downloade. + + Den leveres med materialedesign og mørkt tema som standard og giver god brugeroplevelse til nem brug. Manglen på internetadgang giver dig mere privatliv, sikkerhed og stabilitet end andre apps. + + Indeholder ingen annoncer eller unødvendige tilladelser. Det er fuldstændig opensource, giver farver, der kan tilpasses. + + Se hele pakken med enkle værktøjer her: + https://www.simplemobiletools.com + + Facebook: + https://www.facebook.com/simplemobiletools + + Reddit: + https://www.reddit.com/r/SimpleMobileTools + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a861ccd0..eba10927 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -2,19 +2,21 @@ Schlichter SMS Messenger SMS Messenger Schreibe eine Nachricht… - Message not sent - Not sent. Touch to retry. - Your message to \'%s\' has not been sent + Nachricht nicht versendet. + Nachricht nicht versendet. Berühre, um es erneut zu versuchen. + Deine Nachricht am \'%s\' wurde nicht gesendet. Person hinzufügen Anhang Keine gespeicherten Chats gefunden Neuen Chat beginnen Antworten - Show a character counter at writing messages - Loading messages… - Sender doesn\'t support replies - Draft - Sending… + Zeige einen Zeichenzähler während dem Schreiben von Nachrichten. + Lade Nachrichten… + Der Absender unterstützt keine Antworten. + Entwurf + Sende… + Export messages + Import messages Neuer Chat @@ -49,21 +51,21 @@ - Simple SMS Messenger - Manage messages easily + Simple SMS Messenger-Nachrichten simple verwalten - An easy and quick way of managing SMS and MMS messages without ads. + Eine einfache und schnelle Art SMS & MMS ohne Werbung zu verwalten. - A great way to stay in touch with your relatives, by sending both SMS and MMS messages. The app properly handles group messaging too, just like blocking numbers from Android 7+. + In tolle Möglichkeit mit deinen Verwandten in Kontakt zu bleiben, indem sowohl SMS als auch MMS Nachrichten gesendet werden. Die App handhabt auch Gruppennachrichten gut, genauso wie das Blockieren von Nummern ab Android 7+. - It offers many date formats to choose from, to make you feel comfortable at using it. You can toggle between 12 and 24 hours time format too. + Damit die Nutzung sich vertrauter und komfortabler anfühlt, kannst du das Datumsformat in verschiedenen Arten anpassen. Zudem kannst du zwischen 12 und 24 Stunden Format auswählen. + + Im Vergleich zur Konkurrenz ist die Appgröße sehr klein, wodurch es sehr schnell heruntergeladen ist. - It has a really tiny app size compared to the competition, making it really fast to download. + Es kommt standardmäßig mit einem material design und Dunkelmodus, was für ein großartiges Nutzererlebnis und leichte Nutzbarkeit sorgt. Da es keine Internetverbindung verwendet, bietet diese App mehr Datenschutz, Sicherheit und Stabilität als andere Apps. - It comes with material design and dark theme by default, provides great user experience for easy usage. The lack of internet access gives you more privacy, security and stability than other apps. + Beinhaltet keine Werbung oder unnötige Berechtigungen. Es ist komplett opensource, und bietet anpassbare Farben. - Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors. - - Check out the full suite of Simple Tools here: + Entdecke alle Simple Tools hier: https://www.simplemobiletools.com Facebook: diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index b6f10a90..3bb881be 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -2,9 +2,9 @@ Απλός SMS Messenger SMS Messenger Πληκτρολογήστε ένα μήνυμα… - Message not sent - Not sent. Touch to retry. - Your message to \'%s\' has not been sent + Το μήνυμα δεν εστάλη + Δεν εστάλη. Αγγίξτε για επανάληψη. + Το μήνυμά σας προς το \'%s\' δεν έχει αποσταλεί Προσθήκη ατόμου Συνημμένο Δεν βρέθηκαν αποθηκευμένες συνομιλίες @@ -12,9 +12,11 @@ Απάντηση Εμφάνιση μετρητή χαρακτήρων κατά την πληκτρολόγηση μηνυμάτων Φόρτωση μηνυμάτων… - Sender doesn\'t support replies - Draft - Sending… + Ο αποστολέας δεν υποστηρίζει απαντήσεις + Πρόχειρο + Γίνεται αποστολή… + Εξαγωγή μηνυμάτων + Εισαγωγή μηνυμάτων Νέα συνομιλία diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3516f9ed..479f07a1 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages Nueva conversación diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml new file mode 100644 index 00000000..67afb2ea --- /dev/null +++ b/app/src/main/res/values-fi/strings.xml @@ -0,0 +1,82 @@ + + Simple SMS Messenger + Viestit + Lähetä viesti… + Viestiä ei lähetetty + Ei lähetetty. Yritä uudelleen koskemalla. + Viestiäsi henkilölle \'%s\' ei lähetetty. + Lisää henkilö + Liite + Tallennettuja keskusteluja ei löytyny + Aloita keskustelu + Vastaa + Näytä merkkimäärä kirjoittaessasi viestejä + Ladataan viestejä… + Lähettäjä ei tue vastauksia + Luonnos + Lähetetään… + Export messages + Import messages + + + Uusi keskustelu + Lisää yhteystieto tai numero… + Ehdotuksia + + + Vastaanotettu tekstiviesti + Uusi viesti + Merkitse luetuksi + Merkitse lukemattomaksi + + + Haluatko varmasti poistaa kaikki tämän keskustelun viestit? + + + + yhden keskustelun + %d keskustelua + + + + + yhden viestin + %d viestiä + + + + Miksi sovellus vaatii Internet-yhteyden? + Valitettavasti sitä tarvitaan multimediaviestin-liitteiden lähettämiseen. Multimediaviestien lähettämättä jättäminen olisi todella valtava haitta muihin sovelluksiin verrattuna, joten päätimme mennä tällä tavalla. + Kuten yleensä, mainoksia, seurantaa tai analytiikkaa ei kuitenkaan ole, iternetiä käytetään vain multimediaviestien lähettämiseen. + + + + Simple SMS Messenger - Manage messages easily + + An easy and quick way of managing SMS and MMS messages without ads. + + A great way to stay in touch with your relatives, by sending both SMS and MMS messages. The app properly handles group messaging too, just like blocking numbers from Android 7+. + + It offers many date formats to choose from, to make you feel comfortable at using it. You can toggle between 12 and 24 hours time format too. + + It has a really tiny app size compared to the competition, making it really fast to download. + + It comes with material design and dark theme by default, provides great user experience for easy usage. The lack of internet access gives you more privacy, security and stability than other apps. + + Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors. + + Check out the full suite of Simple Tools here: + https://www.simplemobiletools.com + + Facebook: + https://www.facebook.com/simplemobiletools + + Reddit: + https://www.reddit.com/r/SimpleMobileTools + + + + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b418260b..7e5952e1 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages Nouvelle conversation diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index df73b0b3..3c77b619 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages Percakapan baru diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml new file mode 100644 index 00000000..150a384e --- /dev/null +++ b/app/src/main/res/values-it/strings.xml @@ -0,0 +1,81 @@ + + SMS Messenger + SMS Messenger + Componi messaggio + Messaggio non inviato + Non inviato. Tocca per riprovare + Il tuo messaggio a \'%s\' non è stato inviato + Aggiungi persona + Allegato + Nessuna conversazione trovata + Inizia conversazione + Rispondi + Mostra contatore caratteri + Caricamento messaggi… + Il mittente non accetta risposte + Bozza + Invio… + Export messages + Import messages + + + Nuova conversazione + Inserisci contatto o numero… + Suggerimenti + + + SMS ricevuto + Nuovo messaggio + Letto + Non letto + + + Vuoi cancellare l\'intera conversazione? + + + + %d conversazione + %d conversazioni + + + + + %d messaggio + %d messaggi + + + + Perché l\'applicazione richiede l\'accesso ad internet? + Purtroppo è necessario per poter inviare gli allegati degli MMS. Non essere in grado di inviare gli MMS sarebbe un grosso svantaggio in confronto ad altre applicazioni, quindi abbiamo deciso di intraprendere questa strada. + Ad ogni modo, come sempre, non ci sono pubblicità o tracciamenti, internet è utilizzato soltanto per l\'invio degli MMS. + + + + Simple SMS Messenger - Manage messages easily + + An easy and quick way of managing SMS and MMS messages without ads. + + A great way to stay in touch with your relatives, by sending both SMS and MMS messages. The app properly handles group messaging too, just like blocking numbers from Android 7+. + + It offers many date formats to choose from, to make you feel comfortable at using it. You can toggle between 12 and 24 hours time format too. + + It has a really tiny app size compared to the competition, making it really fast to download. + + It comes with material design and dark theme by default, provides great user experience for easy usage. The lack of internet access gives you more privacy, security and stability than other apps. + + Neturi reklamų ar nereikalingų leidimų. Programėlė visiškai atviro kodo, yra galimybė keisti spalvas. + Check out the full suite of Simple Tools here: + https://www.simplemobiletools.com + + Facebook: + https://www.facebook.com/simplemobiletools + + Reddit: + https://www.reddit.com/r/SimpleMobileTools + + + + diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 356e1f19..a0a5cb95 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages 新しい会話 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 1d10f2cf..1d8cc5e3 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages Naujas pokalbis diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 4eafaf66..e9d0b8ed 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages പുതിയ സംഭാഷണം diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 52bc4bf8..1b8c9dca 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -15,6 +15,8 @@ Afzender ondersteunt geen antwoorden Concept Versturen… + Berichten exporteren + Berichten importeren Nieuw gesprek @@ -32,7 +34,7 @@ - %d gesperk + %d gesprek %d gesprekken diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml new file mode 100644 index 00000000..08f4a634 --- /dev/null +++ b/app/src/main/res/values-pl/strings.xml @@ -0,0 +1,84 @@ + + Proste wiadomości SMS + Wiadomości SMS + Napisz wiadomość… + Wiadomość nie została wysłana + Nie wysłano. Naciśnij, aby spróbować ponownie. + Twoja wiadomość do \'%s\' nie została wysłana + Dodaj odbiorcę + Załącznik + Nie znaleziono żadnych zapisanych konwersacji + Rozpocznij konwersację + Odpowiedz + Pokazuj licznik znaków podczas pisania wiadomości + Ładowanie wiadomości… + Nadawca nie obsługuje odpowiedzi + Szkic + Wysyłanie… + Eksportuj wiadomości + Importuj wiadomości + + + Nowa konwersacja + Dodaj kontakt lub numer… + Propozycje + + + Otrzymywanie SMS + Nowa wiadomość + Oznacz jako przeczytane + Oznacz jako nieprzeczytane + + + Czy jesteś pewny/a, że chcesz usunąć wszystkie wiadomości z tej konwersacji? + + + + %d konwersację + %d konwersacje + %d konwersacji + + + + + %d wiadomość + %d wiadomości + %d wiadomości + + + + Dlaczego aplikacja wymaga dostępu do Internetu? + Niestety jest to konieczne do wysyłania załączników MMS. Brak możliwości wysyłania MMS-ów byłby naprawdę ogromną wadą w porównaniu z innymi aplikacjami, więc zdecydowaliśmy się pójść tą drogą. + Jednak, jak zwykle, nie ma żadnych reklam, śledzenia ani analityki, Internet służy tylko do wysyłania MMS-ów. + + + + Proste wiadomości SMS - Łatwo zarządzaj SMS-ami + + Łatwy i szybki sposób zarządzania wiadomościami SMS i MMS bez reklam. + + Świetny sposób na utrzymywanie kontaktu z bliskimi poprzez wysyłanie zarówno wiadomości SMS, jak i MMS. Aplikacja poprawnie obsługuje również wiadomości grupowe, podobnie jak blokowanie numerów z Androida 7+. + + Oferuje wiele formatów daty do wyboru, abyś czuł(a) się komfortowo podczas korzystania z niego. Możesz także przełączać się między 12- i 24-godzinnym formatem czasu. + + Zajmuje naprawdę mało miejsca w porównaniu do konkurencji, dzięki czemu można go szybko pobrać. + + Domyślnie jest wyposażony w Material Design i ciemny motyw, zapewniając doskonałe doświadczenie użytkownika dla łatwego użytkowania. Brak dostępu do Internetu zapewnia większą prywatność, bezpieczeństwo i stabilność niż inne aplikacje. + + Nie zawiera reklam ani niepotrzebnych uprawnień. Jest w pełni otwartoźródłowy, zapewnia konfigurowalną kolorystykę. + + Sprawdź pełen zestaw od Simple Tools tutaj: + https://www.simplemobiletools.com + + Facebook: + https://www.facebook.com/simplemobiletools + + Reddit: + https://www.reddit.com/r/SimpleMobileTools + + + + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a2c51645..3aefaa20 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -2,19 +2,21 @@ Simple SMS Messenger SMS Messenger Escrever uma mensagem… - Message not sent - Not sent. Touch to retry. - Your message to \'%s\' has not been sent + Mensagem não enviada + Não enviada. Toque para tentar novamente. + A mensagem enviada para \'%s\' não foi enviada. Adicionar pessoa Anexo Não foram encontradas conversas Iniciar uma conversa Responder Mostrar número de caracteres ao escrever a mensagem - Loading messages… - Sender doesn\'t support replies - Draft - Sending… + A carregar mensagens… + O remetente não aceita respostas + Rascunho + A enviar… + Exportar mensagens + Importar mensagens Nova conversa diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 33275eee..a4ec2cf8 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -15,6 +15,8 @@ Отправитель не поддерживает ответы Черновик Отправка… + Экспорт сообщений + Импорт сообщений Новая переписка diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 54a8271f..814a4c0f 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Koncept Odosiela sa… + Exportovať správy + Importovať správy Nová konverzácia diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 3f55992f..f23b8a0d 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages Yeni görüşme diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 338bb279..a2787b8b 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages Нове листування diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2abf8998..36f0de29 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages 新的对话 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 990ae0d5..6a0f4bfe 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,12 +15,8 @@ Sender doesn\'t support replies Draft Sending… - Configure Notification - - - Name and Message - Name - No Details + Export messages + Import messages New conversation @@ -48,6 +44,11 @@ %d messages + + Lock screen notification visibility + Sender and message + Sender only + Why does the app require access to the internet? Sadly it is needed for sending MMS attachments. Not being able to send MMS would be a really huge disadvantage compared to other apps, so we decided to go this way. diff --git a/app/src/main/res/xml/searchable.xml b/app/src/main/res/xml/searchable.xml new file mode 100644 index 00000000..892fa25a --- /dev/null +++ b/app/src/main/res/xml/searchable.xml @@ -0,0 +1,5 @@ + + diff --git a/build.gradle b/build.gradle index b604e4eb..22e54ea7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.4.21' + ext.kotlin_version = '1.5.21' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.1' + classpath 'com.android.tools.build:gradle:4.2.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/fastlane/metadata/android/en-US/changelogs/26.txt b/fastlane/metadata/android/en-US/changelogs/26.txt new file mode 100644 index 00000000..914590da --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/26.txt @@ -0,0 +1,3 @@ + * Fixed a glitch with "Sending..." stuck at messages + * Allow selecting a phone numbers at contacts with multiple ones + * Some translation and stability improvements diff --git a/fastlane/metadata/android/en-US/changelogs/27.txt b/fastlane/metadata/android/en-US/changelogs/27.txt new file mode 100644 index 00000000..10157d25 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/27.txt @@ -0,0 +1,3 @@ + * Fixed a glitch with inability to send messages in empty conversations + * Adding a settings item for quickly getting into notification settings + * Some stability and translation improvements diff --git a/fastlane/metadata/android/en-US/changelogs/28.txt b/fastlane/metadata/android/en-US/changelogs/28.txt new file mode 100644 index 00000000..6a73d43f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/28.txt @@ -0,0 +1 @@ + * Adding some stability and translation improvements diff --git a/fastlane/metadata/android/en-US/changelogs/29.txt b/fastlane/metadata/android/en-US/changelogs/29.txt new file mode 100644 index 00000000..09a9182e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29.txt @@ -0,0 +1,3 @@ + * Added Search + * Added a White theme with special handling + * Some stability and translation improvements diff --git a/fastlane/metadata/android/en-US/changelogs/30.txt b/fastlane/metadata/android/en-US/changelogs/30.txt new file mode 100644 index 00000000..f1b57458 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/30.txt @@ -0,0 +1,3 @@ + * Improved search + * Properly handle sending messages from notification Reply action + * Some design, stability and translation improvements diff --git a/fastlane/metadata/android/en-US/changelogs/31.txt b/fastlane/metadata/android/en-US/changelogs/31.txt new file mode 100644 index 00000000..01022908 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/31.txt @@ -0,0 +1,2 @@ + * Fixed an error message wrongly popping up in some cases + * Some stabiliy and translation improvements diff --git a/fastlane/metadata/android/en-US/changelogs/33.txt b/fastlane/metadata/android/en-US/changelogs/33.txt new file mode 100644 index 00000000..45073c2a --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/33.txt @@ -0,0 +1,2 @@ + * Fixed a glitch with current conversation not being updated correctly at incoming messages + * Couple other stability, translation and bugfixes diff --git a/fastlane/metadata/android/en-US/changelogs/34.txt b/fastlane/metadata/android/en-US/changelogs/34.txt new file mode 100644 index 00000000..1d774fe2 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/34.txt @@ -0,0 +1 @@ + * Adding some UX, stability and translation improvements diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_1.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_1.jpg deleted file mode 100644 index 6e9ebf4e..00000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_1.jpg and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.jpg deleted file mode 100644 index b66c01c5..00000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.jpg and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.jpg deleted file mode 100644 index 6fa74117..00000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.jpg and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/english/1.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/1.jpg new file mode 100644 index 00000000..2c6f62d1 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/1.jpg differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/english/2.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/2.jpg new file mode 100644 index 00000000..ea78e479 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/2.jpg differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/english/3.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/3.jpg new file mode 100644 index 00000000..dc5ac2cc Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/3.jpg differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/english/4.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/4.jpg new file mode 100644 index 00000000..e1ff8478 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/english/4.jpg differ diff --git a/fastlane/metadata/android/pl/full_description.txt b/fastlane/metadata/android/pl/full_description.txt new file mode 100644 index 00000000..27702614 --- /dev/null +++ b/fastlane/metadata/android/pl/full_description.txt @@ -0,0 +1,18 @@ +Świetny sposób na utrzymywanie kontaktu z bliskimi przez wysyłanie zarówno wiadomości SMS, jak i MMS. Aplikacja poprawnie obsługuje również wiadomości grupowe, podobnie jak blokowanie numerów z Androida 7+. + +Oferuje wiele formatów daty do wyboru, abyś czuł(a) się komfortowo podczas korzystania z niego. Możesz także przełączać się między 12- i 24-godzinnym formatem czasu. + +Zajmuje naprawdę mało miejsca w porównaniu do konkurencji, dzięki czemu można go szybko pobrać. + +Domyślnie jest wyposażony w Material Design i ciemny motyw, zapewniając doskonałe doświadczenie użytkownika dla łatwego użytkowania. Brak dostępu do Internetu zapewnia większą prywatność, bezpieczeństwo i stabilność niż inne aplikacje. + +Nie zawiera reklam ani niepotrzebnych uprawnień. Jest w pełni otwartoźródłowy, zapewnia konfigurowalną kolorystykę. + +Sprawdź pełen zestaw od Simple Tools tutaj: +https://www.simplemobiletools.com + +Facebook: +https://www.facebook.com/simplemobiletools + +Reddit: +https://www.reddit.com/r/SimpleMobileTools diff --git a/fastlane/metadata/android/pl/short_description.txt b/fastlane/metadata/android/pl/short_description.txt new file mode 100644 index 00000000..fa223a61 --- /dev/null +++ b/fastlane/metadata/android/pl/short_description.txt @@ -0,0 +1 @@ +Łatwy i szybki sposób zarządzania wiadomościami SMS i MMS bez reklam. diff --git a/fastlane/metadata/android/pl/title.txt b/fastlane/metadata/android/pl/title.txt new file mode 100644 index 00000000..78bb40c6 --- /dev/null +++ b/fastlane/metadata/android/pl/title.txt @@ -0,0 +1 @@ +Proste wiadomości SMS - Łatwo zarządzaj SMS-ami diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a99abc9d..0521dba2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip