Merge branch 'dev' of github.com:loki-project/loki-messenger-android into private-group-chat

This commit is contained in:
Niels Andriesse 2020-02-04 13:23:23 +11:00
commit 155c7f2b12
35 changed files with 147 additions and 153 deletions

View File

@ -6,7 +6,6 @@ buildscript {
ext.kovenant_version = "3.3.0" ext.kovenant_version = "3.3.0"
ext.identicon_version = "v11" ext.identicon_version = "v11"
ext.rss_parser_version = "2.0.4" ext.rss_parser_version = "2.0.4"
ext.mixpanel_version = "5.+"
ext.crashlytics_version = "2.10.1" ext.crashlytics_version = "2.10.1"
repositories { repositories {
@ -196,7 +195,6 @@ dependencies {
implementation "nl.komponents.kovenant:kovenant-android:$kovenant_version" implementation "nl.komponents.kovenant:kovenant-android:$kovenant_version"
implementation "com.github.lelloman:android-identicons:$identicon_version" implementation "com.github.lelloman:android-identicons:$identicon_version"
implementation "com.prof.rssparser:rssparser:$rss_parser_version" implementation "com.prof.rssparser:rssparser:$rss_parser_version"
implementation "com.mixpanel.android:mixpanel-android:$mixpanel_version"
implementation("com.crashlytics.sdk.android:crashlytics:$crashlytics_version@aar") { implementation("com.crashlytics.sdk.android:crashlytics:$crashlytics_version@aar") {
transitive = true transitive = true
} }
@ -237,10 +235,10 @@ android {
project.ext.set("archivesBaseName", "Signal") project.ext.set("archivesBaseName", "Signal")
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L" buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
buildConfigField "String", "SIGNAL_URL", "\"https://textsecure-service.whispersystems.org\"" buildConfigField "String", "SIGNAL_URL", "\"\""
buildConfigField "String", "SIGNAL_CDN_URL", "\"https://cdn.signal.org\"" buildConfigField "String", "SIGNAL_CDN_URL", "\"\""
buildConfigField "String", "SIGNAL_CONTACT_DISCOVERY_URL", "\"https://api.directory.signal.org\"" buildConfigField "String", "SIGNAL_CONTACT_DISCOVERY_URL", "\"\""
buildConfigField "String", "SIGNAL_SERVICE_STATUS_URL", "\"uptime.signal.org\"" buildConfigField "String", "SIGNAL_SERVICE_STATUS_URL", "\"\""
buildConfigField "String", "CONTENT_PROXY_HOST", "\"contentproxy.signal.org\"" buildConfigField "String", "CONTENT_PROXY_HOST", "\"contentproxy.signal.org\""
buildConfigField "int", "CONTENT_PROXY_PORT", "443" buildConfigField "int", "CONTENT_PROXY_PORT", "443"
buildConfigField "String", "USER_AGENT", "\"OWA\"" buildConfigField "String", "USER_AGENT", "\"OWA\""

View File

@ -40,7 +40,19 @@
android:id="@+id/joinPublicChatButton" android:id="@+id/joinPublicChatButton"
android:layout_width="196dp" android:layout_width="196dp"
android:layout_height="@dimen/medium_button_height" android:layout_height="@dimen/medium_button_height"
android:layout_marginBottom="@dimen/medium_spacing"
android:text="Next" /> android:text="Next" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/medium_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:layout_marginBottom="@dimen/medium_spacing"
android:textSize="@dimen/very_small_font_size"
android:textColor="@color/text"
android:alpha="0.6"
android:textAlignment="center"
android:text="Open groups can be joined by anyone and do not provide full metadata protection" />
</LinearLayout> </LinearLayout>

View File

@ -104,7 +104,7 @@
android:indeterminate="false" android:indeterminate="false"
android:progress="80" /> android:progress="80" />
<org.thoughtcrime.securesms.loki.SessionRestoreBannerView <org.thoughtcrime.securesms.loki.redesign.views.SessionRestoreBannerView
android:id="@+id/sessionRestoreBannerView" android:id="@+id/sessionRestoreBannerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

View File

@ -22,7 +22,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing" android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/medium_spacing" android:layout_marginTop="@dimen/small_spacing"
android:layout_marginRight="@dimen/large_spacing" android:layout_marginRight="@dimen/large_spacing"
android:textSize="@dimen/small_font_size" android:textSize="@dimen/small_font_size"
android:textColor="@color/text" android:textColor="@color/text"
@ -40,7 +40,19 @@
android:id="@+id/joinPublicChatButton" android:id="@+id/joinPublicChatButton"
android:layout_width="196dp" android:layout_width="196dp"
android:layout_height="@dimen/medium_button_height" android:layout_height="@dimen/medium_button_height"
android:layout_marginBottom="@dimen/medium_spacing"
android:text="Next" /> android:text="Next" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/small_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:layout_marginBottom="@dimen/small_spacing"
android:textSize="@dimen/very_small_font_size"
android:textColor="@color/text"
android:alpha="0.6"
android:textAlignment="center"
android:text="Open groups can be joined by anyone and do not provide full metadata protection" />
</LinearLayout> </LinearLayout>

View File

@ -33,7 +33,6 @@ import android.support.multidex.MultiDexApplication;
import com.crashlytics.android.Crashlytics; import com.crashlytics.android.Crashlytics;
import com.google.android.gms.security.ProviderInstaller; import com.google.android.gms.security.ProviderInstaller;
import com.mixpanel.android.mpmetrics.MixpanelAPI;
import org.conscrypt.Conscrypt; import org.conscrypt.Conscrypt;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -66,14 +65,14 @@ import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.logging.PersistentLogger; import org.thoughtcrime.securesms.logging.PersistentLogger;
import org.thoughtcrime.securesms.logging.UncaughtExceptionLogger; import org.thoughtcrime.securesms.logging.UncaughtExceptionLogger;
import org.thoughtcrime.securesms.loki.redesign.messaging.BackgroundPollWorker; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.BackgroundPublicChatPollWorker;
import org.thoughtcrime.securesms.loki.LokiAPIDatabase;
import org.thoughtcrime.securesms.loki.LokiPublicChatManager; import org.thoughtcrime.securesms.loki.LokiPublicChatManager;
import org.thoughtcrime.securesms.loki.LokiRSSFeedPoller; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiRSSFeedPoller;
import org.thoughtcrime.securesms.loki.LokiUserDatabase; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
import org.thoughtcrime.securesms.loki.redesign.messaging.BackgroundPollWorker;
import org.thoughtcrime.securesms.loki.redesign.messaging.BackgroundPublicChatPollWorker;
import org.thoughtcrime.securesms.loki.redesign.utilities.Broadcaster; import org.thoughtcrime.securesms.loki.redesign.utilities.Broadcaster;
import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationChannels;
@ -106,11 +105,9 @@ import org.whispersystems.signalservice.loki.api.LokiPublicChat;
import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI; import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI;
import org.whispersystems.signalservice.loki.api.LokiRSSFeed; import org.whispersystems.signalservice.loki.api.LokiRSSFeed;
import org.whispersystems.signalservice.loki.api.LokiStorageAPI; import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
import org.whispersystems.signalservice.loki.utilities.Analytics;
import java.security.Security; import java.security.Security;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -119,7 +116,6 @@ import java.util.concurrent.TimeUnit;
import dagger.ObjectGraph; import dagger.ObjectGraph;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
import kotlin.Unit; import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import network.loki.messenger.BuildConfig; import network.loki.messenger.BuildConfig;
import okhttp3.Cache; import okhttp3.Cache;
@ -155,7 +151,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
private LokiPublicChatAPI lokiPublicChatAPI = null; private LokiPublicChatAPI lokiPublicChatAPI = null;
public Broadcaster broadcaster = null; public Broadcaster broadcaster = null;
public SignalCommunicationModule communicationModule; public SignalCommunicationModule communicationModule;
public MixpanelAPI mixpanel;
private volatile boolean isAppVisible; private volatile boolean isAppVisible;
@ -195,14 +190,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
Fabric.with(this, new Crashlytics()); Fabric.with(this, new Crashlytics());
} }
mixpanel = MixpanelAPI.getInstance(this, "59040b6707e5a1725f3fb6730fefca92");
Analytics.Companion.getShared().trackImplementation = (Function1<String, Unit>) event -> {
HashMap<String, Object> properties = new HashMap();
String configuration = BuildConfig.DEBUG ? "debug" : "production";
properties.put("configuration", configuration);
mixpanel.trackMap(event, properties);
return Unit.INSTANCE;
};
// Loki - Set the cache // Loki - Set the cache
LokiDotNetAPI.setCache(new Cache(this.getCacheDir(), OK_HTTP_CACHE_SIZE)); LokiDotNetAPI.setCache(new Cache(this.getCacheDir(), OK_HTTP_CACHE_SIZE));
// Loki - Update device mappings // Loki - Update device mappings
@ -529,7 +516,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
} }
private LokiRSSFeed lokiMessengerUpdatesFeed() { private LokiRSSFeed lokiMessengerUpdatesFeed() {
return new LokiRSSFeed("loki.network.messenger-updates.feed", "https://loki.network/category/messenger-updates/feed", "Loki Messenger Updates", false); return new LokiRSSFeed("loki.network.messenger-updates.feed", "https://loki.network/category/messenger-updates/feed", "Session Updates", false);
} }
public void createDefaultPublicChatsIfNeeded() { public void createDefaultPublicChatsIfNeeded() {
@ -576,7 +563,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
lokiNewsFeedPoller = null; lokiNewsFeedPoller = null;
}); });
} }
// The user can't delete the Loki Messenger Updates RSS feed // The user can't delete the Session Updates RSS feed
if (lokiMessengerUpdatesFeedPoller == null) { if (lokiMessengerUpdatesFeedPoller == null) {
lokiMessengerUpdatesFeedPoller = new LokiRSSFeedPoller(this, lokiMessengerUpdatesFeed()); lokiMessengerUpdatesFeedPoller = new LokiRSSFeedPoller(this, lokiMessengerUpdatesFeed());
} }

View File

@ -51,7 +51,6 @@ import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec; import org.whispersystems.signalservice.loki.crypto.MnemonicCodec;
import org.whispersystems.signalservice.loki.utilities.Analytics;
import org.whispersystems.signalservice.loki.utilities.SerializationKt; import org.whispersystems.signalservice.loki.utilities.SerializationKt;
import java.io.File; import java.io.File;
@ -101,7 +100,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
if (getIntent() != null && getIntent().getCategories() != null && getIntent().getCategories().contains("android.intent.category.NOTIFICATION_PREFERENCES")) { if (getIntent() != null && getIntent().getCategories() != null && getIntent().getCategories().contains("android.intent.category.NOTIFICATION_PREFERENCES")) {
initFragment(android.R.id.content, new NotificationsPreferenceFragment()); initFragment(android.R.id.content, new NotificationsPreferenceFragment());
} else if (icicle == null) { } else if (icicle == null) {
Analytics.Companion.getShared().track("Settings Opened");
initFragment(android.R.id.content, new ApplicationPreferenceFragment()); initFragment(android.R.id.content, new ApplicationPreferenceFragment());
} }
} }
@ -325,7 +323,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
break; break;
*/ */
case PREFERENCE_CATEGORY_PUBLIC_KEY: case PREFERENCE_CATEGORY_PUBLIC_KEY:
Analytics.Companion.getShared().track("Public Key Shared");
String hexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(getContext()); String hexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(getContext());
if (hexEncodedPublicKey == null) { if (hexEncodedPublicKey == null) {
hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext()); hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext());
@ -339,7 +336,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
case PREFERENCE_CATEGORY_QR_CODE: break; case PREFERENCE_CATEGORY_QR_CODE: break;
case PREFERENCE_CATEGORY_LINKED_DEVICES: break; case PREFERENCE_CATEGORY_LINKED_DEVICES: break;
case PREFERENCE_CATEGORY_SEED: case PREFERENCE_CATEGORY_SEED:
Analytics.Companion.getShared().track("Seed Modal Shown");
File languageFileDirectory = new File(getContext().getApplicationInfo().dataDir); File languageFileDirectory = new File(getContext().getApplicationInfo().dataDir);
try { try {
String hexEncodedSeed = IdentityKeyUtil.retrieve(getContext(), IdentityKeyUtil.lokiSeedKey); String hexEncodedSeed = IdentityKeyUtil.retrieve(getContext(), IdentityKeyUtil.lokiSeedKey);

View File

@ -60,7 +60,6 @@ import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.loki.api.LokiDotNetAPI; import org.whispersystems.signalservice.loki.api.LokiDotNetAPI;
import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI; import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI;
import org.whispersystems.signalservice.loki.api.LokiStorageAPI; import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
import org.whispersystems.signalservice.loki.utilities.Analytics;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
@ -119,8 +118,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
initializeProfileAvatar(getIntent().getBooleanExtra(EXCLUDE_SYSTEM, false)); initializeProfileAvatar(getIntent().getBooleanExtra(EXCLUDE_SYSTEM, false));
ApplicationContext.getInstance(this).injectDependencies(this); ApplicationContext.getInstance(this).injectDependencies(this);
Analytics.Companion.getShared().track("Display Name Screen Viewed");
} }
@Override @Override
@ -386,8 +383,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
protected Boolean doInBackground(Void... params) { protected Boolean doInBackground(Void... params) {
Context context = CreateProfileActivity.this; Context context = CreateProfileActivity.this;
Analytics.Companion.getShared().track("Display Name Updated");
TextSecurePreferences.setProfileName(context, name); TextSecurePreferences.setProfileName(context, name);
LokiPublicChatAPI publicChatAPI = ApplicationContext.getInstance(context).getLokiPublicChatAPI(); LokiPublicChatAPI publicChatAPI = ApplicationContext.getInstance(context).getLokiPublicChatAPI();
if (publicChatAPI != null) { if (publicChatAPI != null) {

View File

@ -25,7 +25,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.loaders.DeviceListLoader; import org.thoughtcrime.securesms.database.loaders.DeviceListLoader;
import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.devicelist.Device; import org.thoughtcrime.securesms.devicelist.Device;
import org.thoughtcrime.securesms.loki.DeviceListBottomSheetFragment; import org.thoughtcrime.securesms.loki.redesign.views.DeviceEditingOptionsBottomSheet;
import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities; import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.ViewUtil;
@ -140,7 +140,7 @@ public class DeviceListFragment extends ListFragment
final String deviceName = ((DeviceListItem)view).getDeviceName(); final String deviceName = ((DeviceListItem)view).getDeviceName();
final String deviceId = ((DeviceListItem)view).getDeviceId(); final String deviceId = ((DeviceListItem)view).getDeviceId();
DeviceListBottomSheetFragment bottomSheet = new DeviceListBottomSheetFragment(); DeviceEditingOptionsBottomSheet bottomSheet = new DeviceEditingOptionsBottomSheet();
bottomSheet.setOnEditTapped(() -> { bottomSheet.setOnEditTapped(() -> {
bottomSheet.dismiss(); bottomSheet.dismiss();
EditText deviceNameEditText = new EditText(getContext()); EditText deviceNameEditText = new EditText(getContext());

View File

@ -149,7 +149,7 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
Collections.sort(users); // Sort to provide a level of stability Collections.sort(users); // Sort to provide a level of stability
profilePictureView.setHexEncodedPublicKey(users.size() > 0 ? users.get(0) : ""); profilePictureView.setHexEncodedPublicKey(users.size() > 0 ? users.get(0) : "");
profilePictureView.setAdditionalHexEncodedPublicKey(users.size() > 1 ? users.get(1) : ""); profilePictureView.setAdditionalHexEncodedPublicKey(users.size() > 1 ? users.get(1) : "");
profilePictureView.setRSSFeed(name.equals("Loki News") || name.equals("Loki Messenger Updates")); profilePictureView.setRSSFeed(name.equals("Loki News") || name.equals("Session Updates"));
} else { } else {
profilePictureView.setHexEncodedPublicKey(this.number); profilePictureView.setHexEncodedPublicKey(this.number);
profilePictureView.setAdditionalHexEncodedPublicKey(null); profilePictureView.setAdditionalHexEncodedPublicKey(null);

View File

@ -157,16 +157,16 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil; import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel; import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities;
import org.thoughtcrime.securesms.loki.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate; import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate;
import org.thoughtcrime.securesms.loki.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
import org.thoughtcrime.securesms.loki.SessionRestoreBannerView;
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate; import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
import org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateSelectionView; import org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateSelectionView;
import org.thoughtcrime.securesms.loki.redesign.views.SessionRestoreBannerView;
import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mediasend.MediaSendActivity; import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
import org.thoughtcrime.securesms.mms.AttachmentManager; import org.thoughtcrime.securesms.mms.AttachmentManager;
@ -658,9 +658,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
break; break;
case PICK_GIF: case PICK_GIF:
setMedia(data.getData(), setMedia(data.getData(),
MediaType.GIF, MediaType.GIF,
data.getIntExtra(GiphyActivity.EXTRA_WIDTH, 0), data.getIntExtra(GiphyActivity.EXTRA_WIDTH, 0),
data.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0)); data.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0));
break; break;
case SMS_DEFAULT: case SMS_DEFAULT:
initializeSecurity(isSecureText, isDefaultSms); initializeSecurity(isSecureText, isDefaultSms);
@ -1935,7 +1935,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
case AttachmentTypeSelector.TAKE_PHOTO: case AttachmentTypeSelector.TAKE_PHOTO:
attachmentManager.capturePhoto(this, TAKE_PHOTO); break; attachmentManager.capturePhoto(this, TAKE_PHOTO); break;
case AttachmentTypeSelector.ADD_GIF: case AttachmentTypeSelector.ADD_GIF:
AttachmentManager.selectGif(this, PICK_GIF, !isSecureText); break; AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Search GIFs?");
builder.setMessage("You will not have full metadata protection when sending GIFs.");
builder.setPositiveButton("OK", (dialog, which) -> {
AttachmentManager.selectGif(this, PICK_GIF, !isSecureText);
dialog.dismiss();
});
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss() );
builder.create().show();
break;
} }
} }
@ -3182,7 +3191,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else if (recipient.isMuted()) { } else if (recipient.isMuted()) {
muteIndicatorImageView.setVisibility(View.VISIBLE); muteIndicatorImageView.setVisibility(View.VISIBLE);
actionBarSubtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault())); actionBarSubtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()));
} else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Loki Messenger Updates") && !recipient.getName().equals("Loki News")) { } else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) {
LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
if (publicChat != null) { if (publicChat != null) {
Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer()); Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer());

