Merge pull request #8 from SimpleMobileTools/master

upd
This commit is contained in:
solokot 2021-02-16 17:53:51 +03:00 committed by GitHub
commit 2a9f50b006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 829 additions and 121 deletions

View File

@ -17,7 +17,7 @@ insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 4
continuation_indent_size = 8
continuation_indent_size = 4
[*.xml]
continuation_indent_size = 4

View File

@ -1,6 +1,32 @@
Changelog
==========
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)*
----------------------------

View File

@ -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
<a href='https://play.google.com/store/apps/details?id=com.simplemobiletools.smsmessenger'><img src='https://simplemobiletools.com/assets/images/google-play.png' alt='Get it on Google Play' height=45/></a>
<a href='https://f-droid.org/packages/com.simplemobiletools.smsmessenger'><img src='https://simplemobiletools.com/assets/images/f-droid.png' alt='Get it on F-Droid' height='45' /></a>
<div style="display:flex;">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/app_1.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/english/1.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/english/2.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/english/3.jpg" width="30%">
</div>

View File

@ -16,8 +16,8 @@ android {
applicationId "com.simplemobiletools.smsmessenger"
minSdkVersion 22
targetSdkVersion 30
versionCode 25
versionName "5.8.0"
versionCode 29
versionName "5.9.0"
setProperty("archivesBaseName", "sms-messenger")
}
@ -56,10 +56,10 @@ android {
}
dependencies {
implementation 'com.simplemobiletools:commons:5.32.20'
implementation 'com.simplemobiletools:commons:5.33.32'
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'

View File

@ -38,6 +38,21 @@
android:name=".activities.ThreadActivity"
android:parentActivityName=".activities.MainActivity" />
<activity
android:name=".activities.SearchActivity"
android:label=""
android:parentActivityName=".activities.MainActivity"
android:resizeableActivity="true">
<meta-data
android:name="android.app.default_searchable"
android:resource="@xml/searchable"/>
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
</activity>
<activity
android:name=".activities.NewConversationActivity"
android:parentActivityName=".activities.MainActivity">

View File

@ -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)
@ -295,6 +297,10 @@ class MainActivity : SimpleActivity() {
.build()
}
private fun launchSearch() {
startActivity(Intent(applicationContext, SearchActivity::class.java))
}
private fun launchSettings() {
startActivity(Intent(applicationContext, SettingsActivity::class.java))
}

View File

@ -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
@ -87,9 +89,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 {
@ -132,7 +137,20 @@ class NewConversationActivity : SimpleActivity() {
ContactsAdapter(this, contacts, contacts_list, null) {
hideKeyboard()
launchThreadActivity((it as SimpleContact).phoneNumbers.first(), it.name)
val contact = it as SimpleContact
val phoneNumbers = contact.phoneNumbers
if (phoneNumbers.size > 1) {
val items = ArrayList<RadioItem>()
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
}

View File

@ -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<Message>, conversations: List<Conversation>, searchedText: String) {
val searchResults = ArrayList<SearchResult>()
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)
}
}
}
}

View File

