mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-21 15:05:19 +00:00
Merge branch 'dev' into disappear-2
This commit is contained in:
commit
892e4b75ec
45
.github/ISSUE_TEMPLATE.md
vendored
45
.github/ISSUE_TEMPLATE.md
vendored
@ -1,45 +0,0 @@
|
||||
<!-- This is a bug report template. By following the instructions below and filling out the sections with your information, you will help the developers get all the necessary data to fix your issue.
|
||||
You can also preview your report before submitting it. You may remove sections that aren't relevant to your particular case.
|
||||
|
||||
Before we begin, please note that this tracker is only for issues. It is not for questions, comments, or feature requests.
|
||||
|
||||
If you are looking for support, please file an issue or email team@oxen.io.
|
||||
|
||||
Let's begin with a checklist: Replace the empty checkboxes [ ] below with checked ones [x] accordingly. -->
|
||||
|
||||
- [ ] I have read and agree to adhere to the [Code of Conduct](https://github.com/oxen-io/session-android/blob/master/CODE_OF_CONDUCT.md).
|
||||
- [ ] I have searched open and closed issues for duplicates
|
||||
- [ ] I am submitting a bug report for existing functionality that does not work as intended
|
||||
- [ ] This isn't a feature request or a discussion topic
|
||||
|
||||
----------------------------------------
|
||||
|
||||
### Bug description
|
||||
Describe here the issue that you are experiencing.
|
||||
|
||||
### Steps to reproduce
|
||||
- using hyphens as bullet points
|
||||
- list the steps
|
||||
- that reproduce the bug
|
||||
|
||||
**Actual result:**
|
||||
|
||||
Describe here what happens after you run the steps above (i.e. the buggy behaviour)
|
||||
|
||||
**Expected result:**
|
||||
|
||||
Describe here what should happen after you run the steps above (i.e. what would be the correct behaviour)
|
||||
|
||||
### Screenshots
|
||||
<!-- you can drag and drop images below -->
|
||||
|
||||
### Device info
|
||||
<!-- replace the examples with your info -->
|
||||
|
||||
**Device:** Manufacturer Model XVI
|
||||
|
||||
**Android version:** 0.0.0
|
||||
|
||||
**Session version:** 0.0.0
|
||||
|
||||
### Link to debug log
|
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,34 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Code of conduct**
|
||||
|
||||
- [ ] I have read and agree to adhere to the [Code of Conduct](https://github.com/oxen-io/session-android/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To reproduce**
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
**Screenshots or logs**
|
||||
|
||||
If applicable, add screenshots or logs to help explain your problem.
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
|
||||
- Device: [e.g. Samsung Galaxy S8]
|
||||
- OS: [e.g. Android Pie]
|
||||
- Version of Session or latest commit hash
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
74
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
74
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
name: 🐞 Bug Report
|
||||
description: Create a report to help us improve
|
||||
title: "[BUG] <title>"
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of conduct
|
||||
description: I have read and agree to adhere to the [Code of Conduct](https://github.com/oxen-io/session-android/blob/master/CODE_OF_CONDUCT.md).
|
||||
options:
|
||||
- label: I have read and agree to adhere to the [Code of Conduct](https://github.com/oxen-io/session-android/blob/master/CODE_OF_CONDUCT.md)
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Self-training on how to write a bug report
|
||||
description: High quality bug reports can help the team save time and improve the chance of getting your issue fixed. Please read [how to write a bug report](https://www.browserstack.com/guide/how-to-write-a-bug-report) before submitting your issue.
|
||||
options:
|
||||
- label: I have learned [how to write a bug report](https://www.browserstack.com/guide/how-to-write-a-bug-report)
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: A concise description of what you're experiencing.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. In this environment...
|
||||
2. With this config...
|
||||
3. Run '...'
|
||||
4. See error...
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: Android Version
|
||||
description: What version of Android are you running?
|
||||
placeholder: ex. Android 11
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: Session Version
|
||||
description: What version of Session are you running? (This can be found at the bottom of the app settings)
|
||||
placeholder: ex. 1.17.0 (3425)
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Add any other context about the problem here.
|
||||
|
||||
Tip: You can attach screenshots or log files to help explain your problem by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: false
|
26
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
26
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
name: 🚀 Feature request
|
||||
description: Suggest an idea for Session
|
||||
title: '[Feature] <title>'
|
||||
labels: [feature-request]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing request for feature?
|
||||
description: Please search to see if an issue already exists for the feature you are requesting.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What feature would you like?
|
||||
description: |
|
||||
A clear and concise description of the feature you would like added to Session
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Add any other context or screenshots about the feature request here
|
||||
validations:
|
||||
required: false
|
@ -122,6 +122,7 @@ android {
|
||||
minifyEnabled false
|
||||
}
|
||||
debug {
|
||||
isDefault true
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
@ -129,6 +130,7 @@ android {
|
||||
flavorDimensions "distribution"
|
||||
productFlavors {
|
||||
play {
|
||||
isDefault true
|
||||
dimension "distribution"
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
ext.websiteUpdateUrl = "null"
|
||||
@ -282,7 +284,7 @@ dependencies {
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxJsonVersion"
|
||||
implementation "com.github.oxen-io.session-android-curve-25519:curve25519-java:$curve25519Version"
|
||||
implementation project(":liblazysodium")
|
||||
implementation "net.java.dev.jna:jna:5.8.0@aar"
|
||||
implementation "net.java.dev.jna:jna:5.12.1@aar"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonDatabindVersion"
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
|
||||
@ -335,15 +337,15 @@ dependencies {
|
||||
testImplementation 'org.robolectric:robolectric:4.4'
|
||||
testImplementation 'org.robolectric:shadows-multidex:4.4'
|
||||
|
||||
implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.1'
|
||||
implementation 'androidx.compose.ui:ui:1.4.3'
|
||||
implementation 'androidx.compose.ui:ui-tooling:1.4.3'
|
||||
implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.31.5-beta"
|
||||
implementation "com.google.accompanist:accompanist-pager-indicators:0.31.5-beta"
|
||||
implementation "androidx.compose.runtime:runtime-livedata:1.4.3"
|
||||
implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.5'
|
||||
implementation 'androidx.compose.ui:ui:1.5.2'
|
||||
implementation 'androidx.compose.ui:ui-tooling:1.5.2'
|
||||
implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.33.1-alpha"
|
||||
implementation "com.google.accompanist:accompanist-pager-indicators:0.33.1-alpha"
|
||||
implementation "androidx.compose.runtime:runtime-livedata:1.5.2"
|
||||
|
||||
implementation 'androidx.compose.foundation:foundation-layout:1.4.3'
|
||||
implementation 'androidx.compose.material:material:1.4.3'
|
||||
implementation 'androidx.compose.foundation:foundation-layout:1.5.2'
|
||||
implementation 'androidx.compose.material:material:1.5.2'
|
||||
}
|
||||
|
||||
static def getLastCommitTimestamp() {
|
||||
|
@ -158,6 +158,7 @@ class HomeActivityTests {
|
||||
|
||||
val dialogPromptText = InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.dialog_open_url_explanation, amazonPuny)
|
||||
|
||||
onView(isRoot()).perform(waitFor(1000)) // no other way for this to work apparently
|
||||
onView(withText(dialogPromptText)).check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
|
@ -238,10 +238,6 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Session.DayNight">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="org.thoughtcrime.securesms.longmessage.LongMessageActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Session.DayNight" />
|
||||
<activity
|
||||
android:name="org.thoughtcrime.securesms.DatabaseUpgradeActivity"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||
|
@ -47,7 +47,6 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.util.Pair;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
@ -534,11 +533,15 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
|
||||
viewModel.setCursor(this, data.first, leftIsRecent);
|
||||
|
||||
int item = restartItem >= 0 ? restartItem : data.second;
|
||||
mediaPager.setCurrentItem(item);
|
||||
if (restartItem >= 0 || data.second >= 0) {
|
||||
int item = restartItem >= 0 ? restartItem : data.second;
|
||||
mediaPager.setCurrentItem(item);
|
||||
|
||||
if (item == 0) {
|
||||
viewPagerListener.onPageSelected(0);
|
||||
if (item == 0) {
|
||||
viewPagerListener.onPageSelected(0);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "one of restartItem "+restartItem+" and data.second "+data.second+" would cause OOB exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1599,7 +1599,12 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
return Pair(recipient.address, sentTimestamp)
|
||||
}
|
||||
|
||||
private fun sendAttachments(attachments: List<Attachment>, body: String?, quotedMessage: MessageRecord? = null, linkPreview: LinkPreview? = null): Pair<Address, Long>? {
|
||||
private fun sendAttachments(
|
||||
attachments: List<Attachment>,
|
||||
body: String?,
|
||||
quotedMessage: MessageRecord? = binding?.inputBar?.quote,
|
||||
linkPreview: LinkPreview? = null
|
||||
): Pair<Address, Long>? {
|
||||
val recipient = viewModel.recipient ?: return null
|
||||
val sentTimestamp = SnodeAPI.nowWithOffset
|
||||
processMessageRequestApproval()
|
||||
|
@ -7,7 +7,6 @@ import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.children
|
||||
|
@ -8,6 +8,7 @@ import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableString
|
||||
import android.widget.Toast
|
||||
@ -300,7 +301,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
||||
EventBus.getDefault().register(this@HomeActivity)
|
||||
if (intent.hasExtra(FROM_ONBOARDING)
|
||||
&& intent.getBooleanExtra(FROM_ONBOARDING, false)) {
|
||||
if ((getSystemService(NOTIFICATION_SERVICE) as NotificationManager).areNotificationsEnabled().not()) {
|
||||
if (Build.VERSION.SDK_INT >= 33 &&
|
||||
(getSystemService(NOTIFICATION_SERVICE) as NotificationManager).areNotificationsEnabled().not()) {
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.POST_NOTIFICATIONS)
|
||||
.execute()
|
||||
|
@ -1,28 +0,0 @@
|
||||
package org.thoughtcrime.securesms.longmessage;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
|
||||
/**
|
||||
* A wrapper around a {@link MessageRecord} and its extra text attachment expanded into a string
|
||||
* held in memory.
|
||||
*/
|
||||
class LongMessage {
|
||||
|
||||
private final MessageRecord messageRecord;
|
||||
private final String fullBody;
|
||||
|
||||
LongMessage(MessageRecord messageRecord, String fullBody) {
|
||||
this.messageRecord = messageRecord;
|
||||
this.fullBody = fullBody;
|
||||
}
|
||||
|
||||
MessageRecord getMessageRecord() {
|
||||
return messageRecord;
|
||||
}
|
||||
|
||||
String getFullBody() {
|
||||
return !TextUtils.isEmpty(fullBody) ? fullBody : messageRecord.getBody();
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package org.thoughtcrime.securesms.longmessage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spannable;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import org.session.libsession.utilities.Address;
|
||||
import org.session.libsession.utilities.Util;
|
||||
import org.session.libsession.utilities.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentView;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class LongMessageActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
private static final String KEY_ADDRESS = "address";
|
||||
private static final String KEY_MESSAGE_ID = "message_id";
|
||||
private static final String KEY_IS_MMS = "is_mms";
|
||||
|
||||
private static final int MAX_DISPLAY_LENGTH = 64 * 1024;
|
||||
|
||||
private TextView textBody;
|
||||
|
||||
private LongMessageViewModel viewModel;
|
||||
|
||||
public static Intent getIntent(@NonNull Context context, @NonNull Address conversationAddress, long messageId, boolean isMms) {
|
||||
Intent intent = new Intent(context, LongMessageActivity.class);
|
||||
intent.putExtra(KEY_ADDRESS, conversationAddress.serialize());
|
||||
intent.putExtra(KEY_MESSAGE_ID, messageId);
|
||||
intent.putExtra(KEY_IS_MMS, isMms);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||
super.onCreate(savedInstanceState, ready);
|
||||
setContentView(R.layout.longmessage_activity);
|
||||
textBody = findViewById(R.id.longmessage_text);
|
||||
|
||||
initViewModel(getIntent().getLongExtra(KEY_MESSAGE_ID, -1), getIntent().getBooleanExtra(KEY_IS_MMS, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initViewModel(long messageId, boolean isMms) {
|
||||
viewModel = new ViewModelProvider(this, new LongMessageViewModel.Factory(getApplication(), new LongMessageRepository(this), messageId, isMms))
|
||||
.get(LongMessageViewModel.class);
|
||||
|
||||
viewModel.getMessage().observe(this, message -> {
|
||||
if (message == null) return;
|
||||
|
||||
if (!message.isPresent()) {
|
||||
Toast.makeText(this, R.string.LongMessageActivity_unable_to_find_message, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.get().getMessageRecord().isOutgoing()) {
|
||||
getSupportActionBar().setTitle(getString(R.string.LongMessageActivity_your_message));
|
||||
} else {
|
||||
Recipient recipient = message.get().getMessageRecord().getRecipient();
|
||||
String name = Util.getFirstNonEmpty(recipient.getName(), recipient.getProfileName(), recipient.getAddress().serialize());
|
||||
getSupportActionBar().setTitle(getString(R.string.LongMessageActivity_message_from_s, name));
|
||||
}
|
||||
Spannable bodySpans = VisibleMessageContentView.Companion.getBodySpans(this, message.get().getMessageRecord(), null);
|
||||
textBody.setText(bodySpans);
|
||||
textBody.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package org.thoughtcrime.securesms.longmessage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import org.session.libsession.utilities.Util;
|
||||
import org.session.libsession.utilities.concurrent.SignalExecutors;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.session.libsignal.utilities.guava.Optional;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.mms.TextSlide;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
class LongMessageRepository {
|
||||
|
||||
private final static String TAG = LongMessageRepository.class.getSimpleName();
|
||||
|
||||
private final MmsDatabase mmsDatabase;
|
||||
private final SmsDatabase smsDatabase;
|
||||
|
||||
LongMessageRepository(@NonNull Context context) {
|
||||
this.mmsDatabase = DatabaseComponent.get(context).mmsDatabase();
|
||||
this.smsDatabase = DatabaseComponent.get(context).smsDatabase();
|
||||
}
|
||||
|
||||
void getMessage(@NonNull Context context, long messageId, boolean isMms, @NonNull Callback<Optional<LongMessage>> callback) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
if (isMms) {
|
||||
callback.onComplete(getMmsLongMessage(context, mmsDatabase, messageId));
|
||||
} else {
|
||||
callback.onComplete(getSmsLongMessage(smsDatabase, messageId));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private Optional<LongMessage> getMmsLongMessage(@NonNull Context context, @NonNull MmsDatabase mmsDatabase, long messageId) {
|
||||
Optional<MmsMessageRecord> record = getMmsMessage(mmsDatabase, messageId);
|
||||
|
||||
if (record.isPresent()) {
|
||||
TextSlide textSlide = record.get().getSlideDeck().getTextSlide();
|
||||
|
||||
if (textSlide != null && textSlide.getUri() != null) {
|
||||
return Optional.of(new LongMessage(record.get(), readFullBody(context, textSlide.getUri())));
|
||||
} else {
|
||||
return Optional.of(new LongMessage(record.get(), ""));
|
||||
}
|
||||
} else {
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private Optional<LongMessage> getSmsLongMessage(@NonNull SmsDatabase smsDatabase, long messageId) {
|
||||
Optional<MessageRecord> record = getSmsMessage(smsDatabase, messageId);
|
||||
|
||||
if (record.isPresent()) {
|
||||
return Optional.of(new LongMessage(record.get(), ""));
|
||||
} else {
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@WorkerThread
|
||||
private Optional<MmsMessageRecord> getMmsMessage(@NonNull MmsDatabase mmsDatabase, long messageId) {
|
||||
try (Cursor cursor = mmsDatabase.getMessage(messageId)) {
|
||||
return Optional.fromNullable((MmsMessageRecord) mmsDatabase.readerFor(cursor).getNext());
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private Optional<MessageRecord> getSmsMessage(@NonNull SmsDatabase smsDatabase, long messageId) {
|
||||
try (Cursor cursor = smsDatabase.getMessageCursor(messageId)) {
|
||||
return Optional.fromNullable(smsDatabase.readerFor(cursor).getNext());
|
||||
}
|
||||
}
|
||||
|
||||
private String readFullBody(@NonNull Context context, @NonNull Uri uri) {
|
||||
try (InputStream stream = PartAuthority.getAttachmentStream(context, uri)) {
|
||||
return Util.readFullyAsString(stream);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to read full text body.", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback<T> {
|
||||
void onComplete(T result);
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package org.thoughtcrime.securesms.longmessage;
|
||||
|
||||
import android.app.Application;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseContentProviders;
|
||||
import org.session.libsignal.utilities.guava.Optional;
|
||||
|
||||
class LongMessageViewModel extends ViewModel {
|
||||
|
||||
private final Application application;
|
||||
private final LongMessageRepository repository;
|
||||
private final long messageId;
|
||||
private final boolean isMms;
|
||||
|
||||
private final MutableLiveData<Optional<LongMessage>> message;
|
||||
private final MessageObserver messageObserver;
|
||||
|
||||
private LongMessageViewModel(@NonNull Application application, @NonNull LongMessageRepository repository, long messageId, boolean isMms) {
|
||||
this.application = application;
|
||||
this.repository = repository;
|
||||
this.messageId = messageId;
|
||||
this.isMms = isMms;
|
||||
this.message = new MutableLiveData<>();
|
||||
this.messageObserver = new MessageObserver(new Handler());
|
||||
|
||||
repository.getMessage(application, messageId, isMms, longMessage -> {
|
||||
if (longMessage.isPresent()) {
|
||||
Uri uri = DatabaseContentProviders.Conversation.getUriForThread(longMessage.get().getMessageRecord().getThreadId());
|
||||
application.getContentResolver().registerContentObserver(uri, true, messageObserver);
|
||||
}
|
||||
|
||||
message.postValue(longMessage);
|
||||
});
|
||||
}
|
||||
|
||||
LiveData<Optional<LongMessage>> getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
application.getContentResolver().unregisterContentObserver(messageObserver);
|
||||
}
|
||||
|
||||
private class MessageObserver extends ContentObserver {
|
||||
MessageObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
repository.getMessage(application, messageId, isMms, message::postValue);
|
||||
}
|
||||
}
|
||||
|
||||
static class Factory extends ViewModelProvider.NewInstanceFactory {
|
||||
|
||||
private final Application context;
|
||||
private final LongMessageRepository repository;
|
||||
private final long messageId;
|
||||
private final boolean isMms;
|
||||
|
||||
public Factory(@NonNull Application application, @NonNull LongMessageRepository repository, long messageId, boolean isMms) {
|
||||
this.context = application;
|
||||
this.repository = repository;
|
||||
this.messageId = messageId;
|
||||
this.isMms = isMms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull<T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||
return modelClass.cast(new LongMessageViewModel(context, repository, messageId, isMms));
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import com.goterl.lazysodium.utils.Key
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonBuilder
|
||||
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||
@ -28,6 +29,7 @@ private const val TAG = "PushHandler"
|
||||
|
||||
class PushReceiver @Inject constructor(@ApplicationContext val context: Context) {
|
||||
private val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
fun onPush(dataMap: Map<String, String>?) {
|
||||
onPush(dataMap?.asByteArray())
|
||||
@ -89,7 +91,7 @@ class PushReceiver @Inject constructor(@ApplicationContext val context: Context)
|
||||
?: error("Failed to decode bencoded list from payload")
|
||||
|
||||
val metadataJson = (expectedList[0] as? BencodeString)?.value ?: error("no metadata")
|
||||
val metadata: PushNotificationMetadata = Json.decodeFromString(String(metadataJson))
|
||||
val metadata: PushNotificationMetadata = json.decodeFromString(String(metadataJson))
|
||||
|
||||
return (expectedList.getOrNull(1) as? BencodeString)?.value.also {
|
||||
// null content is valid only if we got a "data_too_long" flag
|
||||
|
@ -110,7 +110,7 @@
|
||||
android:layout_gravity="center"
|
||||
android:textColor="?message_sent_text_color"
|
||||
android:background="?colorAccent"
|
||||
android:textSize="9sp"
|
||||
android:textSize="11sp"
|
||||
android:paddingVertical="4dp"
|
||||
android:paddingHorizontal="64dp"
|
||||
android:gravity="center"
|
||||
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:textSize="@dimen/text_size"
|
||||
android:focusable="true"
|
||||
android:textColorLink="?android:textColorPrimary"
|
||||
android:id="@+id/longmessage_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -36,15 +36,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/view_voice_message"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/voiceMessageView"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="36dp"/>
|
||||
|
||||
<include layout="@layout/view_open_group_invitation"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@ -75,6 +66,15 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/view_voice_message"
|
||||
app:layout_constraintTop_toBottomOf="@id/quoteView"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/voiceMessageView"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="36dp"/>
|
||||
|
||||
<include layout="@layout/view_link_preview"
|
||||
app:layout_constraintTop_toBottomOf="@+id/quoteView"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
12
build.gradle
12
build.gradle
@ -12,11 +12,9 @@ buildscript {
|
||||
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:$gradlePluginVersion"
|
||||
classpath files('libs/gradle-witness.jar')
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
|
||||
classpath "com.google.gms:google-services:$googleServicesVersion"
|
||||
classpath files('libs/gradle-witness.jar')
|
||||
classpath "com.squareup:javapoet:1.13.0"
|
||||
classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerVersion"
|
||||
if (project.hasProperty('huawei')) classpath 'com.huawei.agconnect:agcp:1.9.1.300'
|
||||
@ -55,12 +53,6 @@ allprojects {
|
||||
includeGroupByRegex "org\\.signal.*"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://repo1.maven.org/maven2/com/goterl/lazysodium-android"
|
||||
content {
|
||||
includeGroupByRegex "com\\.goterl.*"
|
||||
}
|
||||
}
|
||||
jcenter()
|
||||
maven { url "https://jitpack.io" }
|
||||
if (project.hasProperty('huawei')) maven {
|
||||
@ -76,7 +68,7 @@ allprojects {
|
||||
|
||||
project.ext {
|
||||
androidMinimumSdkVersion = 23
|
||||
androidTargetSdkVersion = 33
|
||||
androidCompileSdkVersion = 33
|
||||
androidTargetSdkVersion = 34
|
||||
androidCompileSdkVersion = 34
|
||||
}
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
configurations.maybeCreate("default")
|
||||
artifacts.add("default", file('lazysodium.aar'))
|
||||
artifacts.add("default", file('session-lazysodium-android.aar'))
|
Binary file not shown.
BIN
liblazysodium/session-lazysodium-android.aar
Normal file
BIN
liblazysodium/session-lazysodium-android.aar
Normal file
Binary file not shown.
@ -42,6 +42,6 @@ dependencies {
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
implementation(project(":libsignal"))
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
}
|
@ -21,7 +21,7 @@ dependencies {
|
||||
implementation project(":libsignal")
|
||||
implementation project(":libsession-util")
|
||||
implementation project(":liblazysodium")
|
||||
implementation "net.java.dev.jna:jna:5.8.0@aar"
|
||||
implementation "net.java.dev.jna:jna:5.12.1@aar"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
|
||||
implementation "androidx.core:core-ktx:$coreVersion"
|
||||
implementation "androidx.appcompat:appcompat:$appcompatVersion"
|
||||
@ -29,8 +29,8 @@ dependencies {
|
||||
implementation "com.google.android.material:material:$materialVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "com.google.dagger:hilt-android:$daggerVersion"
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
implementation "com.github.bumptech.glide:glide:$glideVersion"
|
||||
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
implementation 'com.annimon:stream:1.1.8'
|
||||
|
@ -89,19 +89,21 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
|
||||
}
|
||||
|
||||
val threadRecipient = storage.getRecipientForThread(threadID)
|
||||
val sender = if (messageDataProvider.isMmsOutgoing(databaseMessageID)) {
|
||||
val selfSend = messageDataProvider.isMmsOutgoing(databaseMessageID)
|
||||
val sender = if (selfSend) {
|
||||
storage.getUserPublicKey()
|
||||
} else {
|
||||
messageDataProvider.getIndividualRecipientForMms(databaseMessageID)?.address?.serialize()
|
||||
}
|
||||
val contact = sender?.let { storage.getContactWithSessionID(it) }
|
||||
if (threadRecipient == null || sender == null || contact == null) {
|
||||
if (threadRecipient == null || sender == null || (contact == null && !selfSend)) {
|
||||
handleFailure(Error.NoSender, null)
|
||||
return
|
||||
}
|
||||
if (!threadRecipient.isGroupRecipient && (!contact.isTrusted && storage.getUserPublicKey() != sender)) {
|
||||
if (!threadRecipient.isGroupRecipient || (contact?.isTrusted != true && storage.getUserPublicKey() != sender)) {
|
||||
// if we aren't receiving a group message, a message from ourselves (self-send) and the contact sending is not trusted:
|
||||
// do not continue, but do not fail
|
||||
handleFailure(Error.NoSender, null)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,6 @@ dependencies {
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
|
||||
implementation "nl.komponents.kovenant:kovenant:$kovenantVersion"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "org.assertj:assertj-core:1.7.1"
|
||||
testImplementation "org.assertj:assertj-core:3.11.1"
|
||||
testImplementation "org.conscrypt:conscrypt-openjdk-uber:2.0.0"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user