View File

@ -801,7 +801,7 @@ public class ConversationItem extends LinearLayout
int groupThreadMargin = (int)(getResources().getDimension(R.dimen.large_spacing) + getResources().getDimension(R.dimen.small_profile_picture_size)); int groupThreadMargin = (int)(getResources().getDimension(R.dimen.large_spacing) + getResources().getDimension(R.dimen.small_profile_picture_size));
int defaultMargin = 0; int defaultMargin = 0;
String threadName = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(messageRecord.getThreadId()).getName(); String threadName = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(messageRecord.getThreadId()).getName();
boolean isRSSFeed = threadName != null && (threadName.equals("Loki News") || threadName.equals("Loki Messenger Updates")); boolean isRSSFeed = threadName != null && (threadName.equals("Loki News") || threadName.equals("Session Updates"));
layoutParams.setMarginStart((groupThread && !isRSSFeed) ? groupThreadMargin : defaultMargin); layoutParams.setMarginStart((groupThread && !isRSSFeed) ? groupThreadMargin : defaultMargin);
bodyBubble.setLayoutParams(layoutParams); bodyBubble.setLayoutParams(layoutParams);
if (profilePictureView == null) return; if (profilePictureView == null) return;
@ -983,7 +983,7 @@ public class ConversationItem extends LinearLayout
private void setAuthor(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread) { private void setAuthor(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread) {
String threadName = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(current.getThreadId()).getName(); String threadName = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(current.getThreadId()).getName();
boolean isRSSFeed = threadName != null && (threadName.equals("Loki News") || threadName.equals("Loki Messenger Updates")); boolean isRSSFeed = threadName != null && (threadName.equals("Loki News") || threadName.equals("Session Updates"));
if (isGroupThread && !isRSSFeed && !current.isOutgoing()) { if (isGroupThread && !isRSSFeed && !current.isOutgoing()) {
contactPhotoHolder.setVisibility(VISIBLE); contactPhotoHolder.setVisibility(VISIBLE);

View File

@ -32,6 +32,10 @@ import org.thoughtcrime.securesms.database.helpers.ClassicOpenHelper;
import org.thoughtcrime.securesms.database.helpers.SQLCipherMigrationHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherMigrationHelper;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.loki.*; import org.thoughtcrime.securesms.loki.*;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyRecordDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiUserDatabase;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class DatabaseFactory { public class DatabaseFactory {

View File

@ -35,12 +35,12 @@ import org.thoughtcrime.securesms.database.StickerDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.LokiAPIDatabase;
import org.thoughtcrime.securesms.loki.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.LokiPreKeyBundleDatabase;
import org.thoughtcrime.securesms.loki.LokiPreKeyRecordDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.LokiUserDatabase; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyRecordDatabase;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiUserDatabase;
import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.GroupUtil;

View File

@ -9,9 +9,7 @@ import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException; import java.io.IOException;
@ -67,11 +65,11 @@ public class DirectoryRefreshJob extends BaseJob {
public void onRun() throws IOException { public void onRun() throws IOException {
Log.i(TAG, "DirectoryRefreshJob.onRun()"); Log.i(TAG, "DirectoryRefreshJob.onRun()");
if (recipient == null) { // if (recipient == null) {
DirectoryHelper.refreshDirectory(context, notifyOfNewUsers); // DirectoryHelper.refreshDirectory(context, notifyOfNewUsers);
} else { // } else {
DirectoryHelper.refreshDirectoryFor(context, recipient); // DirectoryHelper.refreshDirectoryFor(context, recipient);
} // }
} }
@Override @Override

View File

@ -70,8 +70,8 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.FriendRequestHandler; import org.thoughtcrime.securesms.loki.FriendRequestHandler;
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities;
import org.thoughtcrime.securesms.loki.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.LokiPreKeyBundleDatabase; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase;
import org.thoughtcrime.securesms.loki.LokiPreKeyRecordDatabase; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyRecordDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;

View File

@ -9,7 +9,6 @@ import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
@ -56,10 +55,11 @@ public class RotateCertificateJob extends BaseJob implements InjectableType {
@Override @Override
public void onRun() throws IOException { public void onRun() throws IOException {
synchronized (RotateCertificateJob.class) { // Loki - Do nothing
byte[] certificate = accountManager.getSenderCertificate(); // synchronized (RotateCertificateJob.class) {
TextSecurePreferences.setUnidentifiedAccessCertificate(context, certificate); // byte[] certificate = accountManager.getSenderCertificate();
} // TextSecurePreferences.setUnidentifiedAccessCertificate(context, certificate);
// }
} }
@Override @Override

View File

@ -7,11 +7,7 @@ import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.Database import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.redesign.utilities.get import org.thoughtcrime.securesms.loki.redesign.utilities.*
import org.thoughtcrime.securesms.loki.redesign.utilities.getInt
import org.thoughtcrime.securesms.loki.redesign.utilities.getLong
import org.thoughtcrime.securesms.loki.redesign.utilities.getString
import org.thoughtcrime.securesms.loki.redesign.utilities.insertOrUpdate
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.internal.util.JsonUtil import org.whispersystems.signalservice.internal.util.JsonUtil
@ -67,7 +63,6 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
override fun setFriendRequestStatus(threadID: Long, friendRequestStatus: LokiThreadFriendRequestStatus) { override fun setFriendRequestStatus(threadID: Long, friendRequestStatus: LokiThreadFriendRequestStatus) {
if (threadID < 0) { return } if (threadID < 0) { return }
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val contentValues = ContentValues(2) val contentValues = ContentValues(2)
contentValues.put(Companion.threadID, threadID) contentValues.put(Companion.threadID, threadID)
@ -152,7 +147,6 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
databaseHelper.writableDatabase.delete(publicChatTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) databaseHelper.writableDatabase.delete(publicChatTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() ))
} }
// region Session Restore
fun addSessionRestoreDevice(threadID: Long, hexEncodedPublicKey: String) { fun addSessionRestoreDevice(threadID: Long, hexEncodedPublicKey: String) {
val devices = getSessionRestoreDevices(threadID).toMutableSet() val devices = getSessionRestoreDevices(threadID).toMutableSet()
if (devices.add(hexEncodedPublicKey)) { if (devices.add(hexEncodedPublicKey)) {
@ -172,5 +166,4 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
TextSecurePreferences.setStringPreference(context, "session_restore_devices_$threadID", "") TextSecurePreferences.setStringPreference(context, "session_restore_devices_$threadID", "")
delegate?.handleSessionRestoreDevicesChanged(threadID) delegate?.handleSessionRestoreDevicesChanged(threadID)
} }
// endregion
} }

View File

@ -6,12 +6,10 @@ import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.all import nl.komponents.kovenant.all
import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.bind
import nl.komponents.kovenant.functional.map import nl.komponents.kovenant.functional.map
import nl.komponents.kovenant.then
import nl.komponents.kovenant.toFailVoid import nl.komponents.kovenant.toFailVoid
import nl.komponents.kovenant.ui.successUi import nl.komponents.kovenant.ui.successUi
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.crypto.PreKeyUtil
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil
import org.thoughtcrime.securesms.database.Address import org.thoughtcrime.securesms.database.Address
@ -20,14 +18,11 @@ import org.thoughtcrime.securesms.logging.Log
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.util.guava.Optional
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.loki.api.LokiStorageAPI import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.api.PairingAuthorisation import org.whispersystems.signalservice.loki.api.PairingAuthorisation
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
import org.whispersystems.signalservice.loki.utilities.Analytics
import org.whispersystems.signalservice.loki.utilities.recover import org.whispersystems.signalservice.loki.utilities.recover
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
import java.util.* import java.util.*
@ -44,7 +39,6 @@ fun checkForRevocation(context: Context) {
DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(ourDevice) DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(ourDevice)
LokiStorageAPI.shared.updateUserDeviceMappings() LokiStorageAPI.shared.updateUserDeviceMappings()
}.successUi { }.successUi {
Analytics.shared.track("Secondary Device Unlinked")
TextSecurePreferences.setNeedsRevocationCheck(context, false) TextSecurePreferences.setNeedsRevocationCheck(context, false)
ApplicationContext.getInstance(context).clearData() ApplicationContext.getInstance(context).clearData()
}.fail { error -> }.fail { error ->

View File

@ -15,7 +15,7 @@ import network.loki.messenger.R
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.devicelist.Device import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.DeviceListBottomSheetFragment import org.thoughtcrime.securesms.loki.redesign.views.DeviceEditingOptionsBottomSheet
import org.thoughtcrime.securesms.loki.redesign.dialogs.EditDeviceNameDialog import org.thoughtcrime.securesms.loki.redesign.dialogs.EditDeviceNameDialog
import org.thoughtcrime.securesms.loki.redesign.dialogs.EditDeviceNameDialogDelegate import org.thoughtcrime.securesms.loki.redesign.dialogs.EditDeviceNameDialogDelegate
import org.thoughtcrime.securesms.loki.redesign.dialogs.LinkDeviceMasterModeDialog import org.thoughtcrime.securesms.loki.redesign.dialogs.LinkDeviceMasterModeDialog
@ -104,7 +104,7 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager
} }
override fun onDeviceClick(device: Device) { override fun onDeviceClick(device: Device) {
val bottomSheet = DeviceListBottomSheetFragment() val bottomSheet = DeviceEditingOptionsBottomSheet()
bottomSheet.onEditTapped = { bottomSheet.onEditTapped = {
bottomSheet.dismiss() bottomSheet.dismiss()
val editDeviceNameDialog = EditDeviceNameDialog() val editDeviceNameDialog = EditDeviceNameDialog()

View File

@ -12,7 +12,7 @@ import network.loki.messenger.R
import org.thoughtcrime.securesms.qr.ScanListener import org.thoughtcrime.securesms.qr.ScanListener
import org.thoughtcrime.securesms.qr.ScanningThread import org.thoughtcrime.securesms.qr.ScanningThread
class ScanQRCodeFragmentV2 : Fragment() { class ScanQRCodeFragment : Fragment() {
private val scanningThread = ScanningThread() private val scanningThread = ScanningThread()
var scanListener: ScanListener? = null var scanListener: ScanListener? = null
set(value) { field = value; scanningThread.setScanListener(scanListener) } set(value) { field = value; scanningThread.setScanListener(scanListener) }

View File

@ -28,7 +28,7 @@ class ScanQRCodeWrapperFragment : Fragment(), ScanQRCodePlaceholderFragmentDeleg
private fun update() { private fun update() {
val fragment: Fragment val fragment: Fragment
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
val scanQRCodeFragment = ScanQRCodeFragmentV2() val scanQRCodeFragment = ScanQRCodeFragment()
scanQRCodeFragment.scanListener = this scanQRCodeFragment.scanListener = this
scanQRCodeFragment.message = message scanQRCodeFragment.message = message
fragment = scanQRCodeFragment fragment = scanQRCodeFragment

View File

@ -10,7 +10,6 @@ import org.thoughtcrime.securesms.service.PersistentAlarmManagerListener
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope
import org.whispersystems.signalservice.loki.api.LokiAPI import org.whispersystems.signalservice.loki.api.LokiAPI
import org.whispersystems.signalservice.loki.utilities.Analytics
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class BackgroundPollWorker : PersistentAlarmManagerListener() { class BackgroundPollWorker : PersistentAlarmManagerListener() {
@ -30,7 +29,6 @@ class BackgroundPollWorker : PersistentAlarmManagerListener() {
override fun onAlarm(context: Context, scheduledTime: Long): Long { override fun onAlarm(context: Context, scheduledTime: Long): Long {
if (scheduledTime != 0L) { if (scheduledTime != 0L) {
Analytics.shared.track("Performed Background Fetch")
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context) val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context)
try { try {

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.messaging
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
@ -88,7 +88,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
} }
string string
} }
val row = wrap(mapOf( Companion.hexEncodedPublicKey to hexEncodedPublicKey, swarm to swarmAsString )) val row = wrap(mapOf(Companion.hexEncodedPublicKey to hexEncodedPublicKey, swarm to swarmAsString))
database.insertOrUpdate(swarmCache, row, "${Companion.hexEncodedPublicKey} = ?", wrap(hexEncodedPublicKey)) database.insertOrUpdate(swarmCache, row, "${Companion.hexEncodedPublicKey} = ?", wrap(hexEncodedPublicKey))
} }
@ -101,7 +101,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
override fun setLastMessageHashValue(target: LokiAPITarget, newValue: String) { override fun setLastMessageHashValue(target: LokiAPITarget, newValue: String) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val row = wrap(mapOf( Companion.target to target.address, lastMessageHashValue to newValue )) val row = wrap(mapOf(Companion.target to target.address, lastMessageHashValue to newValue))
database.insertOrUpdate(lastMessageHashValueCache, row, "${Companion.target} = ?", wrap(target.address)) database.insertOrUpdate(lastMessageHashValueCache, row, "${Companion.target} = ?", wrap(target.address))
} }
@ -116,7 +116,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
override fun setReceivedMessageHashValues(newValue: Set<String>) { override fun setReceivedMessageHashValues(newValue: Set<String>) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val receivedMessageHashValuesAsString = newValue.joinToString(", ") val receivedMessageHashValuesAsString = newValue.joinToString(", ")
val row = wrap(mapOf( userID to userPublicKey, receivedMessageHashValues to receivedMessageHashValuesAsString )) val row = wrap(mapOf(userID to userPublicKey, receivedMessageHashValues to receivedMessageHashValuesAsString))
database.insertOrUpdate(receivedMessageHashValuesCache, row, "$userID = ?", wrap(userPublicKey)) database.insertOrUpdate(receivedMessageHashValuesCache, row, "$userID = ?", wrap(userPublicKey))
} }
@ -148,7 +148,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
override fun setLastMessageServerID(group: Long, server: String, newValue: Long) { override fun setLastMessageServerID(group: Long, server: String, newValue: Long) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val index = "$server.$group" val index = "$server.$group"
val row = wrap(mapOf( lastMessageServerIDCacheIndex to index, lastMessageServerID to newValue.toString() )) val row = wrap(mapOf(lastMessageServerIDCacheIndex to index, lastMessageServerID to newValue.toString()))
database.insertOrUpdate(lastMessageServerIDCache, row, "$lastMessageServerIDCacheIndex = ?", wrap(index)) database.insertOrUpdate(lastMessageServerIDCache, row, "$lastMessageServerIDCacheIndex = ?", wrap(index))
} }
@ -169,7 +169,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
override fun setLastDeletionServerID(group: Long, server: String, newValue: Long) { override fun setLastDeletionServerID(group: Long, server: String, newValue: Long) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val index = "$server.$group" val index = "$server.$group"
val row = wrap(mapOf( lastDeletionServerIDCacheIndex to index, lastDeletionServerID to newValue.toString() )) val row = wrap(mapOf(lastDeletionServerIDCacheIndex to index, lastDeletionServerID to newValue.toString()))
database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index)) database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index))
} }
@ -221,7 +221,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
override fun setUserCount(userCount: Int, group: Long, server: String) { override fun setUserCount(userCount: Int, group: Long, server: String) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val index = "$server.$group" val index = "$server.$group"
val row = wrap(mapOf( publicChatID to index, LokiAPIDatabase.userCount to userCount.toString() )) val row = wrap(mapOf(publicChatID to index, Companion.userCount to userCount.toString()))
database.insertOrUpdate(userCountCache, row, "$publicChatID = ?", wrap(index)) database.insertOrUpdate(userCountCache, row, "$publicChatID = ?", wrap(index))
} }
} }

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.messaging
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.messaging
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context

View File

@ -120,33 +120,33 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
val attachments = message.attachments.mapNotNull { attachment -> val attachments = message.attachments.mapNotNull { attachment ->
if (attachment.kind != LokiPublicChatMessage.Attachment.Kind.Attachment) { return@mapNotNull null } if (attachment.kind != LokiPublicChatMessage.Attachment.Kind.Attachment) { return@mapNotNull null }
SignalServiceAttachmentPointer( SignalServiceAttachmentPointer(
attachment.serverID, attachment.serverID,
attachment.contentType, attachment.contentType,
ByteArray(0), ByteArray(0),
Optional.of(attachment.size), Optional.of(attachment.size),
Optional.absent(), Optional.absent(),
attachment.width, attachment.height, attachment.width, attachment.height,
Optional.absent(), Optional.absent(),
Optional.of(attachment.fileName), Optional.of(attachment.fileName),
false, false,
Optional.fromNullable(attachment.caption), Optional.fromNullable(attachment.caption),
attachment.url) attachment.url)
} }
val linkPreview = message.attachments.firstOrNull { it.kind == LokiPublicChatMessage.Attachment.Kind.LinkPreview } val linkPreview = message.attachments.firstOrNull { it.kind == LokiPublicChatMessage.Attachment.Kind.LinkPreview }
val signalLinkPreviews = mutableListOf<SignalServiceDataMessage.Preview>() val signalLinkPreviews = mutableListOf<SignalServiceDataMessage.Preview>()
if (linkPreview != null) { if (linkPreview != null) {
val attachment = SignalServiceAttachmentPointer( val attachment = SignalServiceAttachmentPointer(
linkPreview.serverID, linkPreview.serverID,
linkPreview.contentType, linkPreview.contentType,
ByteArray(0), ByteArray(0),
Optional.of(linkPreview.size), Optional.of(linkPreview.size),
Optional.absent(), Optional.absent(),
linkPreview.width, linkPreview.height, linkPreview.width, linkPreview.height,
Optional.absent(), Optional.absent(),
Optional.of(linkPreview.fileName), Optional.of(linkPreview.fileName),
false, false,
Optional.fromNullable(linkPreview.caption), Optional.fromNullable(linkPreview.caption),
linkPreview.url) linkPreview.url)
signalLinkPreviews.add(SignalServiceDataMessage.Preview(linkPreview.linkPreviewURL!!, linkPreview.linkPreviewTitle!!, Optional.of(attachment))) signalLinkPreviews.add(SignalServiceDataMessage.Preview(linkPreview.linkPreviewURL!!, linkPreview.linkPreviewTitle!!, Optional.of(attachment)))
} }
val body = if (message.body == message.timestamp.toString()) "" else message.body // Workaround for the fact that the back-end doesn't accept messages without a body val body = if (message.body == message.timestamp.toString()) "" else message.body // Workaround for the fact that the back-end doesn't accept messages without a body
@ -161,7 +161,6 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})" val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})"
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName) DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName)
} }
val senderPublicKey = primaryDevice ?: message.hexEncodedPublicKey val senderPublicKey = primaryDevice ?: message.hexEncodedPublicKey
val serviceDataMessage = getDataMessage(message) val serviceDataMessage = getDataMessage(message)
val serviceContent = SignalServiceContent(serviceDataMessage, senderPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, false) val serviceContent = SignalServiceContent(serviceDataMessage, senderPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, false)
@ -170,7 +169,6 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
} else { } else {
PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
} }
// Update profile avatar if needed // Update profile avatar if needed
val senderRecipient = Recipient.from(context, Address.fromSerialized(senderPublicKey), false) val senderRecipient = Recipient.from(context, Address.fromSerialized(senderPublicKey), false)
if (message.avatar != null && message.avatar!!.url.isNotEmpty()) { if (message.avatar != null && message.avatar!!.url.isNotEmpty()) {
@ -204,8 +202,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
} else { } else {
PushDecryptJob(context).handleSynchronizeSentTextMessage(transcript) PushDecryptJob(context).handleSynchronizeSentTextMessage(transcript)
} }
// If we got a message from our master device then make sure our mappings stay in sync
// Loki - If we got a message from our master device then make sure our mappings stay in sync
val recipient = Recipient.from(context, Address.fromSerialized(message.hexEncodedPublicKey), false) val recipient = Recipient.from(context, Address.fromSerialized(message.hexEncodedPublicKey), false)
if (recipient.isOurMasterDevice && message.avatar != null) { if (recipient.isOurMasterDevice && message.avatar != null) {
val profileKey = message.avatar!!.profileKey val profileKey = message.avatar!!.profileKey

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.messaging
import android.content.Context import android.content.Context
import android.os.Handler import android.os.Handler

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.messaging
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
@ -18,7 +18,6 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
companion object { companion object {
// Shared // Shared
private val displayName = "display_name" private val displayName = "display_name"
private val profileAvatarUrl = "profile_avatar_url"
// Display name cache // Display name cache
private val displayNameTable = "loki_user_display_name_database" private val displayNameTable = "loki_user_display_name_database"
private val hexEncodedPublicKey = "hex_encoded_public_key" private val hexEncodedPublicKey = "hex_encoded_public_key"
@ -70,7 +69,7 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
} }
} }
override fun getProfileAvatarUrl(hexEncodedPublicKey: String): String? { override fun getProfilePictureURL(hexEncodedPublicKey: String): String? {
return if (hexEncodedPublicKey == TextSecurePreferences.getLocalNumber(context)) { return if (hexEncodedPublicKey == TextSecurePreferences.getLocalNumber(context)) {
TextSecurePreferences.getProfileAvatarUrl(context) TextSecurePreferences.getProfileAvatarUrl(context)
} else { } else {

View File

@ -53,7 +53,7 @@ class ConversationView : LinearLayout {
val randomUsers = users.sorted() // Sort to provide a level of stability val randomUsers = users.sorted() // Sort to provide a level of stability
profilePictureView.hexEncodedPublicKey = randomUsers.getOrNull(0) ?: "" profilePictureView.hexEncodedPublicKey = randomUsers.getOrNull(0) ?: ""
profilePictureView.additionalHexEncodedPublicKey = randomUsers.getOrNull(1) ?: "" profilePictureView.additionalHexEncodedPublicKey = randomUsers.getOrNull(1) ?: ""
profilePictureView.isRSSFeed = thread.recipient.name == "Loki News" || thread.recipient.name == "Loki Messenger Updates" profilePictureView.isRSSFeed = thread.recipient.name == "Loki News" || thread.recipient.name == "Session Updates"
} else { } else {
profilePictureView.hexEncodedPublicKey = thread.recipient.address.toString() profilePictureView.hexEncodedPublicKey = thread.recipient.address.toString()
profilePictureView.additionalHexEncodedPublicKey = null profilePictureView.additionalHexEncodedPublicKey = null

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.views
import android.os.Bundle import android.os.Bundle
import android.support.design.widget.BottomSheetDialogFragment import android.support.design.widget.BottomSheetDialogFragment
@ -8,7 +8,7 @@ import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_device_list_bottom_sheet.* import kotlinx.android.synthetic.main.fragment_device_list_bottom_sheet.*
import network.loki.messenger.R import network.loki.messenger.R
public class DeviceListBottomSheetFragment : BottomSheetDialogFragment() { public class DeviceEditingOptionsBottomSheet : BottomSheetDialogFragment() {
var onEditTapped: (() -> Unit)? = null var onEditTapped: (() -> Unit)? = null
var onUnlinkTapped: (() -> Unit)? = null var onUnlinkTapped: (() -> Unit)? = null

View File

@ -61,7 +61,7 @@ class ProfilePictureView : RelativeLayout {
glide.clear(imageView) glide.clear(imageView)
if (hexEncodedPublicKey.isNotEmpty()) { if (hexEncodedPublicKey.isNotEmpty()) {
val signalProfilePicture = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).contactPhoto val signalProfilePicture = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).contactPhoto
if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0") { if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0" && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "") {
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView) glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView)
} else { } else {
val size = resources.getDimensionPixelSize(sizeID) val size = resources.getDimensionPixelSize(sizeID)

View File

@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki.redesign.views
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet

View File

@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.loki.utilities.Analytics;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -127,12 +126,6 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean enabled = (Boolean)newValue; boolean enabled = (Boolean)newValue;
if (enabled) {
Analytics.Companion.getShared().track("Screen Lock Enabled");
} else {
Analytics.Companion.getShared().track("Screen Lock Disabled");
}
TextSecurePreferences.setScreenLockEnabled(getContext(), enabled); TextSecurePreferences.setScreenLockEnabled(getContext(), enabled);
Intent intent = new Intent(getContext(), KeyCachingService.class); Intent intent = new Intent(getContext(), KeyCachingService.class);
@ -203,12 +196,6 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean enabled = (boolean)newValue; boolean enabled = (boolean)newValue;
if (enabled) {
Analytics.Companion.getShared().track("Typing Indicators Enabled");
} else {
Analytics.Companion.getShared().track("Typing Indicators Disabled");
}
ApplicationContext.getInstance(getContext()) ApplicationContext.getInstance(getContext())
.getJobManager() .getJobManager()
.add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()), .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()),
@ -230,9 +217,22 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
boolean enabled = (boolean)newValue; boolean enabled = (boolean)newValue;
if (enabled) { if (enabled) {
Analytics.Companion.getShared().track("Link Previews Enabled"); AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
} else { builder.setTitle("Enable Link Previews?");
Analytics.Companion.getShared().track("Link Previews Disabled"); builder.setMessage("You will not have full metadata protection when sending or receiving link previews.");
builder.setPositiveButton("OK", (dialog, which) -> dialog.dismiss());
builder.setNegativeButton("Cancel", (dialog, which) -> {
TextSecurePreferences.setLinkPreviewsEnabled(requireContext(), false);
((SwitchPreferenceCompat)AppProtectionPreferenceFragment.this.findPreference(TextSecurePreferences.LINK_PREVIEWS)).setChecked(false);
ApplicationContext.getInstance(requireContext())
.getJobManager()
.add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()),
TextSecurePreferences.isTypingIndicatorsEnabled(requireContext()),
TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(requireContext()),
false));
dialog.dismiss();
});
builder.create().show();
} }
ApplicationContext.getInstance(requireContext()) ApplicationContext.getInstance(requireContext())

View File

@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.BaseActionBarActivity;
import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.loki.utilities.Analytics;
import network.loki.messenger.R; import network.loki.messenger.R;
@ -23,7 +22,6 @@ public class WelcomeActivity extends BaseActionBarActivity {
setContentView(R.layout.registration_welcome_activity); setContentView(R.layout.registration_welcome_activity);
findViewById(R.id.welcome_terms_button).setOnClickListener(v -> onTermsClicked()); findViewById(R.id.welcome_terms_button).setOnClickListener(v -> onTermsClicked());
findViewById(R.id.welcome_continue_button).setOnClickListener(v -> onContinueClicked()); findViewById(R.id.welcome_continue_button).setOnClickListener(v -> onContinueClicked());
Analytics.Companion.getShared().track("Landing Screen Viewed");
} }
@Override @Override

View File

@ -367,7 +367,11 @@ public class TextSecurePreferences {
} }
public static boolean isLinkPreviewsEnabled(Context context) { public static boolean isLinkPreviewsEnabled(Context context) {
return getBooleanPreference(context, LINK_PREVIEWS, true); return getBooleanPreference(context, LINK_PREVIEWS, false);
}
public static void setLinkPreviewsEnabled(Context context, boolean enabled) {
setBooleanPreference(context, LINK_PREVIEWS, enabled);
} }
public static boolean isGifSearchInGridLayout(Context context) { public static boolean isGifSearchInGridLayout(Context context) {