@ -30,6 +30,7 @@ class SettingsActivity : SimpleActivity() {
setupPurchaseThankYou()
setupCustomizeColors()
setupCustomizeNotifications()
setupUseEnglish()
setupManageBlockedNumbers()
setupChangeDateTimeFormat()
@ -66,6 +67,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

View File

@ -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,62 +116,6 @@ class ThreadActivity : SimpleActivity() {
isActivityVisible = false
}
private fun setupThread() {
val privateCursor = getMyContactsCursor()?.loadInBackground()
ensureBackgroundThread {
val cachedMessagesCode = messages.hashCode()
messages = getMessages(threadId)
if (messages.hashCode() == cachedMessagesCode) {
return@ensureBackgroundThread
}
setupParticipants()
// check if no participant came from a privately stored contact in Simple Contacts
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
if (privateContacts.isNotEmpty()) {
val senderNumbersToReplace = HashMap<String, String>()
participants.filter { it.doesContainPhoneNumber(it.name) }.forEach { participant ->
privateContacts.firstOrNull { it.doesContainPhoneNumber(participant.phoneNumbers.first()) }?.apply {
senderNumbersToReplace[participant.phoneNumbers.first()] = name
participant.name = name
participant.photoUri = photoUri
}
}
messages.forEach { message ->
if (senderNumbersToReplace.keys.contains(message.senderName)) {
message.senderName = senderNumbersToReplace[message.senderName]!!
}
}
}
if (participants.isEmpty()) {
val name = intent.getStringExtra(THREAD_TITLE) ?: ""
val number = intent.getStringExtra(THREAD_NUMBER)
if (number == null) {
toast(R.string.unknown_error_occurred)
finish()
return@ensureBackgroundThread
}
val contact = SimpleContact(0, 0, name, "", arrayListOf(number), ArrayList(), ArrayList())
participants.add(contact)
}
messages.chunked(30).forEach { currentMessages ->
messagesDB.insertMessages(*currentMessages.toTypedArray())
}
setupAttachmentSizes()
setupAdapter()
runOnUiThread {
setupThreadTitle()
setupSIMSelector()
}
}
}
override fun onDestroy() {
super.onDestroy()
bus?.unregister(this)
@ -219,6 +173,62 @@ class ThreadActivity : SimpleActivity() {
}
}
private fun setupThread() {
val privateCursor = getMyContactsCursor()?.loadInBackground()
ensureBackgroundThread {
val cachedMessagesCode = messages.hashCode()
messages = getMessages(threadId)
if (messages.hashCode() == cachedMessagesCode && participants.isNotEmpty()) {
return@ensureBackgroundThread
}
setupParticipants()
// check if no participant came from a privately stored contact in Simple Contacts
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
if (privateContacts.isNotEmpty()) {
val senderNumbersToReplace = HashMap<String, String>()
participants.filter { it.doesContainPhoneNumber(it.name) }.forEach { participant ->
privateContacts.firstOrNull { it.doesContainPhoneNumber(participant.phoneNumbers.first()) }?.apply {
senderNumbersToReplace[participant.phoneNumbers.first()] = name
participant.name = name
participant.photoUri = photoUri
}
}
messages.forEach { message ->
if (senderNumbersToReplace.keys.contains(message.senderName)) {
message.senderName = senderNumbersToReplace[message.senderName]!!
}
}
}
if (participants.isEmpty()) {
val name = intent.getStringExtra(THREAD_TITLE) ?: ""
val number = intent.getStringExtra(THREAD_NUMBER)
if (number == null) {
toast(R.string.unknown_error_occurred)
finish()
return@ensureBackgroundThread
}
val contact = SimpleContact(0, 0, name, "", arrayListOf(number), ArrayList(), ArrayList())
participants.add(contact)
}
messages.chunked(30).forEach { currentMessages ->
messagesDB.insertMessages(*currentMessages.toTypedArray())
}
setupAttachmentSizes()
setupAdapter()
runOnUiThread {
setupThreadTitle()
setupSIMSelector()
}
}
}
private fun setupAdapter() {
threadItems = getThreadItems()
invalidateOptionsMenu()
@ -458,11 +468,20 @@ class ThreadActivity : SimpleActivity() {
}
private fun showSelectedContacts() {
val adjustedColor = getAdjustedPrimaryColor()
val views = ArrayList<View>()
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)

View File

@ -5,12 +5,16 @@ 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<SimpleContact>) : ArrayAdapter<SimpleContact>(activity, 0, contacts) {
var resultList = ArrayList<SimpleContact>()
@ -30,8 +34,13 @@ class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: Ar
isFocusable = false
}
val backgroundColor = activity.config.backgroundColor
findViewById<TextView>(R.id.item_contact_name).text = contact.name
findViewById<TextView>(R.id.item_contact_number).text = contact.phoneNumbers.first()
findViewById<RelativeLayout>(R.id.item_contact_holder).setBackgroundColor(backgroundColor.darkenColor())
findViewById<TextView>(R.id.item_contact_name).setTextColor(backgroundColor.getContrastColor())
findViewById<TextView>(R.id.item_contact_number).setTextColor(backgroundColor.getContrastColor())
SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name)
}

View File

@ -232,7 +232,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)
}

View File

