Commit 98e4c3ad authored by Romain Hunault's avatar Romain Hunault

Merge branch 'dev' into 'master'

[RELEASE] Sprint Istanbul

Closes e/management#1015

See merge request !21
parents e750dffb ab18217a
Pipeline #48448 passed with stage
in 10 minutes and 16 seconds
![QKSMS](https://user-images.githubusercontent.com/4358785/39079306-a5a409b6-44e5-11e8-8589-b4acd63b636e.jpg)
# Message
# QKSMS
Message is an open source replacement to the stock messaging app on Android.
Message is forked from [QKSMS](https://github.com/moezbhatti/qksms)
[![Build Status](https://travis-ci.org/moezbhatti/qksms.svg?branch=master)](https://travis-ci.org/moezbhatti/qksms)
[![Liberapay donation](https://img.shields.io/badge/donate-liberapay-yellow.svg)](https://liberapay.com/moezbhatti/)
[![Bitcoin donation](https://img.shields.io/badge/donate-bitcoin-yellow.svg)](https://qklabs.com/donate-btc/)
[![PayPal donation](https://img.shields.io/badge/donate-paypal-yellow.svg)](https://qklabs.com/donate)
## Authors
QKSMS is an open source replacement to the [stock messaging app](https://github.com/android/platform_packages_apps_mms) on Android. It is currently available on the [Google Play Store](https://play.google.com/store/apps/details?id=com.moez.QKSMS) and on [F-Droid](https://f-droid.org/repository/browse/?fdid=com.moez.QKSMS)
[Authors](https://gitlab.e.foundation/e/apps/Message/-/blob/master/AUTHORS)
<a href="https://play.google.com/store/apps/details?id=com.moez.QKSMS"><img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Download on Google Play" height="100"></a><a href="https://f-droid.org/repository/browse/?fdid=com.moez.QKSMS"><img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="100"></a>
## Release Notes
## Reporting bugs
Check out the [Release Notes](https://gitlab.e.foundation/e/apps/Message/-/releases) to find out what changed
in each version of Message.
A great bug report contains a description of the problem and steps to reproduce the problem. We need to know what we're looking for and where to look for it.
## Privacy Policy
When reporting a bug, please make sure to provide the following information:
- Steps to reproduce the issue
- QKSMS version
- Device / OS information
## Translations
If you'd like to add translations to QKSMS, please join the project on [Crowdin](https://crowdin.com/project/qksms). Translations that are committed directly to source files will not be accepted.
## Thank you
A special thank you to Jake ([@klinker41](https://github.com/klinker41)) and Luke Klinker ([@klinker24](https://github.com/klinker24)) for their work on [android-smsmms](https://github.com/klinker41/android-smsmms), which has been an unspeakably large help in implementing MMS into QKSMS.
## Contact
QKSMS is developed and maintained by [Moez Bhatti](https://github.com/moezbhatti). Feel free to reach out to moez@qklabs.com
[Privacy Policy](https://e.foundation/legal-notice-privacy)
[Terms of service](https://e.foundation/legal-notice-privacy)
## License
QKSMS is released under the **The GNU General Public License v3.0 (GPLv3)**, which can be found in the `LICENSE` file in the root of this project.
Message is released under the [The GNU General Public License v3.0 (GPLv3)](https://gitlab.e.foundation/e/apps/Message/-/blob/master/LICENSE)
......@@ -3,11 +3,11 @@
buildscript {
ext.androidx_appcompat_version = '1.1.0'
ext.androidx_constraintlayout_version = '1.1.3'
ext.androidx_core_version = '1.1.0'
ext.androidx_core_version = '1.2.0'
ext.androidx_emoji_version = '1.0.0'
ext.androidx_exifinterface_version = '1.0.0'
ext.androidx_testrunner_version = '1.1.0-alpha3'
ext.androidx_viewpager_version = '1.0.0-beta05'
ext.androidx_viewpager_version = '1.0.0'
ext.autodispose_version = '1.3.0'
ext.conductor_version = '2.1.5'
ext.coroutines_version = '1.2.2'
......@@ -17,8 +17,8 @@ buildscript {
ext.glide_version = "4.8.0"
ext.junit_version = '4.12'
ext.kotlin_version = '1.3.50'
ext.lifecycle_version = '2.1.0'
ext.material_version = '1.0.0'
ext.lifecycle_version = '2.2.0'
ext.material_version = '1.1.0'
ext.mockito_version = '2.18.3'
ext.moshi_version = '1.8.0'
ext.okhttp3_version = '4.1.0'
......
......@@ -43,6 +43,10 @@ android {
withAnalytics { dimension "analytics" }
noAnalytics { dimension "analytics" }
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
......
......@@ -33,6 +33,16 @@ android {
minSdkVersion 21
targetSdkVersion 28 // Don't upgrade to 29 until we support Scoped storage
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
......
......@@ -187,6 +187,12 @@
<data android:scheme="mmsto" />
</intent-filter>
</service>
<service
android:name=".feature.service.ESmsRestoreService"
android:exported="true">
</service>
<service
android:name=".common.util.QkChooserTargetService"
android:label="@string/app_name"
......
package foundation.e.message;
interface IRestoreService {
oneway void restoreMessages(in String messagesJson);
}
......@@ -141,36 +141,11 @@ class Navigator @Inject constructor(
startActivity(intent)
}
fun showDeveloper() {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/moezbhatti"))
startActivityExternal(intent)
}
fun showSourceCode() {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/moezbhatti/qksms"))
startActivityExternal(intent)
}
fun showFork() {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/moezbhatti/qksms"))
startActivity(intent)
}
fun showCopyright() {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://gitlab.e.foundation/e/apps/message/blob/master/AUTHORS"))
fun openUri(uri: Uri) {
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
}
fun showChangelog() {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/moezbhatti/qksms/releases"))
startActivityExternal(intent)
}
fun showLicense() {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://gitlab.e.foundation/e/apps/message/blob/master/LICENSE"))
startActivityExternal(intent)
}
fun showBlockedConversations() {
val intent = Intent(context, BlockingActivity::class.java)
startActivity(intent)
......@@ -287,7 +262,6 @@ class Navigator @Inject constructor(
if (threadId != 0L) {
notificationManager.createNotificationChannel(threadId)
}
val channelId = notificationManager.buildNotificationChannelId(threadId)
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId)
......
......@@ -29,7 +29,8 @@ import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.*
import kotlinx.android.synthetic.main.toolbar.view.*
abstract class QkController<ViewContract : QkViewContract<State>, State, Presenter : QkPresenter<ViewContract, State>> : LifecycleController(), LayoutContainer {
abstract class QkController<ViewContract : QkViewContract<State>,
State, Presenter : QkPresenter<ViewContract, State>> : LifecycleController(), LayoutContainer {
abstract var presenter: Presenter
......
......@@ -19,6 +19,7 @@
package com.moez.QKSMS.feature.compose
import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.Glide
......@@ -80,7 +81,7 @@ class AttachmentAdapter @Inject constructor(
.mapNotNull { vCard -> Ezvcard.parse(vCard).first() }
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { vcard -> view.name?.text = vcard.formattedName.value }
.subscribe( { vcard -> view.name?.text = vcard.formattedName.value }, { throwable -> Log.i("AttachmentAdapter.kt", "Name field is null") } )
}
}
......@@ -89,4 +90,4 @@ class AttachmentAdapter @Inject constructor(
is Attachment.Contact -> VIEW_TYPE_CONTACT
}
}
\ No newline at end of file
}
......@@ -19,6 +19,7 @@
package com.moez.QKSMS.feature.compose.part
import android.content.Context
import android.util.Log
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
......@@ -63,7 +64,7 @@ class VCardBinder @Inject constructor(colors: Colors, private val context: Conte
.mapNotNull { inputStream -> inputStream.use { Ezvcard.parse(it).first() } }
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { vcard -> view.name?.text = vcard.formattedName.value }
.subscribe( { vcard -> view.name?.text = vcard.formattedName.value }, { throwable -> Log.i("VCardBinder.kt", "Name field is null") } )
val params = view.vCardBackground.layoutParams as FrameLayout.LayoutParams
if (!message.isMe()) {
......@@ -81,4 +82,4 @@ class VCardBinder @Inject constructor(colors: Colors, private val context: Conte
}
}
}
\ No newline at end of file
}
......@@ -18,6 +18,7 @@
*/
package com.moez.QKSMS.feature.main
import android.net.Uri
import androidx.recyclerview.widget.ItemTouchHelper
import com.moez.QKSMS.R
import com.moez.QKSMS.common.Navigator
......@@ -87,7 +88,9 @@ class MainViewModel @Inject constructor(
// If we have all permissions and we've never run a sync, run a sync. This will be the case
// when upgrading from 2.7.3, or if the app's data was cleared
val lastSync = Realm.getDefaultInstance().use { realm -> realm.where(SyncLog::class.java)?.max("date") ?: 0 }
val lastSync = Realm.getDefaultInstance().use { realm ->
realm.where(SyncLog::class.java)?.max("date") ?: 0
}
if (lastSync == 0 && permissionManager.isDefaultSms() && permissionManager.hasReadSms() && permissionManager.hasContacts()) {
syncMessages.execute(Unit)
}
......@@ -152,7 +155,7 @@ class MainViewModel @Inject constructor(
view.changelogMoreIntent
.autoDisposable(view.scope())
.subscribe { navigator.showChangelog() }
.subscribe { navigator.openUri(Uri.parse("https://gitlab.e.foundation/e/apps/Message/-/releases")) }
view.queryChangedIntent
.debounce(200, TimeUnit.MILLISECONDS)
......
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.feature.service
import android.app.*
import android.content.ContentValues
import android.content.Intent
import android.net.Uri
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.provider.Telephony
import androidx.core.app.NotificationCompat
import com.moez.QKSMS.injection.appComponent
import com.moez.QKSMS.repository.SyncRepositoryImpl
import foundation.e.message.IRestoreService
import org.json.JSONArray
import javax.inject.Inject
class ESmsRestoreService : Service() {
override fun onBind(intent: Intent?): IBinder? {
return RestoreServiceStub()
}
@Inject lateinit var syncMessages: SyncRepositoryImpl
val CHANNEL_ID:String = "restore_sms"
override fun onCreate() {
appComponent.inject(this)
super.onCreate()
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
CHANNEL_ID,
"Restore Sms Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(serviceChannel)
}
}
inner class RestoreServiceStub : IRestoreService.Stub() {
override fun restoreMessages(messagesJson: String?) {
createNotificationChannel()
val notificationIntent = Intent()
val pendingIntent = PendingIntent.getActivity(applicationContext,
0, notificationIntent, 0)
val notification = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
.setContentTitle("Restoring SMS")
.setContentText("")
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
val packageName:String = getPackageManager().getPackagesForUid(Binder.getCallingUid())?.get(0)?:""
if(!packageName.equals("e.foundation.sms_sync"))
return
messagesJson?.takeIf { it != null }?.let { messages ->
val array:JSONArray = JSONArray(messages);
for (i in 0 until array.length()) {
val values = ContentValues()
values.put(Telephony.Sms.ADDRESS, array.getJSONObject(i).getString("address"))
values.put(Telephony.Sms.BODY, array.getJSONObject(i).getString("body"))
values.put(Telephony.Sms.DATE, array.getJSONObject(i).getString("date"))
values.put(Telephony.Sms.TYPE, array.getJSONObject(i).getInt("type"))
values.put(Telephony.Sms.SEEN, 1)
values.put(Telephony.Sms.READ, 1)
getContentResolver().insert(Uri.parse(array.getJSONObject(i).getString("mailbox")), values)
}
// Force this refresh to fix dates
getContentResolver().delete(Uri.parse("content://sms/conversations/-1"), null, null)
}
syncMessages.syncMessages()
}
}
}
\ No newline at end of file
......@@ -31,7 +31,8 @@ import javax.inject.Inject
class AboutController : QkController<AboutView, Unit, AboutPresenter>(), AboutView {
@Inject override lateinit var presenter: AboutPresenter
@Inject
override lateinit var presenter: AboutPresenter
init {
appComponent.inject(this)
......@@ -39,6 +40,7 @@ class AboutController : QkController<AboutView, Unit, AboutPresenter>(), AboutVi
}
override fun onViewCreated() {
app_version.summary = BuildConfig.VERSION_NAME
}
override fun onAttach(view: View) {
......
......@@ -18,6 +18,7 @@
*/
package com.moez.QKSMS.feature.settings.about
import android.net.Uri
import com.moez.QKSMS.R
import com.moez.QKSMS.common.Navigator
import com.moez.QKSMS.common.base.QkPresenter
......@@ -26,7 +27,7 @@ import com.uber.autodispose.autoDisposable
import javax.inject.Inject
class AboutPresenter @Inject constructor(
private val navigator: Navigator
private val navigator: Navigator
) : QkPresenter<AboutView, Unit>(Unit) {
override fun bindIntents(view: AboutView) {
......@@ -36,13 +37,14 @@ class AboutPresenter @Inject constructor(
.autoDisposable(view.scope())
.subscribe { preference ->
when (preference.id) {
R.id.fork -> navigator.showFork()
R.id.source -> navigator.showSourceCode()
R.id.copyright -> navigator.showCopyright()
R.id.license -> navigator.showLicense()
R.id.fork -> navigator.openUri(Uri.parse("https://github.com/moezbhatti/qksms"))
R.id.source -> navigator.openUri(Uri.parse("https://gitlab.e.foundation/e/apps/message"))
R.id.copyright -> navigator.openUri(Uri.parse("https://gitlab.e.foundation/e/apps/Message/-/blob/master/AUTHORS"))
R.id.license -> navigator.openUri(Uri.parse("https://gitlab.e.foundation/e/apps/Message/-/blob/master/LICENSE"))
R.id.author -> navigator.openUri(Uri.parse("https://gitlab.e.foundation/e/apps/Message/-/blob/master/AUTHORS"))
R.id.privacy -> navigator.openUri(Uri.parse("https://e.foundation/legal-notice-privacy/"))
R.id.service_terms -> navigator.openUri(Uri.parse("https://e.foundation/legal-notice-privacy/"))
R.id.app_version -> navigator.openUri(Uri.parse("https://gitlab.e.foundation/e/apps/Message/-/releases"))
}
}
}
......
......@@ -35,6 +35,7 @@ import com.moez.QKSMS.feature.blocking.messages.BlockedMessagesController
import com.moez.QKSMS.feature.blocking.numbers.BlockedNumbersController
import com.moez.QKSMS.feature.compose.DetailedChipView
import com.moez.QKSMS.feature.conversationinfo.injection.ConversationInfoComponent
import com.moez.QKSMS.feature.service.ESmsRestoreService
import com.moez.QKSMS.feature.settings.SettingsController
import com.moez.QKSMS.feature.settings.about.AboutController
import com.moez.QKSMS.feature.settings.swipe.SwipeActionsController
......@@ -81,6 +82,8 @@ interface AppComponent {
* This can't use AndroidInjection, or else it will crash on pre-marshmallow devices
*/
fun inject(service: QkChooserTargetService)
fun inject(service: ESmsRestoreService)
fun inject(view: AvatarView)
fun inject(view: DetailedChipView)
......
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
~
~ This file is part of QKSMS.
......@@ -19,7 +18,6 @@
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground">
......@@ -33,12 +31,40 @@
android:paddingTop="8dp"
android:paddingBottom="8dp">
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/app_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:summary="@string/app_info"
app:title="@string/app_info_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/app_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/app_version_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/fork"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/about_fork_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/license"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:summary="@string/about_license"
app:title="@string/about_license_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:summary="@string/about_author"
app:title="@string/about_author_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/source"
android:layout_width="match_parent"
......@@ -46,12 +72,18 @@
app:summary="@string/about_source"
app:title="@string/about_source_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/license"
android:id="@+id/privacy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:summary="@string/about_license"
app:title="@string/about_license_title" />
app:title="@string/about_privacy_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/service_terms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/about_terms_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/copyright"
......
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--
<!--Generated by crowdin.com--><!--
~ Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
~
~ This file is part of QKSMS.
......@@ -17,8 +16,7 @@
~
~ You should have received a copy of the GNU General Public License
~ along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
--><resources>
<string name="shortcut_compose_long_label">Nuova conversazione</string>
<string name="shortcut_compose_short_label">Componi</string>
<string name="shortcut_compose_disabled_message">Scelta rapida disattivata</string>
......@@ -26,14 +24,14 @@
<string name="title_settings">Impostazioni</string>
<string name="title_notification_prefs">Notifiche</string>
<string name="title_theme">Tema</string>
<string name="title_conversations">Cerca in posta in arrivo&#8230;</string>
<string name="title_conversations">Cerca in posta in arrivo</string>
<string name="title_compose">Digita un nome o un numero</string>
<string name="setup_skip">Salta</string>
<string name="setup_next">Continua</string>
<string name="menu_call">Chiama</string>
<string name="menu_info">Dettagli</string>
<string name="menu_save">Salva nella galleria</string>
<string name="main_drawer_open_cd">Apri il pannello di navigazione</string>
<string name="main_drawer_open_cd">Apri barra di navigazione</string>
<string name="main_title_selected">%d selezionato</string>
<string name="main_menu_clear">Azzera</string>
<string name="main_menu_archive">Archivia</string>
......@@ -45,7 +43,7 @@
<string name="main_menu_read">Segna come letto</string>
<string name="main_menu_unread">Segna come non letto</string>
<string name="main_menu_block">Sposta negli indesiderati</string>
<string name="main_syncing">La sincronizzazione dei messaggi&#8230;</string>
<string name="main_syncing">La sincronizzazione dei messaggi</string>
<string name="main_sender_you">Tu: %s</string>
<string name="main_draft">Bozza: %s</string>
<string name="main_message_results_title">Risultati nei messaggi</string>
......@@ -92,7 +90,7 @@
<string name="compose_scheduled_for">Pianificato per</string>
<string name="compose_scheduled_future">L\'ora selezionata deve essere nel futuro!</string>
<string name="compose_scheduled_toast">Aggiunto ai messaggi pianificati</string>
<string name="compose_hint">Scrivi un messaggio&#8230;</string>
<string name="compose_hint">Scrivi un messaggio</string>
<string name="compose_menu_copy">Copia testo</string>
<string name="compose_menu_forward">Inoltra</string>
<string name="compose_menu_delete">Elimina</string>
......@@ -118,7 +116,7 @@
<string name="compose_contact_error">Errore nella lettura del contatto</string>
<string name="compose_sim_cd">%s selezionato, cambiare SIM</string>
<string name="compose_send_cd">Invia messaggio</string>
<string name="message_status_sending">Invio in corso&#8230;</string>
<string name="message_status_sending">Invio in corso</string>
<string name="message_status_delivered">%s consegnati</string>
<string name="message_status_failed">Impossibile inviare. Tocca per riprovare</string>
<string name="info_title">Dettagli</string>
......@@ -136,12 +134,12 @@
<string name="backup_backing_up">Backup dei messaggi</string>
<string name="backup_restoring">Ripristino da backup</string>
<string name="backup_last">Ultimo backup</string>
<string name="backup_loading">Caricamento&#8230;</string>
<string name="backup_loading">Caricamento</string>
<string name="backup_never">Mai</string>
<string name="backup_restore_title">Ripristino</string>
<string name="backup_restore_summary">Selezionare un backup</string>
<string name="backup_restore_error_backup">Backup in corso&#8230;</string>
<string name="backup_restore_error_restore">Ripristino in corso&#8230;</string>
<string name="backup_restore_error_backup">Backup in corso</string>
<string name="backup_restore_error_restore">Ripristino in corso</string>
<string name="backup_restore_confirm_title">Ripristino da backup</string>
<string name="backup_restore_confirm_message">Sei sicuro che desideri ripristinare i messaggi da questo backup?</string>
<string name="backup_restore_stop_title">Interrompi il ripristino</string>
......@@ -154,10 +152,10 @@
</plurals>
<string name="backup_disclaimer">Attualmente Backup e Restore supportano solo gli SMS. Il supporto per gli MMS ed i backup schedulati arriverà presto!</string>
<string name="backup_now">Backup adesso</string>
<string name="backup_progress_parsing">L\'analisi del backup&#8230;</string>
<string name="backup_progress_parsing">L\'analisi del backup</string>
<string name="backup_progress_running">%d/%d messaggi</string>
<string name="backup_progress_saving">Salvataggio backup&#8230;</string>
<string name="backup_progress_syncing">Sincronizzazione messaggi&#8230;</string>
<string name="backup_progress_saving">Salvataggio backup</string>
<string name="backup_progress_syncing">Sincronizzazione messaggi</string>
<string name="backup_progress_finished">Terminato!</string>
<string name="backup_notification_channel_name">Backup e ripristino</string>
<string name="scheduled_title">Messaggi pianificati</string>
......@@ -297,7 +295,7 @@
<string name="qksms_plus_respond_summary">Rispondere automaticamente ai messaggi in arrivo con una risposta preimpostata</string>
<string name="qksms_plus_more_title">Altro</string>
<string name="qksms_plus_more_summary">QKSMS è sotto sviluppo attivo, e l\'acquisto includerà tutte le caratteristiche future di QKSMS+!</string>
<string name="widget_loading">Caricamento&#8230;</string>
<string name="widget_loading">Caricamento</string>
<string name="widget_more">Mostra altre conversazioni</string>
<string name="qkreply_menu_read">Segna come letto</string>
<string name="qkreply_menu_call">Chiama</string>
......@@ -378,4 +376,5 @@
<item>LOL</item>
<item>Va bene</item>
</string-array>
</resources>
<string name="toast_qksms_plus">per utilizzarlo, devi sbloccare QKSMS+</string>
</resources>
\ No newline at end of file
......@@ -288,6 +288,12 @@
<string name="about_source_title">Source code</string>
<string name="about_license_title">License</string>
<string name="about_copyright_title">Copyright</string>
<string name="app_info_title">Message Information</string>
<string name="app_version_title">App Version</string>
<string name="app_info" translatable="false">- Message is an open source replacement to the stock messaging app on Android.</string>
<string name="about_privacy_title">Privacy policy</string>
<string name="about_terms_title">Terms of service</string>
<string name="qksms_plus_description_title">Support development, unlock everything</string>
<string name="qksms_plus_description_summary">You can save a starving developer for just %s</string>
......@@ -342,6 +348,7 @@
<string name="about_developer" translatable="false">Moez Bhatti</string>
<string name="about_source" translatable="false">https://github.com/moezbhatti/qksms</string>
<string name="about_changelog" translatable="false">https://github.com/moezbhatti/qksms/releases</string>
<string name="about_author" translatable="false">https://gitlab.e.foundation/e/apps/Message/-/blob/master/AUTHORS</string>
<string name="about_contact" translatable="false">moez@qklabs.com</string>
<string name="about_license" translatable="false">GNU General Public License v3.0</string>
<string name="about_copyright" translatable="false">© 2014–2019</string>
......@@ -444,4 +451,6 @@
<item>That\'s okay</item>
</string-array>
<string name="about_author_title">Authors</string>
</resources>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment