Merge pull request 'master' (#3) from Arne/monocles_chat:master into master

Reviewed-on: https://codeberg.org/Pirujo/monocles_chat_translate/pulls/3
This commit is contained in:
Pirujo 2022-07-06 17:18:06 +02:00
commit 2d6bd54fba
14 changed files with 141 additions and 35 deletions

View file

@ -7,7 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.1'
}
classpath 'com.google.gms:google-services:4.3.13' }
}
apply plugin: 'com.android.application'
@ -34,7 +34,7 @@ configurations {
}
dependencies {
playstoreImplementation('com.google.firebase:firebase-messaging:23.0.5') {
playstoreImplementation('com.google.firebase:firebase-messaging:23.0.6') {
exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
@ -59,7 +59,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.appcompat:appcompat:1.4.2' // 1.4.0 needs minCompileSdk 31
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.exifinterface:exifinterface:1.3.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.emoji2:emoji2:1.2.0-alpha04"
@ -106,8 +106,8 @@ android {
targetSdkVersion 30
//versionNameSuffix " beta_(2021-12-19)" // " beta_(XXXX-XX-XX)" // activate for beta versions
versionCode 114
versionName "1.5.3"
versionCode 115
versionName "1.5.4"
//resConfigs "en"
archivesBaseName += "-$versionName"

View file

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
</manifest>

View file

@ -60,7 +60,6 @@
<intent>
<action android:name="android.intent.action.GET_CONTENT" />
</intent>
<!-- OpenKeyChain -->
<package android:name="org.sufficientlysecure.keychain"/>
<intent>
@ -96,7 +95,8 @@
<service android:name=".services.XmppConnectionService" />
<receiver android:name=".services.EventReceiver">
<receiver android:name=".services.EventReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
@ -125,7 +125,8 @@
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/SplashTheme"
android:windowSoftInputMode="stateHidden">
android:windowSoftInputMode="stateHidden"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -145,7 +146,8 @@
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".ui.UriHandlerActivity"
android:label="@string/app_name">
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -186,7 +188,8 @@
android:name=".ui.StartConversationActivity"
android:configChanges="orientation|screenSize"
android:label="@string/title_activity_start_conversation"
android:launchMode="singleTop">
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
@ -206,7 +209,8 @@
<activity
android:name=".ui.ImportBackupActivity"
android:label="@string/restore_backup"
android:launchMode="singleTask">
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@ -258,7 +262,8 @@
</activity>
<activity
android:name=".ui.SettingsActivity"
android:label="@string/title_activity_settings">
android:label="@string/title_activity_settings"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
@ -276,7 +281,8 @@
<activity
android:name=".ui.ChooseAccountForProfilePictureActivity"
android:enabled="false"
android:label="@string/choose_account">
android:label="@string/choose_account"
android:exported="true">
<intent-filter android:label="@string/set_profile_picture">
<action android:name="android.intent.action.ATTACH_DATA" />
<category android:name="android.intent.category.DEFAULT" />
@ -319,7 +325,8 @@
<activity
android:name=".ui.ShareWithActivity"
android:label="@string/app_name"
android:launchMode="singleTop">
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
@ -371,7 +378,8 @@
android:name=".ui.AboutActivity"
android:label="@string/title_activity_about"
android:launchMode="singleTask"
android:parentActivityName=".ui.SettingsActivity">
android:parentActivityName=".ui.SettingsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.PREFERENCE" />
@ -384,7 +392,8 @@
android:name=".ui.MemoryManagementActivity"
android:label="@string/title_memory_management"
android:launchMode="singleTask"
android:parentActivityName=".ui.SettingsActivity">
android:parentActivityName=".ui.SettingsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.PREFERENCE" />
@ -402,7 +411,8 @@
<activity
android:name=".ui.ShortcutActivity"
android:label="@string/contact"
android:launchMode="singleTask">
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
</intent-filter>
@ -441,7 +451,8 @@
<service android:name=".services.ImportBackupService" />
<service
android:name=".services.ContactChooserTargetService"
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.service.chooser.ChooserTargetService" />
</intent-filter>

View file

@ -263,6 +263,19 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
onMessageFound.onMessageFound(result);
}
}
public void findResendAbleFailedMessage(OnMessageFound onMessageFound) {
final ArrayList<Message> results = new ArrayList<>();
synchronized (this.messages) {
for (final Message message : this.messages) {
if (message.getStatus() == Message.STATUS_SEND_FAILED && !message.isFileOrImage()) {
results.add(message);
}
}
}
for (final Message result : results) {
onMessageFound.onMessageFound(result);
}
}
public void findUnreadMessagesAndCalls(OnMessageFound onMessageFound) {
final ArrayList<Message> results = new ArrayList<>();
@ -1341,7 +1354,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
&& !contact.isOwnServer()
&& !contact.showInContactList()
&& !contact.isSelf()
&& !Config.QUICKSY_DOMAIN.equals(contact.getJid().toEscapedString())
&& !(Config.QUICKSY_DOMAIN.equals(contact.getJid().toEscapedString()) && (contact.getJid().isDomainJid()))
&& sentMessagesCount() == 0;
}

View file

@ -124,6 +124,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
private String errorMessage = null;
private Set<ReadByMarker> readByMarkers = new CopyOnWriteArraySet<>();
private String retractId = null;
protected int resendCount = 0;
private Boolean isGeoUri = null;
private Boolean isXmppUri = null;
@ -1127,4 +1128,11 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
message.setType(isFile ? Message.TYPE_PRIVATE_FILE : Message.TYPE_PRIVATE);
return true;
}
public int getResendCount(){
return resendCount;
}
public int increaseResendCount(){
return ++resendCount;
}
}

View file

@ -1458,7 +1458,7 @@ public class NotificationService {
private PendingIntent createShowLocationIntent(final Message message) {
Iterable<Intent> intents = GeoHelper.createGeoIntentsFromMessage(mXmppConnectionService, message);
for (Intent intent : intents) {
for (final Intent intent : intents) {
if (intent.resolveActivity(mXmppConnectionService.getPackageManager()) != null) {
return PendingIntent.getActivity(mXmppConnectionService, generateRequestCode(message.getConversation(), 18), intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@ -1657,6 +1657,7 @@ public class NotificationService {
mBuilder.setWhen(0);
mBuilder.setPriority(Notification.PRIORITY_MIN);
mBuilder.setSmallIcon(connected > 0 ? R.drawable.ic_link_white_24dp : R.drawable.ic_link_off_white_24dp);
mBuilder.setLocalOnly(true);
if (Compatibility.runsTwentySix()) {
mBuilder.setChannelId(FOREGROUND_CHANNEL_ID);
}

View file

@ -15,6 +15,8 @@ import static eu.siacs.conversations.ui.SettingsActivity.SHOW_OWN_ACCOUNTS;
import static eu.siacs.conversations.ui.SettingsActivity.USE_INNER_STORAGE;
import static eu.siacs.conversations.utils.RichPreview.RICH_LINK_METADATA;
import static eu.siacs.conversations.utils.StorageHelper.getAppMediaDirectory;
import android.content.res.Resources;
import android.os.Handler;
import android.Manifest;
import androidx.annotation.RequiresApi;
@ -231,6 +233,7 @@ public class XmppConnectionService extends Service {
private final SerialSingleThreadExecutor mNotificationExecutor = new SerialSingleThreadExecutor("NotificationExecutor");
public final SerialSingleThreadExecutor mWebPreviewExecutor = new SerialSingleThreadExecutor("WebPreview");
public final SerialSingleThreadExecutor mNotificationChannelExecutor = new SerialSingleThreadExecutor("updateNotificationChannels");
public final SerialSingleThreadExecutor mMessageResendTaskExecuter = new SerialSingleThreadExecutor("MessageResender");
private final ReplacingTaskManager mRosterSyncTaskManager = new ReplacingTaskManager();
private final IBinder mBinder = new XmppConnectionBinder();
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
@ -881,6 +884,7 @@ public class XmppConnectionService extends Service {
for (Conversation conversation : conversations) {
if (conversation.getAccount() == account && !account.pendingConferenceJoins.contains(conversation)) {
resendFailedFileMessages(conversation);
resendFailedMessages(conversation);
}
}
final boolean lowTimeout = isInLowPingTimeoutMode(account);
@ -911,7 +915,9 @@ public class XmppConnectionService extends Service {
}
}
}
public int maxResendTime(){
return Integer.parseInt(getPreferences().getString(SettingsActivity.MAX_RESEND_TIME, getResources().getString(R.string.max_resend_time)));
}
private void deleteWebpreviewCache() {
new Thread(() -> {
try {
@ -1993,7 +1999,18 @@ public class XmppConnectionService extends Service {
mDatabaseWriterExecutor.execute((runnable));
}
private void resendFailedMessages(final Conversation conversation) {
final Runnable runnable = () -> {
conversation.findResendAbleFailedMessage(message -> {
if (message.increaseResendCount() < maxResendTime()) {
Log.d(Config.LOGTAG, "Resend failed message " + message.getErrorMessage() + " at times " + message.getResendCount() + " bytes for " + conversation.getJid());
// because it'll use a custom delay here, only the last time will delay the message.
resendFailedMessages(message);
}
});
};
mMessageResendTaskExecuter.execute((runnable));
}
private void resendFailedFileMessages(final Conversation conversation) {
final Runnable runnable = () -> {
conversation.findFailedMessagesWithFiles(message -> {
@ -4563,8 +4580,25 @@ public class XmppConnectionService extends Service {
updateConversationUi();
if (oldStatus != status && status == Message.STATUS_SEND_FAILED) {
mNotificationService.pushFailedDelivery(message);
// resend it
mMessageResendTaskExecuter.execute(() -> {
try {
if (message.increaseResendCount() <= maxResendTime() / 2) {
Thread.sleep(resendDelay());
resendFailedMessages(message);
}
}
catch (Exception ignore){
// if system halt, give it up
Log.w(Config.LOGTAG,"System Halt, so the message resend give up");
}
});
}
}
private long resendDelay() {
return Long.parseLong(getPreferences().getString(SettingsActivity.RESEND_DELAY, getResources().getString(R.string.resend_delay)));
}
public SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

View file

@ -93,6 +93,8 @@ public class SettingsActivity extends XmppActivity implements
public static final String MIN_ANDROID_SDK21_SHOWN = "min_android_sdk21_shown";
public static final String INDIVIDUAL_NOTIFICATION_PREFIX = "individual_notification_set_";
public static final String PAUSE_VOICE = "pause_voice_on_move_from_ear";
public static final String MAX_RESEND_TIME = "max_resend_time";
public static final String RESEND_DELAY = "resend_delay";
public static final int REQUEST_CREATE_BACKUP = 0xbf8701;
public static final int REQUEST_IMPORT_SETTINGS = 0xbf8702;

View file

@ -49,6 +49,7 @@ import android.widget.TextView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.graphics.drawable.DrawableCompat;
import com.google.common.base.Strings;
@ -277,7 +278,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
break;
case Message.STATUS_SEND_FAILED:
DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
if (isResendable && file.exists()) {
if (isResendable && file.exists() || message.getResendCount() < activity.xmppConnectionService.maxResendTime()) {
info = getContext().getString(R.string.send_failed_resend);
} else {
final String errorMessage = message.getErrorMessage();
@ -1195,6 +1196,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.status_message.setText(DateUtils.formatDateTime(activity, message.getTimeSent(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
}
viewHolder.message_box.setBackgroundResource(darkBackground ? R.drawable.date_bubble_dark : R.drawable.date_bubble);
int date_bubble_color = ColorUtils.setAlphaComponent(StyledAttributes.getColor(activity, R.attr.colorAccent), 80); //set alpha to date_bubble
activity.setBubbleColor(viewHolder.message_box, (date_bubble_color), -1); // themed color
return view;
} else if (type == RTP_SESSION) {
final boolean isDarkTheme = activity.isDarkTheme();
@ -1218,6 +1221,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.indicatorReceived.setImageResource(RtpSessionStatus.getDrawable(received, rtpSessionStatus.successful, isDarkTheme));
viewHolder.indicatorReceived.setAlpha(isDarkTheme ? 0.7f : 0.57f);
viewHolder.message_box.setBackgroundResource(darkBackground ? R.drawable.date_bubble_dark : R.drawable.date_bubble);
int date_bubble_color = ColorUtils.setAlphaComponent(StyledAttributes.getColor(activity, R.attr.colorAccent), 80); //set alpha to date bubble
activity.setBubbleColor(viewHolder.message_box, (date_bubble_color), -1); //themed color
return view;
} else if (type == STATUS) {
if ("LOAD_MORE".equals(message.getBody())) {

View file

@ -48,17 +48,28 @@ public class EditMessageActionModeCallback implements ActionMode.Callback {
public EditMessageActionModeCallback(EditMessage editMessage) {
this.editMessage = editMessage;
this.clipboardManager = (ClipboardManager) editMessage.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
this.clipboardManager =
(ClipboardManager)
editMessage.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
final MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.edit_message_actions, menu);
final MenuItem pasteAsQuote = menu.findItem(R.id.paste_as_quote);
final ClipData primaryClip = clipboardManager.getPrimaryClip();
if (primaryClip != null && primaryClip.getItemCount() >= 0) {
pasteAsQuote.setVisible(primaryClip.getDescription().getMimeType(0).startsWith("text/") && !TextUtils.isEmpty(primaryClip.getItemAt(0).getText()));
if (primaryClip != null && primaryClip.getItemCount() > 0) {
final String mimeType;
try {
mimeType = primaryClip.getDescription().getMimeType(0);
} catch (final Exception e) {
pasteAsQuote.setVisible(false);
return true;
}
pasteAsQuote.setVisible(
mimeType.startsWith("text/")
&& !TextUtils.isEmpty(primaryClip.getItemAt(0).getText()));
} else {
pasteAsQuote.setVisible(false);
}
@ -71,10 +82,10 @@ public class EditMessageActionModeCallback implements ActionMode.Callback {
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
if (item.getItemId() == R.id.paste_as_quote) {
final ClipData primaryClip = clipboardManager.getPrimaryClip();
if (primaryClip != null && primaryClip.getItemCount() >= 1) {
if (primaryClip != null && primaryClip.getItemCount() > 0) {
editMessage.insertAsQuote(primaryClip.getItemAt(0).getText().toString());
return true;
}
@ -83,7 +94,5 @@ public class EditMessageActionModeCallback implements ActionMode.Callback {
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
public void onDestroyActionMode(ActionMode mode) {}
}

View file

@ -1201,4 +1201,5 @@
<string name="participants">Participantes</string>
<string name="download_failed_invalid_file">Descarga fallida: Fichero no válido</string>
<string name="orbot_not_found">Orbot no encontrado</string>
<string name="account_status_temporary_auth_failure">Fallo temporal de autentificación</string>
</resources>

View file

@ -36,7 +36,7 @@
<bool name="presence_colored_names">false</bool>
<bool name="use_max_brightness">false</bool>
<bool name="auto_rotate">false</bool>
<bool name="send_crashreport">true</bool>
<bool name="send_crashreport">false</bool>
<bool name="use_invidious">false</bool>
<bool name="use_inner_storage">true</bool>
<string name="invidious_host">monocles.live</string>
@ -93,6 +93,8 @@
<integer name="low_video_res">360</integer>
<integer name="mid_video_res">720</integer>
<integer name="high_video_res">1080</integer>
<string name="max_resend_time">4</string>
<string name="resend_delay">500</string>
<bool name="easy_downloader">false</bool>
<bool name="hide_memory_warning">false</bool>
<bool name="pause_voice">false</bool>

View file

@ -1204,4 +1204,8 @@
<string name="download_failed_invalid_file">Download failed: Invalid file</string>
<string name="orbot_not_found">Orbot not found</string>
<string name="account_status_temporary_auth_failure">Temporary authentication failure</string>
<string name="pref_max_resend_time_title">Max Time of resend failed Message</string>
<string name="pref_max_resend_time_summary">When plain message send fail, the max time to resend it. when resend count bigger than half max time, message will be delay for traffic reason.</string>
<string name="pref_resend_delay_title">Resend Delay (MillsSecond)</string>
<string name="pref_resend_delay_summary">Resend Delay (MillsSecond), the time for delay resend.</string>
</resources>

View file

@ -474,6 +474,20 @@
android:targetClass="com.huawei.systemmanager.optimize.process.ProtectActivity"
android:targetPackage="com.huawei.systemmanager" />
</PreferenceScreen>
<EditTextPreference
android:defaultValue="@string/max_resend_time"
android:key="max_resend_time"
android:summary="@string/pref_max_resend_time_summary"
android:title="@string/pref_max_resend_time_title"
android:inputType="number"
/>
<EditTextPreference
android:defaultValue="@string/resend_delay"
android:key="resend_delay"
android:summary="@string/pref_resend_delay_summary"
android:title="@string/pref_resend_delay_title"
android:inputType="number"
/>
<CheckBoxPreference
android:defaultValue="@bool/enable_multi_accounts"
android:key="enable_multi_accounts"