@ -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<SearchResult>, 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<SearchResult>, highlightText: String = "") {
if (newItems.hashCode() != searchResults.hashCode()) {
searchResults = newItems.clone() as ArrayList<SearchResult>
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)
}
}
}

View File

@ -42,8 +42,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<ThreadItem>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
class ThreadAdapter(
activity: SimpleActivity, var messages: ArrayList<ThreadItem>, 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 +136,17 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
}
private fun copyToClipboard() {
val firstItem = getSelectedItems().first() as? Message ?: return
val firstItem = getSelectedItems().firstOrNull() as? Message ?: return
activity.copyToClipboard(firstItem.body)
}
private fun shareText() {
val firstItem = getSelectedItems().first() as? Message ?: return
val firstItem = getSelectedItems().firstOrNull() as? Message ?: return
activity.shareTextIntent(firstItem.body)
}
private fun selectText() {
val firstItem = getSelectedItems().first() as? Message ?: return
val firstItem = getSelectedItems().firstOrNull() as? Message ?: return
if (firstItem.body.trim().isNotEmpty()) {
SelectTextDialog(activity, firstItem.body)
}
@ -224,7 +226,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
} else {
thread_message_sender_photo?.beGone()
val background = context.getAdjustedPrimaryColor()
thread_message_body.background.applyColorFilter(background.adjustAlpha(0.8f))
thread_message_body.background.applyColorFilter(background)
val contrastColor = background.getContrastColor()
thread_message_body.setTextColor(contrastColor)
@ -287,7 +289,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
val background = context.getAdjustedPrimaryColor()
val attachmentView = layoutInflater.inflate(R.layout.item_sent_unknown_attachment, null).apply {
thread_sent_attachment_label.apply {
this.background.applyColorFilter(background.adjustAlpha(0.8f))
this.background.applyColorFilter(background)
setTextColor(background.getContrastColor())
if (attachment.filename.isNotEmpty()) {
thread_sent_attachment_label.text = attachment.filename
@ -329,7 +331,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
private fun setupDateTime(view: View, dateTime: ThreadDateTime) {
view.apply {
thread_date_time.apply {
text = dateTime.date.formatDateOrTime(context, false)
text = dateTime.date.formatDateOrTime(context, false, false)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
}
thread_date_time.setTextColor(textColor)

View File

@ -709,7 +709,7 @@ fun Context.showMessageNotification(address: String, body: String, threadId: Lon
val builder = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL)
.setContentTitle(sender)
.setContentText(body)
.setColor(config.primaryColor)
.setColor(getAdjustedPrimaryColor())
.setSmallIcon(R.drawable.ic_messenger)
.setLargeIcon(largeIcon)
.setStyle(NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body))

View File

@ -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"

View File

@ -17,6 +17,9 @@ interface ConversationsDao {
@Query("SELECT * FROM conversations WHERE read = 0")
fun getUnreadConversations(): List<Conversation>
@Query("SELECT * FROM conversations WHERE title LIKE :text")
fun getConversationsWithText(text: String): List<Conversation>
@Query("UPDATE conversations SET read = 1 WHERE thread_id = :threadId")
fun markRead(threadId: Long)

View File

@ -23,6 +23,9 @@ interface MessagesDao {
@Query("SELECT * FROM messages WHERE thread_id = :threadId")
fun getThreadMessages(threadId: Long): List<Message>
@Query("SELECT * FROM messages WHERE body LIKE :text")
fun getMessagesWithText(text: String): List<Message>
@Query("UPDATE messages SET read = 1 WHERE id = :id")
fun markRead(id: Long)

View File

@ -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)

View File

@ -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

View File

@ -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
@ -92,7 +93,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))

View File

@ -1,9 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/selected_contact_bg">
<shape android:shape="rectangle">
<corners android:radius="@dimen/normal_margin" />
<corners android:radius="@dimen/normal_margin" />
<solid android:color="@color/activated_item_foreground" />
<solid android:color="@color/md_grey_white" />
</shape>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/search_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/search_placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/activity_margin"
android:alpha="0.8"
android:gravity="center"
android:paddingStart="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
android:text="@string/no_items_found"
android:textSize="@dimen/bigger_text_size"
android:textStyle="italic" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/search_placeholder_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/search_placeholder"
android:layout_centerHorizontal="true"
android:alpha="0.8"
android:gravity="center"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/medium_margin"
android:text="@string/type_2_characters"
android:textSize="@dimen/bigger_text_size"
android:textStyle="italic" />
<com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/search_results_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical"
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
</RelativeLayout>

View File

@ -53,6 +53,27 @@
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_customize_notifications_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingLeft="@dimen/normal_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingBottom="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_customize_notifications_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingStart="@dimen/medium_margin"
android:text="@string/customize_notifications" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_manage_blocked_numbers_holder"
android:layout_width="match_parent"

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/search_result_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/small_margin"
android:layout_marginBottom="@dimen/small_margin"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/normal_margin">
<ImageView
android:id="@+id/search_result_image"
android:layout_width="@dimen/normal_icon_size"
android:layout_height="@dimen/normal_icon_size"
android:layout_marginEnd="@dimen/normal_margin" />
<TextView
android:id="@+id/search_result_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/search_result_date"
android:layout_toEndOf="@+id/search_result_image"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="@dimen/activity_margin"
android:textSize="@dimen/big_text_size"
tools:text="John" />
<TextView
android:id="@+id/search_result_snippet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/search_result_title"
android:layout_toEndOf="@+id/search_result_image"
android:alpha="0.7"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="@dimen/activity_margin"
android:textSize="@dimen/big_text_size"
tools:text="Hey buddy!" />
<TextView
android:id="@+id/search_result_date"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignTop="@+id/search_result_title"
android:layout_alignBottom="@+id/search_result_title"
android:layout_alignParentEnd="true"
android:layout_marginTop="@dimen/tiny_margin"
android:alpha="0.7"
android:gravity="center_vertical"
android:textSize="@dimen/smaller_text_size"
tools:text="08/02/2021" />
</RelativeLayout>

View File

@ -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">
<ImageView
android:id="@+id/suggested_contact_image"

View File

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search_vector"
android:title="@string/search"
app:showAsAction="always" />
<item
android:id="@+id/settings"
android:title="@string/settings"

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search_vector"
android:title="@string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|always" />
</menu>

View File

@ -2,19 +2,21 @@
<string name="app_name">Schlichter SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Schreibe eine Nachricht…</string>
<string name="message_not_sent_short">Message not sent</string>
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
<string name="message_not_sent_short">Nachricht nicht versendet.</string>
<string name="message_not_sent_touch_retry">Nachricht nicht versendet. Berühre, um es erneut zu versuchen.</string>
<string name="message_sending_error">Deine Nachricht am \'%s\' wurde nicht gesendet.</string>
<string name="add_person">Person hinzufügen</string>
<string name="attachment">Anhang</string>
<string name="no_conversations_found">Keine gespeicherten Chats gefunden</string>
<string name="start_conversation">Neuen Chat beginnen</string>
<string name="reply">Antworten</string>
<string name="show_character_counter">Show a character counter at writing messages</string>
<string name="loading_messages">Loading messages…</string>
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="show_character_counter">Zeige einen Zeichenzähler während dem Schreiben von Nachrichten.</string>
<string name="loading_messages">Lade Nachrichten…</string>
<string name="no_reply_support">Der Absender unterstützt keine Antworten.</string>
<string name="draft">Entwurf</string>
<string name="sending">Sende…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Neuer Chat</string>
@ -49,21 +51,21 @@
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
<string name="app_title">Simple SMS Messenger - Manage messages easily</string>
<string name="app_title">Simple SMS Messenger-Nachrichten simple verwalten</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">An easy and quick way of managing SMS and MMS messages without ads.</string>
<string name="app_short_description">Eine einfache und schnelle Art SMS &amp; MMS ohne Werbung zu verwalten.</string>
<string name="app_long_description">
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.
<b>Check out the full suite of Simple Tools here:</b>
<b>Entdecke alle Simple Tools hier:</b>
https://www.simplemobiletools.com
<b>Facebook:</b>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Νέα συνομιλία</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nueva conversación</string>

View File

@ -0,0 +1,82 @@
<resources>
<string name="app_name">Simple SMS Messenger</string>
<string name="app_launcher_name">Viestit</string>
<string name="type_a_message">Lähetä viesti…</string>
<string name="message_not_sent_short">Viestiä ei lähetetty</string>
<string name="message_not_sent_touch_retry">Ei lähetetty. Yritä uudelleen koskemalla.</string>
<string name="message_sending_error">Viestiäsi henkilölle \'%s\' ei lähetetty.</string>
<string name="add_person">Lisää henkilö</string>
<string name="attachment">Liite</string>
<string name="no_conversations_found">Tallennettuja keskusteluja ei löytyny</string>
<string name="start_conversation">Aloita keskustelu</string>
<string name="reply">Vastaa</string>
<string name="show_character_counter">Näytä merkkimäärä kirjoittaessasi viestejä</string>
<string name="loading_messages">Ladataan viestejä…</string>
<string name="no_reply_support">Lähettäjä ei tue vastauksia</string>
<string name="draft">Luonnos</string>
<string name="sending">Lähetetään…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Uusi keskustelu</string>
<string name="add_contact_or_number">Lisää yhteystieto tai numero…</string>
<string name="suggestions">Ehdotuksia</string>
<!-- Notifications -->
<string name="channel_received_sms">Vastaanotettu tekstiviesti</string>
<string name="new_message">Uusi viesti</string>
<string name="mark_as_read">Merkitse luetuksi</string>
<string name="mark_as_unread">Merkitse lukemattomaksi</string>
<!-- Confirmation dialog -->
<string name="delete_whole_conversation_confirmation">Haluatko varmasti poistaa kaikki tämän keskustelun viestit?</string>
<!-- Are you sure you want to delete 5 conversations? -->
<plurals name="delete_conversations">
<item quantity="one">yhden keskustelun</item>
<item quantity="other">%d keskustelua</item>
</plurals>
<!-- Are you sure you want to delete 5 messages? -->
<plurals name="delete_messages">
<item quantity="one">yhden viestin</item>
<item quantity="other">%d viestiä</item>
</plurals>
<!-- FAQ -->
<string name="faq_1_title">Miksi sovellus vaatii Internet-yhteyden?</string>
<string name="faq_1_text">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.</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
<string name="app_title">Simple SMS Messenger - Manage messages easily</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">An easy and quick way of managing SMS and MMS messages without ads.</string>
<string name="app_long_description">
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.
<b>Check out the full suite of Simple Tools here:</b>
https://www.simplemobiletools.com
<b>Facebook:</b>
https://www.facebook.com/simplemobiletools
<b>Reddit:</b>
https://www.reddit.com/r/SimpleMobileTools
</string>
<!--
Haven't found some strings? There's more at
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
-->
</resources>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nouvelle conversation</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Percakapan baru</string>

View File

@ -0,0 +1,81 @@
<resources>
<string name="app_name">SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Componi messaggio</string>
<string name="message_not_sent_short">Messaggio non inviato</string>
<string name="message_not_sent_touch_retry">Non inviato. Tocca per riprovare</string>
<string name="message_sending_error">Il tuo messaggio a \'%s\' non è stato inviato</string>
<string name="add_person">Aggiungi persona</string>
<string name="attachment">Allegato</string>
<string name="no_conversations_found">Nessuna conversazione trovata</string>
<string name="start_conversation">Inizia conversazione</string>
<string name="reply">Rispondi</string>
<string name="show_character_counter">Mostra contatore caratteri</string>
<string name="loading_messages">Caricamento messaggi…</string>
<string name="no_reply_support">Il mittente non accetta risposte</string>
<string name="draft">Bozza</string>
<string name="sending">Invio…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nuova conversazione</string>
<string name="add_contact_or_number">Inserisci contatto o numero…</string>
<string name="suggestions">Suggerimenti</string>
<!-- Notifications -->
<string name="channel_received_sms">SMS ricevuto</string>
<string name="new_message">Nuovo messaggio</string>
<string name="mark_as_read">Letto</string>
<string name="mark_as_unread">Non letto</string>
<!-- Confirmation dialog -->
<string name="delete_whole_conversation_confirmation">Vuoi cancellare l\'intera conversazione?</string>
<!-- Are you sure you want to delete 5 conversations? -->
<plurals name="delete_conversations">
<item quantity="one">%d conversazione</item>
<item quantity="other">%d conversazioni</item>
</plurals>
<!-- Are you sure you want to delete 5 messages? -->
<plurals name="delete_messages">
<item quantity="one">%d messaggio</item>
<item quantity="other">%d messaggi</item>
</plurals>
<!-- FAQ -->
<string name="faq_1_title">Perché l\'applicazione richiede l\'accesso ad internet?</string>
<string name="faq_1_text">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.</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
<string name="app_title">Simple SMS Messenger - Manage messages easily</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">An easy and quick way of managing SMS and MMS messages without ads.</string>
<string name="app_long_description">
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.
<b>Check out the full suite of Simple Tools here:</b>
https://www.simplemobiletools.com
<b>Facebook:</b>
https://www.facebook.com/simplemobiletools
<b>Reddit:</b>
https://www.reddit.com/r/SimpleMobileTools
</string>
<!--
Haven't found some strings? There's more at
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
-->
</resources>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">新しい会話</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Naujas pokalbis</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">പുതിയ സംഭാഷണം</string>

View File

@ -2,9 +2,9 @@
<string name="app_name">Eenvoudig Berichtenbeheer (SMS)</string>
<string name="app_launcher_name">Berichten</string>
<string name="type_a_message">Typ een bericht…</string>
<string name="message_not_sent_short">Message not sent</string>
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
<string name="message_not_sent_short">Bericht niet verzonden</string>
<string name="message_not_sent_touch_retry">Niet verzonden. Probeer het nogmaals.</string>
<string name="message_sending_error">Bericht naar \'%s\' is niet verzonden</string>
<string name="add_person">Persoon toevoegen</string>
<string name="attachment">Bijlage</string>
<string name="no_conversations_found">Geen opgeslagen berichten gevonden</string>
@ -15,6 +15,8 @@
<string name="no_reply_support">Afzender ondersteunt geen antwoorden</string>
<string name="draft">Concept</string>
<string name="sending">Versturen…</string>
<string name="export_messages">Berichten exporteren</string>
<string name="import_messages">Berichten importeren</string>
<!-- New conversation -->
<string name="new_conversation">Nieuw gesprek</string>

View File

@ -2,19 +2,21 @@
<string name="app_name">Simple SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Escrever uma mensagem…</string>
<string name="message_not_sent_short">Message not sent</string>
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
<string name="message_not_sent_short">Mensagem não enviada</string>
<string name="message_not_sent_touch_retry">Não enviada. Toque para tentar novamente.</string>
<string name="message_sending_error">A mensagem enviada para \'%s\' não foi enviada.</string>
<string name="add_person">Adicionar pessoa</string>
<string name="attachment">Anexo</string>
<string name="no_conversations_found">Não foram encontradas conversas</string>
<string name="start_conversation">Iniciar uma conversa</string>
<string name="reply">Responder</string>
<string name="show_character_counter">Mostrar número de caracteres ao escrever a mensagem</string>
<string name="loading_messages">Loading messages…</string>
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="loading_messages">A carregar mensagens…</string>
<string name="no_reply_support">O remetente não aceita respostas</string>
<string name="draft">Rascunho</string>
<string name="sending">A enviar…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nova conversa</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Отправитель не поддерживает ответы</string>
<string name="draft">Черновик</string>
<string name="sending">Отправка…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Новая переписка</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Koncept</string>
<string name="sending">Odosiela sa…</string>
<string name="export_messages">Exportovať správy</string>
<string name="import_messages">Importovať správy</string>
<!-- New conversation -->
<string name="new_conversation">Nová konverzácia</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Yeni görüşme</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Нове листування</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">新的对话</string>

View File

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">New conversation</string>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search"
android:label="@string/app_name"/>

View File

@ -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.4.30'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.1'
classpath 'com.android.tools.build:gradle:4.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
* Adding some stability and translation improvements

View File

@ -0,0 +1,3 @@
* Added Search
* Added a White theme with special handling
* Some stability and translation improvements

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB