Performed a PR pass to fix up anything obvious - there's still a few things left TODO

This commit is contained in:
alansley
2024-08-26 11:52:41 +10:00
parent 53978f818d
commit 404fb8001c
82 changed files with 147 additions and 1129 deletions

View File

@@ -225,7 +225,7 @@ dependencies {
ksp("androidx.hilt:hilt-compiler:$jetpackHiltVersion")
ksp("com.google.dagger:hilt-compiler:$daggerHiltVersion")
ksp "com.github.bumptech.glide:ksp:$glideVersion"
ksp("com.github.bumptech.glide:ksp:$glideVersion")
implementation 'androidx.compose.material3:material3-android:1.2.1'
implementation("com.google.dagger:hilt-android:$daggerHiltVersion")
@@ -273,7 +273,6 @@ dependencies {
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
implementation "com.github.bumptech.glide:glide:$glideVersion"
implementation "com.github.bumptech.glide:compose:1.0.0-beta01"
ksp "com.github.bumptech.glide:ksp:$glideVersion"
implementation 'com.makeramen:roundedimageview:2.1.0'
implementation 'com.pnikosis:materialish-progress:1.5'
implementation 'org.greenrobot:eventbus:3.0.0'

View File

@@ -268,13 +268,6 @@
android:theme="@style/Theme.Session.DayNight.NoActionBar"
android:launchMode="singleTask"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="org.thoughtcrime.securesms.MediaOverviewActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/Theme.Session.DayNight.NoActionBar"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="org.thoughtcrime.securesms.DummyActivity"
android:allowTaskReparenting="true"

View File

@@ -405,7 +405,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
@SuppressWarnings("CodeBlock2Expr")
@SuppressLint("InlinedApi")
private void saveToDisk() {
Log.w("ACL", "Asked to save to disk!");
MediaItem mediaItem = getCurrentMediaItem();
if (mediaItem == null) return;
@@ -487,6 +486,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
// TODO / WARNING: R.id values are NON-CONSTANT in Gradle 8.0+ - what would be the best way to address this?! -AL 2024/08/26
case R.id.media_preview__overview: showOverview(); return true;
case R.id.media_preview__forward: forward(); return true;
case R.id.save: saveToDisk(); return true;
@@ -537,15 +537,11 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
throw new RuntimeException("restartItem = " + restartItem + ", data.second = " + data.second + " leftIsRecent = " + leftIsRecent, e);
}
if (item == 0) {
viewPagerListener.onPageSelected(0);
}
if (item == 0) { viewPagerListener.onPageSelected(0); }
}
@Override
public void onLoaderReset(@NonNull Loader<Pair<Cursor, Integer>> loader) {
}
public void onLoaderReset(@NonNull Loader<Pair<Cursor, Integer>> loader) { /* Do nothing */ }
private class ViewPagerListener implements ViewPager.OnPageChangeListener {
@@ -580,13 +576,11 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
/* Do nothing */
}
@Override
public void onPageScrollStateChanged(int state) {
}
public void onPageScrollStateChanged(int state) { /* Do nothing */ }
}
private static class SingleItemPagerAdapter extends MediaItemAdapter {
@@ -651,9 +645,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
}
@Override
public void pause(int position) {
}
public void pause(int position) { /* Do nothing */ }
@Override
public @Nullable View getPlaybackControls(int position) {

View File

@@ -29,12 +29,14 @@ import android.provider.OpenableColumns;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import network.loki.messenger.R;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.DistributionTypes;
import org.session.libsession.utilities.ViewUtil;
@@ -49,12 +51,6 @@ import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.providers.BlobProvider;
import org.thoughtcrime.securesms.util.MediaUtil;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import network.loki.messenger.R;
/**
* An activity to quickly share content with contacts
*
@@ -69,7 +65,6 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
public static final String EXTRA_ADDRESS_MARSHALLED = "address_marshalled";
public static final String EXTRA_DISTRIBUTION_TYPE = "distribution_type";
private ContactSelectionListFragment contactsFragment;
private SearchToolbar searchToolbar;
private ImageView searchAction;

View File

@@ -167,7 +167,6 @@ public class AudioSlidePlayer implements SensorEventListener {
}
}
@Override
public void onPlayerError(PlaybackException error) {
Log.w(TAG, "MediaPlayer Error: " + error);
@@ -206,9 +205,7 @@ public class AudioSlidePlayer implements SensorEventListener {
this.mediaPlayer.release();
}
if (this.audioAttachmentServer != null) {
this.audioAttachmentServer.stop();
}
if (this.audioAttachmentServer != null) { this.audioAttachmentServer.stop(); }
sensorManager.unregisterListener(AudioSlidePlayer.this);
@@ -217,9 +214,7 @@ public class AudioSlidePlayer implements SensorEventListener {
}
public synchronized static void stopAll() {
if (playing.isPresent()) {
playing.get().stop();
}
if (playing.isPresent()) { playing.get().stop(); }
}
public synchronized boolean isReady() {
@@ -361,9 +356,8 @@ public class AudioSlidePlayer implements SensorEventListener {
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
public void onAccuracyChanged(Sensor sensor, int accuracy) { /* Do nothing */ }
}
public interface Listener {
void onPlayerStart(@NonNull AudioSlidePlayer player);

View File

@@ -44,7 +44,7 @@ public class SwitchPreferenceCompat extends CheckBoxPreference {
// Substitute app name into lockscreen preference summary
if (key.equalsIgnoreCase(LOCK_SCREEN_KEY)) {
Context c = getContext();
CharSequence substitutedSummaryCS = Phrase.from(c, R.string.lockAppDescriptionAndroid)
CharSequence substitutedSummaryCS = Phrase.from(c, R.string.lockAppDescription)
.put(APP_NAME_KEY, c.getString(R.string.app_name))
.format();
this.setSummary(substitutedSummaryCS);

View File

@@ -14,7 +14,6 @@ import com.bumptech.glide.RequestManager
class UserView : LinearLayout {
private lateinit var binding: ViewUserBinding
var openGroupThreadID: Long = -1L // FIXME: This is a bit ugly
enum class ActionIndicator {
None,
@@ -86,8 +85,6 @@ class UserView : LinearLayout {
}
}
fun unbind() {
binding.profilePictureView.recycle()
}
fun unbind() { binding.profilePictureView.recycle() }
// endregion
}

View File

@@ -41,7 +41,6 @@ internal class NewMessageViewModel @Inject constructor(
override fun onChange(value: String) {
loadOnsJob?.cancel()
loadOnsJob = null
_state.update { it.copy(newMessageIdOrOns = value, isTextErrorColor = false, loading = false) }
}
@@ -112,4 +111,4 @@ internal data class State(
val isNextButtonEnabled: Boolean get() = newMessageIdOrOns.isNotBlank()
}
internal data class Success(val publicKey: String)
internal data class Success(val publicKey: String)

View File

@@ -1368,7 +1368,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
return false
} else {
// ..otherwise if the earliest emoji reaction was more than a minute ago we'll
// remove that early reaction to move the timestamp at index 1 into index 0,, add
// remove that early reaction to move the timestamp at index 1 into index 0, add
// our new timestamp and return true to accept the emoji reaction.
emojiRateLimiterQueue.removeFirst()
emojiRateLimiterQueue.addLast(timestamp)
@@ -1843,7 +1843,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
// ..otherwise we can attempt to send the attachment(s).
// Note: The only multi-attachment message type is when sending images - all others
// attempt send on initial attachment selection.
// attempt send the attachment immediately upon file selection.
sendAttachments(attachmentManager.buildSlideDeck().asAttachments(), null)
}
@@ -1931,8 +1931,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
} else {
Permissions.with(this)
.request(Manifest.permission.RECORD_AUDIO)
.withRationaleDialog(getString(R.string.permissionsMicrophoneAccessRequiredAndroid), R.drawable.ic_baseline_mic_48)
.withPermanentDenialDialog(Phrase.from(applicationContext, R.string.permissionsMicrophoneAccessRequiredAndroid)
.withRationaleDialog(getString(R.string.permissionsMicrophoneAccessRequired), R.drawable.ic_baseline_mic_48)
.withPermanentDenialDialog(Phrase.from(applicationContext, R.string.permissionsMicrophoneAccessRequired)
.put(APP_NAME_KEY, getString(R.string.app_name))
.format().toString())
.execute()
@@ -2119,7 +2119,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
override fun banUser(messages: Set<MessageRecord>) {
showSessionDialog {
title(R.string.banUser)
// ACL TODO - We need a string for the below `text` element
// ACL TODO - We need a string for the below `text` element - have asked Lucy about this 2024/08/26 -AL
text("This will ban the selected user from this room. It won't ban them from other rooms.")
button(R.string.banUser) { viewModel.banUser(messages.first().individualRecipient); endActionMode() }
cancelButton(::endActionMode)
@@ -2129,7 +2129,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
override fun banAndDeleteAll(messages: Set<MessageRecord>) {
showSessionDialog {
title(R.string.banUser)
// ACL TODO - We need a string for the below `text` element
// ACL TODO - We need a string for the below `text` element - have asked Lucy about this 2024/08/26 -AL
text("This will ban the selected user from this room and delete all messages sent by them. It won't ban them from other rooms or delete the messages they sent there.")
button(R.string.banUser) { viewModel.banAndDeleteAll(messages.first()); endActionMode() }
cancelButton(::endActionMode)

View File

@@ -33,7 +33,7 @@ class BlockedDialog(private val recipient: Recipient, private val context: Conte
title(resources.getString(R.string.blockUnblock))
text(spannable)
dangerButton(R.string.blockUnblock,R.string.AccessibilityId_unblockConfirm) { unblock() }
dangerButton(R.string.blockUnblock, R.string.AccessibilityId_unblockConfirm) { unblock() }
cancelButton { dismiss() }
}

View File

@@ -634,7 +634,7 @@ open class Storage(
val threadID = getOrCreateThreadIdFor(Address.fromSerialized(groupId))
threadDb.setDate(threadID, formationTimestamp)
// ACL Note: Commenting out this line prevents the timestamp of room creation being added to a new closed group,
// Note: Commenting out this line prevents the timestamp of room creation being added to a new closed group,
// which in turn allows us to show the `groupNoMessages` control message text.
//insertOutgoingInfoMessage(context, groupId, SignalServiceGroup.Type.CREATION, title, members.map { it.serialize() }, admins.map { it.serialize() }, threadID, formationTimestamp)

View File

@@ -6,17 +6,15 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.database.Cursor;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import com.squareup.phrase.Phrase;
import java.io.File;
import net.zetetic.database.sqlcipher.SQLiteConnection;
import net.zetetic.database.sqlcipher.SQLiteDatabase;
import net.zetetic.database.sqlcipher.SQLiteDatabaseHook;
import net.zetetic.database.sqlcipher.SQLiteOpenHelper;
import network.loki.messenger.R;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
@@ -43,13 +41,8 @@ import org.thoughtcrime.securesms.database.SessionContactDatabase;
import org.thoughtcrime.securesms.database.SessionJobDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities;
import java.io.File;
import network.loki.messenger.R;
public class SQLCipherOpenHelper extends SQLiteOpenHelper {
@SuppressWarnings("unused")

View File

@@ -156,123 +156,10 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
private val isFromOnboarding: Boolean get() = intent.getBooleanExtra(FROM_ONBOARDING, false)
private val isNewAccount: Boolean get() = intent.getBooleanExtra(NEW_ACCOUNT, false)
// ACL REMOVE BLOCK START
fun getRelativeTimeLocalized(timestampMS: Long): String {
// Get the current system time
val nowMS = System.currentTimeMillis()
// Calculate the time difference in milliseconds - this value will be negative if it's in the
// future or positive if it's in the past.
val timeDifferenceMS = nowMS - timestampMS
// Choose a desired time resolution based on the time difference.
// Note: We do this against the absolute time difference so this function can still work for
// both future/past times without having separate future/past cases.
val desiredResolution = when (abs(timeDifferenceMS)) {
in 0..DateUtils.MINUTE_IN_MILLIS -> DateUtils.SECOND_IN_MILLIS
in DateUtils.MINUTE_IN_MILLIS..DateUtils.HOUR_IN_MILLIS -> DateUtils.MINUTE_IN_MILLIS
in DateUtils.HOUR_IN_MILLIS..DateUtils.DAY_IN_MILLIS -> DateUtils.HOUR_IN_MILLIS
in DateUtils.DAY_IN_MILLIS..DateUtils.WEEK_IN_MILLIS -> DateUtils.DAY_IN_MILLIS
// We don't do months or years, so if the result is 53 weeks then so be it - also, the
// getRelativeTimeSpanString method's resolution maxes out at weeks!
else -> DateUtils.WEEK_IN_MILLIS
}
// Use DateUtils to get the relative time span string
return DateUtils.getRelativeTimeSpanString(
timestampMS,
nowMS,
desiredResolution,
DateUtils.FORMAT_ABBREV_RELATIVE
// Using either DateUtils.FORMAT_ABBREV_RELATIVE or DateUtils.FORMAT_ABBREV_ALL gives:
// - 1 sec. ago / 2 sec. ago
// - 1 min. ago / 2 min. ago
// - 1 hr. ago / 2 hr. ago
// - Yesterday / 2 days ago
// - August 2 / 2 wk. ago / 14 wk. ago <-- Note: Date running this test is August 9th.
// Using either 0 or DateUtils.FORMAT_ABBREV_TIME gives:
// - 1 second ago / 2 seconds ago
// - 1 minute ago / 2 minutes ago
// - 1 hour ago / 2 hours ago
// - Yesterday / 2 days ago
// - August 2nd / 2 weeks ago / 14 weeks ago <-- Note: Date running this test is August 9th.
).toString()
}
fun testRelativeTimes(op: (Long, Long) -> Long) {
var t = 0L
// 1 and 2 seconds
t = op(System.currentTimeMillis(), 1.seconds.inWholeMilliseconds)
Log.w("ACL", "1s -> ${getRelativeTimeLocalized(t)}")
t = op(System.currentTimeMillis(), 2.seconds.inWholeMilliseconds)
Log.w("ACL", "2s -> ${getRelativeTimeLocalized(t)}")
// 1 and 2 minutes
t = op(System.currentTimeMillis(), 1.minutes.inWholeMilliseconds)
Log.w("ACL", "1m -> ${getRelativeTimeLocalized(t)}")
t = op(System.currentTimeMillis(), 2.minutes.inWholeMilliseconds)
Log.w("ACL", "2m -> ${getRelativeTimeLocalized(t)}")
// 1 and 2 hours
t = op(System.currentTimeMillis(), 1.hours.inWholeMilliseconds)
Log.w("ACL", "1h -> ${getRelativeTimeLocalized(t)}")
t = op(System.currentTimeMillis(), 2.hours.inWholeMilliseconds)
Log.w("ACL", "2h -> ${getRelativeTimeLocalized(t)}")
// 1 and 2 days
t = op(System.currentTimeMillis(), 1.days.inWholeMilliseconds)
Log.w("ACL", "1d -> ${getRelativeTimeLocalized(t)}")
t = op(System.currentTimeMillis(), 2.days.inWholeMilliseconds)
Log.w("ACL", "2d -> ${getRelativeTimeLocalized(t)}")
// 1 week, 2 weeks, and 100 days (14.285 weeks)
t = op(System.currentTimeMillis(), 7.days.inWholeMilliseconds)
Log.w("ACL", "1w -> ${getRelativeTimeLocalized(t)}")
t = op(System.currentTimeMillis(), 14.days.inWholeMilliseconds)
Log.w("ACL", "2w -> ${getRelativeTimeLocalized(t)}")
t = op(System.currentTimeMillis(), 100.days.inWholeMilliseconds)
Log.w("ACL", "100d -> ${getRelativeTimeLocalized(t)}")
}
fun testSystemGeneratedRelativeTimes() {
// Print relative times in the past
var op: (Long, Long) -> Long = Long::minus
testRelativeTimes(op)
// Print relative times in the future
op = Long::plus
testRelativeTimes(op)
}
// ACL REMOVE BLOCK END
// region Lifecycle
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
super.onCreate(savedInstanceState, isReady)
// ACL REMOVE THIS WHEN UNIT TESTS ARE FIXED
//Locale.setDefault(Locale.FRENCH)
//testSystemGeneratedRelativeTimes()
// Set content view
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)

View File

@@ -53,7 +53,7 @@ class PathActivity : PassphraseRequiredActionBarActivity() {
setContentView(binding.root)
supportActionBar!!.title = resources.getString(R.string.onionRoutingPath)
// Substitute the localised version of "Session" into the layout
// Substitute "Session" into the path description. Note: This is a non-translatable string.
val appName = applicationContext.getString(R.string.app_name)
val txt = Phrase.from(applicationContext, R.string.onionRoutingPathDescription).put(APP_NAME_KEY, appName).format().toString()
binding.pathDescription.text = txt

View File

@@ -1,10 +1,5 @@
package org.thoughtcrime.securesms.linkpreview;
import static org.thoughtcrime.securesms.giph.util.InfiniteScrollListener.TAG;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.annotation.SuppressLint;
import android.os.Build;
import android.text.Html;
@@ -12,15 +7,9 @@ import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.util.DateUtils;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsession.utilities.Util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
@@ -30,10 +19,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.text.format.DateFormat;
import okhttp3.HttpUrl;
import org.session.libsession.utilities.Util;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Optional;
public final class LinkPreviewUtil {
@@ -71,9 +60,9 @@ public final class LinkPreviewUtil {
if (linkUrl == null) return false;
HttpUrl url = HttpUrl.parse(linkUrl);
return url != null &&
!TextUtils.isEmpty(url.scheme()) &&
"https".equals(url.scheme()) &&
return url != null &&
!TextUtils.isEmpty(url.scheme()) &&
"https".equals(url.scheme()) &&
isLegalUrl(linkUrl);
}
@@ -84,9 +73,9 @@ public final class LinkPreviewUtil {
if (mediaUrl == null) return false;
HttpUrl url = HttpUrl.parse(mediaUrl);
return url != null &&
!TextUtils.isEmpty(url.scheme()) &&
"https".equals(url.scheme()) &&
return url != null &&
!TextUtils.isEmpty(url.scheme()) &&
"https".equals(url.scheme()) &&
isLegalUrl(mediaUrl);
}

View File

@@ -35,9 +35,9 @@ class FixedTimeBuckets(
@StringRes
fun getBucketText(time: ZonedDateTime): Int? {
return when {
time >= startOfToday -> R.string.BucketedThreadMedia_Today // Should be replaced with call to getLocalisedRelativeDayString
time >= startOfYesterday -> R.string.BucketedThreadMedia_Yesterday // Should be replaced with call to getLocalisedRelativeDayString
time >= startOfThisWeek -> R.string.attachmentsThisWeek
time >= startOfToday -> R.string.BucketedThreadMedia_Today
time >= startOfYesterday -> R.string.BucketedThreadMedia_Yesterday
time >= startOfThisWeek -> R.string.attachmentsThisWeek
time >= startOfThisMonth -> R.string.attachmentsThisMonth
else -> null
}

View File

@@ -28,6 +28,8 @@ import android.database.Cursor
import android.os.AsyncTask
import android.os.Build
import android.text.TextUtils
import android.widget.Toast
import androidx.camera.core.impl.utils.ContextUtil.getApplicationContext
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
@@ -45,6 +47,7 @@ import org.session.libsession.messaging.utilities.AccountId
import org.session.libsession.messaging.utilities.SodiumUtilities.blindedKeyPair
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.ServiceUtil
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.EMOJI_KEY
import org.session.libsession.utilities.TextSecurePreferences.Companion.getLocalNumber
import org.session.libsession.utilities.TextSecurePreferences.Companion.getNotificationPrivacy
@@ -67,6 +70,8 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.ReactionRecord
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get
import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.ShareLogsDialog
import org.thoughtcrime.securesms.service.KeyCachingService
import org.thoughtcrime.securesms.util.SessionMetaProtocol.canUserReplyToNotification
import org.thoughtcrime.securesms.util.SpanUtil
@@ -209,7 +214,6 @@ class DefaultMessageNotifier : MessageNotifier {
return
}
//var notificationState: NotificationState
try {
val notificationState = constructNotificationState(context, telcoCursor)
@@ -353,7 +357,7 @@ class DefaultMessageNotifier : MessageNotifier {
val notification = builder.build()
// ACL FIX THIS PROPERLY
// TODO - ACL to fix this properly & will do on 2024-08-26, but just skipping for now so review can start
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
@@ -435,7 +439,7 @@ class DefaultMessageNotifier : MessageNotifier {
builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag)
// ACL FIX THIS PROPERLY
// TODO - ACL to fix this properly & will do on 2024-08-26, but just skipping for now so review can start
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
@@ -463,7 +467,7 @@ class DefaultMessageNotifier : MessageNotifier {
val threadDatabase = get(context).threadDatabase()
val cache: MutableMap<Long, String?> = HashMap()
// CAREFUL: Do not put this loop back as `while ((reader.next.also { record = it }) != null) {` because it breaks with a Null Pointer Exception - you have been warned.
// CAREFUL: Do not put this loop back as `while ((reader.next.also { record = it }) != null) {` because it breaks with a Null Pointer Exception!
var record: MessageRecord? = null
do {
record = reader.next
@@ -587,7 +591,6 @@ class DefaultMessageNotifier : MessageNotifier {
if (count == 0) ShortcutBadger.removeCount(context)
else ShortcutBadger.applyCount(context, count)
} catch (t: Throwable) {
// NOTE :: I don't totally trust this thing, so I'm catching everything.
Log.w("MessageNotifier", t)
}
}

View File

@@ -18,7 +18,6 @@ import java.util.List;
import network.loki.messenger.R;
import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.utilities.NotificationPrivacyPreference;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.database.SessionContactDatabase;
@@ -41,12 +40,15 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu
}
public void setMessageCount(int messageCount, int threadCount) {
String txt = Phrase.from(context, R.string.notificationsAndroidSystem)
String txt = Phrase.from(context, R.string.notificationsSystem)
.put(MESSAGE_COUNT_KEY, messageCount)
.put(CONVERSATION_COUNT_KEY, threadCount)
.format().toString();
setSubText(txt);
setContentInfo(String.valueOf(messageCount)); // Note: `setContentInfo` details are only visible in Android API 24 and below - remove when min. API is upgraded.
// Note: `setContentInfo` details are only visible in Android API 24 and below - as our minimum is now API 26 this can be skipped.
//setContentInfo(String.valueOf(messageCount));
setNumber(messageCount);
}

View File

@@ -71,7 +71,7 @@ internal fun MessageNotificationsScreen(
NotificationRadioButton(
R.string.notificationsFastMode,
R.string.notificationsFastModeDescriptionAndroid,
R.string.notificationsFastModeDescription,
modifier = Modifier.contentDescription(R.string.AccessibilityId_notificationsFastMode),
tag = R.string.recommended,
checked = state.pushEnabled,

View File

@@ -1,41 +0,0 @@
package org.thoughtcrime.securesms.preferences
import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import network.loki.messenger.R
import org.session.libsignal.crypto.MnemonicCodec
import org.session.libsignal.utilities.hexEncodedPrivateKey
import org.thoughtcrime.securesms.createSessionDialog
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
class SeedDialog: DialogFragment() {
private val seed by lazy {
val hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
?: IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
MnemonicCodec { fileName -> MnemonicUtilities.loadFileContents(requireContext(), fileName) }
.encode(hexEncodedSeed, MnemonicCodec.Language.Configuration.english)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
title(R.string.sessionRecoveryPassword)
text(R.string.recoveryPasswordDescription)
text(seed, R.style.AccountIdTextView)
button(R.string.copy, R.string.AccessibilityId_sessionRecoveryPasswordCopy) { copySeed() }
button(R.string.close) { dismiss() }
}
private fun copySeed() {
val clipboard = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Seed", seed)
clipboard.setPrimaryClip(clip)
Toast.makeText(requireContext(), R.string.copied, Toast.LENGTH_SHORT).show()
dismiss()
}
}

View File

@@ -15,6 +15,11 @@ import android.widget.Toast
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.squareup.phrase.Phrase
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.Objects
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
@@ -29,11 +34,6 @@ import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.createSessionDialog
import org.thoughtcrime.securesms.util.FileProviderUtil
import org.thoughtcrime.securesms.util.StreamUtil
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.Objects
import java.util.concurrent.TimeUnit
class ShareLogsDialog(private val updateCallback: (Boolean)->Unit): DialogFragment() {

View File

@@ -54,7 +54,7 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels;
*
* @author Moxie Marlinspike
*/
//TODO AC: This service does only serve one purpose now - to track the screen lock state and handle the timer.
// TODO: This service does only serve one purpose now - to track the screen lock state and handle the timer.
// We need to refactor it and cleanup from all the old Signal code.
public class KeyCachingService extends Service {
@@ -70,7 +70,7 @@ public class KeyCachingService extends Service {
private final IBinder binder = new KeySetBinder();
// AC: This is a temporal drop off replacement for the refactoring time being.
// This is a temporal drop off replacement for the refactoring time being.
// This field only indicates if the app was unlocked or not (null means locked).
private static Object masterSecret = null;

View File

@@ -8,21 +8,17 @@ import android.content.Intent;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.widget.Toast;
import com.squareup.phrase.Phrase;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import network.loki.messenger.R;
import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.sending_receiving.MessageSender;
import org.session.libsession.snode.SnodeAPI;
import org.session.libsession.utilities.Address;
import org.session.libsignal.utilities.Log;
import org.session.libsession.messaging.sending_receiving.MessageSender;
import org.thoughtcrime.securesms.util.Rfc5724Uri;
import java.net.URISyntaxException;
import java.net.URLDecoder;
public class QuickResponseService extends IntentService {
private static final String TAG = QuickResponseService.class.getSimpleName();

View File

@@ -10,12 +10,14 @@ import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.squareup.phrase.Phrase;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import network.loki.messenger.R;
import org.session.libsession.utilities.FileUtils;
import org.session.libsession.utilities.ServiceUtil;
import org.session.libsession.utilities.TextSecurePreferences;
@@ -24,13 +26,6 @@ import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.util.FileProviderUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import network.loki.messenger.R;
public class UpdateApkReadyListener extends BroadcastReceiver {
private static final String TAG = UpdateApkReadyListener.class.getSimpleName();
@@ -128,4 +123,4 @@ public class UpdateApkReadyListener extends BroadcastReceiver {
return false;
}
}
}
}

View File

@@ -31,7 +31,7 @@ import java.util.Locale
import java.util.concurrent.TimeUnit
// Enums used to get the locale-aware String for one of the three relative days
public enum class RelativeDay { TODAY, YESTERDAY, TOMORROW }
enum class RelativeDay { TODAY, YESTERDAY, TOMORROW }
/**
* Utility methods to help display dates in a nice, easily readable way.
@@ -81,30 +81,6 @@ object DateUtils : android.text.format.DateUtils() {
FORMAT_SHOW_DATE).toString()
}
// Method to get the locale-aware String for the word "Now"
// public fun getLocalisedNowString(): String {
// val now = Calendar.getInstance().timeInMillis
// return getRelativeTimeSpanString(now, now,MINUTE_IN_MILLIS, FORMAT_SHOW_TIME).toString()
// }
// THIS DOES NOT WORK
public fun getLocalisedNowString(): String {
val now = Calendar.getInstance().timeInMillis
val relativeTime = getRelativeTimeSpanString(now, now, MINUTE_IN_MILLIS, FORMAT_SHOW_TIME).toString()
// Create a DateFormat instance for the current time
val timeFormat = getTimeInstance(SHORT, Locale.getDefault())
val formattedTime = timeFormat.format(Calendar.getInstance().time)
// Check if the relative time indicates "0 minutes ago" or similar and replace it with the formatted time
return if (relativeTime == "0 minutes ago" || relativeTime == "in 0 minutes") {
formattedTime
} else {
relativeTime
}
}
fun getFormattedDateTime(time: Long, template: String, locale: Locale): String {
val localizedPattern = getLocalizedPattern(template, locale)
return SimpleDateFormat(localizedPattern, locale).format(Date(time))
@@ -117,8 +93,9 @@ object DateUtils : android.text.format.DateUtils() {
fun getDisplayFormattedTimeSpanString(c: Context, locale: Locale, timestamp: Long): String {
// If the timestamp is invalid (ie. 0) then assume we're waiting on data and just use the 'Now' copy
return if (timestamp == 0L || isWithin(timestamp, 1, TimeUnit.MINUTES)) {
getLocalisedNowString()
//c.getString(R.string.DateUtils_just_now) // ACL REMOVE WHEN HAPPY
// TODO ACL: We need a string for "Now" because I can't seem to coax a localised version from DateUtils -
// TODO: although anyone seeing is this is more than welcome to try! - 2024-08-26
"Now"
} else if (isToday(timestamp)) {
getFormattedDateTime(timestamp, getHourFormat(c), locale)
} else if (isWithin(timestamp, 6, TimeUnit.DAYS)) {

View File

@@ -133,15 +133,9 @@ class SaveAttachmentTask @JvmOverloads constructor(context: Context, count: Int
private fun createOutputUri(context: Context, outputUri: Uri, contentType: String, fileName: String): Uri? {
if (fileName == null)
{
Log.w("ACL", "Filename is null - wtf!")
}
if (fileName != null && fileName.isEmpty())
{
Log.w("ACL", "Filename is empty - wtf!")
}
// TODO: This method may pass an empty string as the filename in Android API 28 and below. This requires
// TODO: follow-up investigation, but has temporarily been worked around, see:
// TODO: https://github.com/oxen-io/session-android/commit/afbb71351a74220c312a09c25cc1c79738453c12
val fileParts: Array<String> = getFileNameParts(fileName)
val base = fileParts[0]

View File

@@ -7,7 +7,7 @@
<org.thoughtcrime.securesms.components.SwitchPreferenceCompat
android:key="pref_key_use_fcm"
android:title="@string/useFastMode"
android:summary="@string/notificationsFastModeDescriptionAndroid"
android:summary="@string/notificationsFastModeDescription"
android:defaultValue="false" />
<Preference android:title="@string/notificationsGoToDevice"

View File

@@ -9,7 +9,7 @@
android:key="pref_android_screen_lock"
android:defaultValue="false"
android:title="@string/lockApp"
android:summary="@string/lockAppDescriptionAndroid" />
android:summary="@string/lockAppDescription" />
<org.thoughtcrime.securesms.components.SwitchPreferenceCompat
android:defaultValue="@bool/screen_security_default"