diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 165f1eb2df..7b88684d51 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -477,12 +477,12 @@ android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" /> + android:windowSoftInputMode="stateAlwaysVisible" + android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" /> + android:windowSoftInputMode="stateAlwaysVisible" + android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" /> diff --git a/captures/network.loki.messenger_2019.10.11_14.38.li b/captures/network.loki.messenger_2019.10.11_14.38.li deleted file mode 100644 index 8311920633..0000000000 Binary files a/captures/network.loki.messenger_2019.10.11_14.38.li and /dev/null differ diff --git a/res/layout/fragment_add_public_chat.xml b/res/layout/fragment_add_public_chat.xml index 8f677a5784..f6ad5a9887 100644 --- a/res/layout/fragment_add_public_chat.xml +++ b/res/layout/fragment_add_public_chat.xml @@ -13,12 +13,12 @@ android:orientation="vertical"> + app:labeledEditText_label="@string/fragment_add_public_chat_url_edit_text_label"/> + app:cpb_textIdle="@string/fragment_add_public_chat_add_button_title_1" /> diff --git a/res/values/strings.xml b/res/values/strings.xml index 5cd6bf7d23..3a1a2303d6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1575,7 +1575,6 @@ Copied to clipboard Share Public Key Show QR Code - Add Public Chat Link Device Show Seed Your Seed @@ -1601,13 +1600,12 @@ Please enter the public key of the person you\'d like to message Add Public Chat - Server URL - Enter the full URL of the public server. E.g https://public-server.url - Add - Adding Server... - Invalid Url provided - Failed to connect to server - Added public chat server + URL + Enter the URL of the public chat you\'d like to join. The Loki Public Chat URL is https://chat.lokinet.org. + Add + Adding Server... + Invalid URL + Couldn\'t Connect Accept Reject diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 2260f55718..21598d3421 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -41,13 +41,9 @@ android:title="@string/activity_settings_show_qr_code_button_title" android:icon="@drawable/icon_qr_code"/> - - + android:title="@string/activity_settings_link_device_button_title" + android:icon="@drawable/icon_link"/> groupChatServers = DatabaseFactory.getLokiThreadDatabase(context).getAllPublicChatServers(); for (String server : groupChatServers) { - chatAPI.setDisplayName(name, server); + publicChatAPI.setDisplayName(name, server); } } diff --git a/src/org/thoughtcrime/securesms/components/QuoteView.java b/src/org/thoughtcrime/securesms/components/QuoteView.java index f868c56082..1c2c705197 100644 --- a/src/org/thoughtcrime/securesms/components/QuoteView.java +++ b/src/org/thoughtcrime/securesms/components/QuoteView.java @@ -197,9 +197,9 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener // If we're in a group then try and use the display name in the group if (conversationRecipient.isGroupRecipient()) { long threadId = DatabaseFactory.getThreadDatabase(getContext()).getThreadIdFor(conversationRecipient); - LokiPublicChat chat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); - if (chat != null) { - String senderDisplayName = DatabaseFactory.getLokiUserDatabase(getContext()).getServerDisplayName(chat.getId(), author.getAddress().serialize()); + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + if (publicChat != null) { + String senderDisplayName = DatabaseFactory.getLokiUserDatabase(getContext()).getServerDisplayName(publicChat.getId(), author.getAddress().serialize()); if (senderDisplayName != null) { quoteeDisplayName = senderDisplayName; } } } diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 0e2835ed2f..87b03e5118 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -406,14 +406,14 @@ public class ConversationFragment extends Fragment boolean isGroupChat = recipient.isGroupRecipient(); if (isGroupChat) { - LokiPublicChat groupChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); - boolean isPublicChat = groupChat != null; + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + boolean isPublicChat = publicChat != null; int selectedMessageCount = messageRecords.size(); boolean isSentByUser = ((MessageRecord)messageRecords.toArray()[0]).isOutgoing(); menu.findItem(R.id.menu_context_copy_public_key).setVisible(isPublicChat && selectedMessageCount == 1 && !isSentByUser); menu.findItem(R.id.menu_context_reply).setVisible(isPublicChat && selectedMessageCount == 1); String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext()); - boolean userCanModerate = groupChat != null && LokiPublicChatAPI.Companion.isUserModerator(userHexEncodedPublicKey, groupChat.getChannel(), groupChat.getServer()); + boolean userCanModerate = isPublicChat && LokiPublicChatAPI.Companion.isUserModerator(userHexEncodedPublicKey, publicChat.getChannel(), publicChat.getServer()); boolean isDeleteOptionVisible = isPublicChat && selectedMessageCount == 1 && (isSentByUser || userCanModerate); menu.findItem(R.id.menu_context_delete_message).setVisible(isDeleteOptionVisible); } else { @@ -508,8 +508,8 @@ public class ConversationFragment extends Fragment builder.setMessage(getActivity().getResources().getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messagesCount, messagesCount)); builder.setCancelable(true); - // Loki - The delete option is only visible to the user in a group chat - LokiPublicChat groupChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + // Loki - The delete option is only visible to the user in a public chat + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() { @Override @@ -523,16 +523,16 @@ public class ConversationFragment extends Fragment for (MessageRecord messageRecord : messageRecords) { boolean isThreadDeleted; - if (groupChat != null) { + if (publicChat != null) { final SettableFuture[] future = { new SettableFuture() }; - LokiPublicChatAPI chatAPI = ApplicationContext.getInstance(getContext()).getLokiPublicChatAPI(); + LokiPublicChatAPI publicChatAPI = ApplicationContext.getInstance(getContext()).getLokiPublicChatAPI(); boolean isSentByUser = messageRecord.isOutgoing(); Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id); - if (chatAPI != null && serverID != null) { - chatAPI - .deleteMessage(serverID, groupChat.getChannel(), groupChat.getServer(), isSentByUser) + if (publicChatAPI != null && serverID != null) { + publicChatAPI + .deleteMessage(serverID, publicChat.getChannel(), publicChat.getServer(), isSentByUser) .success(l -> { @SuppressWarnings("unchecked") SettableFuture f = (SettableFuture) future[0]; f.set(Unit.INSTANCE); diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationItem.java b/src/org/thoughtcrime/securesms/conversation/ConversationItem.java index bedeb16cfe..57fbe13391 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -939,10 +939,9 @@ public class ConversationItem extends LinearLayout contactPhoto.setVisibility(VISIBLE); int visibility = View.GONE; - // If we have a chat then use that to determine mod status - LokiPublicChat groupChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(messageRecord.getThreadId()); - if (groupChat != null) { - boolean isModerator = LokiPublicChatAPI.Companion.isUserModerator(current.getRecipient().getAddress().toString(), groupChat.getChannel(), groupChat.getServer()); + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(messageRecord.getThreadId()); + if (publicChat != null) { + boolean isModerator = LokiPublicChatAPI.Companion.isUserModerator(current.getRecipient().getAddress().toString(), publicChat.getChannel(), publicChat.getServer()); visibility = isModerator ? View.VISIBLE : View.GONE; } diff --git a/src/org/thoughtcrime/securesms/database/Address.java b/src/org/thoughtcrime/securesms/database/Address.java index 40d8a2ebd5..ed20c6fbbb 100644 --- a/src/org/thoughtcrime/securesms/database/Address.java +++ b/src/org/thoughtcrime/securesms/database/Address.java @@ -52,7 +52,7 @@ public class Address implements Parcelable, Comparable
{ private final String address; - // Loki - Special flag to indicate whether this address is meant to representing a public chat or not + // Loki - Special flag to indicate whether this address represents a public chat or not private Boolean isPublicChat; private Address(@NonNull String address) { diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 2f798fe3ee..be4dd9ed4e 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -287,12 +287,12 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType { private @NonNull List
getGroupMessageRecipients(String groupId, long messageId) { ArrayList
result = new ArrayList<>(); - // Loki - All group messages should be directed to their servers + // Loki - All group messages should be directed to their respective servers long threadID = GroupManager.getThreadIdFromGroupId(groupId, context); - LokiPublicChat chat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID); - if (chat != null) { + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID); + if (publicChat != null) { // We need to somehow maintain information that will allow the sender to map - // a Recipient to the correct public chat thread, and so this might be a bit hacky + // a recipient to the correct public chat thread, and so this might be a bit hacky result.add(Address.fromPublicChatGroupID(groupId)); } diff --git a/src/org/thoughtcrime/securesms/loki/AddPublicChatActivity.kt b/src/org/thoughtcrime/securesms/loki/AddPublicChatActivity.kt index 9e034f32bc..bab0f78c97 100644 --- a/src/org/thoughtcrime/securesms/loki/AddPublicChatActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/AddPublicChatActivity.kt @@ -44,26 +44,25 @@ class AddPublicChatActivity : PassphraseRequiredActionBarActivity() { private fun addPublicChatIfPossible() { val inputMethodManager = getSystemService(BaseActionBarActivity.INPUT_METHOD_SERVICE) as InputMethodManager - inputMethodManager.hideSoftInputFromWindow(serverUrlEditText.windowToken, 0) + inputMethodManager.hideSoftInputFromWindow(urlEditText.windowToken, 0) - val url = serverUrlEditText.text.toString().toLowerCase().replace("http://", "https://") + val url = urlEditText.text.toString().toLowerCase().replace("http://", "https://") if (!Patterns.WEB_URL.matcher(url).matches() || !url.startsWith("https://")) { return Toast.makeText(this, R.string.fragment_add_public_chat_invalid_url_message, Toast.LENGTH_SHORT).show() } setButtonEnabled(false) ApplicationContext.getInstance(this).lokiPublicChatManager.addChat(url, 1).successUi { - Toast.makeText(this, R.string.fragment_add_public_chat_success_message, Toast.LENGTH_SHORT).show() finish() }.failUi { setButtonEnabled(true) - Toast.makeText(this, R.string.fragment_add_public_chat_failed_connect_message, Toast.LENGTH_SHORT).show() + Toast.makeText(this, R.string.fragment_add_public_chat_connection_failed_message, Toast.LENGTH_SHORT).show() } } private fun setButtonEnabled(enabled: Boolean) { addButton.isEnabled = enabled - val text = if (enabled) R.string.fragment_add_public_chat_add_button_title else R.string.fragment_add_public_chat_adding_server_button_title + val text = if (enabled) R.string.fragment_add_public_chat_add_button_title_1 else R.string.fragment_add_public_chat_add_button_title_2 addButton.setText(text) - serverUrlEditText.isEnabled = enabled + urlEditText.isEnabled = enabled } } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/DisplayNameActivity.kt b/src/org/thoughtcrime/securesms/loki/DisplayNameActivity.kt index 18bc717ba4..31d31a611e 100644 --- a/src/org/thoughtcrime/securesms/loki/DisplayNameActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/DisplayNameActivity.kt @@ -43,11 +43,10 @@ class DisplayNameActivity : BaseActionBarActivity() { application.setUpStorageAPIIfNeeded() startActivity(Intent(this, ConversationListActivity::class.java)) finish() - - val chatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI - if (chatAPI != null && name != null) { + val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI + if (publicChatAPI != null) { val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers() - servers.forEach { chatAPI.setDisplayName(name, it) } + servers.forEach { publicChatAPI.setDisplayName(name, it) } } } } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/GeneralUtilities.kt b/src/org/thoughtcrime/securesms/loki/GeneralUtilities.kt index 6da575b9ce..856b038b9a 100644 --- a/src/org/thoughtcrime/securesms/loki/GeneralUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/GeneralUtilities.kt @@ -23,7 +23,7 @@ fun toPx(dp: Int, resources: Resources): Int { return (dp * scale).roundToInt() } -fun isGroupRecipient(context: Context, recipient: String): Boolean { +fun isPublicChat(context: Context, recipient: String): Boolean { return DatabaseFactory.getLokiThreadDatabase(context).getAllPublicChats().values.map { it.server }.contains(recipient) } diff --git a/src/org/thoughtcrime/securesms/loki/LokiPublicChatManager.kt b/src/org/thoughtcrime/securesms/loki/LokiPublicChatManager.kt index b8ae58f0bb..01da3532ad 100644 --- a/src/org/thoughtcrime/securesms/loki/LokiPublicChatManager.kt +++ b/src/org/thoughtcrime/securesms/loki/LokiPublicChatManager.kt @@ -59,7 +59,7 @@ class LokiPublicChatManager(private val context: Context) { // Set our name on the server val displayName = TextSecurePreferences.getProfileName(context) if (!TextUtils.isEmpty(displayName)) { - ApplicationContext.getInstance(context).lokiPublicChatAPI?.setDisplayName(server, displayName) + ApplicationContext.getInstance(context).lokiPublicChatAPI?.setDisplayName(displayName, server) } // Start polling Util.runOnMain{ startPollersIfNeeded() } diff --git a/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt b/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt index b7e604a587..931241168d 100644 --- a/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt @@ -20,14 +20,14 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa companion object { private val friendRequestTableName = "loki_thread_friend_request_database" private val sessionResetTableName = "loki_thread_session_reset_database" - public val groupChatMappingTableName = "loki_group_chat_mapping_database" + public val publicChatTableName = "loki_public_chat_database" public val threadID = "thread_id" private val friendRequestStatus = "friend_request_status" private val sessionResetStatus = "session_reset_status" - public val groupChatJSON = "group_chat_json" + public val publicChat = "public_chat" @JvmStatic val createFriendRequestTableCommand = "CREATE TABLE $friendRequestTableName ($threadID INTEGER PRIMARY KEY, $friendRequestStatus INTEGER DEFAULT 0);" @JvmStatic val createSessionResetTableCommand = "CREATE TABLE $sessionResetTableName ($threadID INTEGER PRIMARY KEY, $sessionResetStatus INTEGER DEFAULT 0);" - @JvmStatic val createGroupChatMappingTableCommand = "CREATE TABLE $groupChatMappingTableName ($threadID INTEGER PRIMARY KEY, $groupChatJSON TEXT);" + @JvmStatic val createGroupChatMappingTableCommand = "CREATE TABLE $publicChatTableName ($threadID INTEGER PRIMARY KEY, $publicChat TEXT);" } override fun getThreadID(hexEncodedPublicKey: String): Long { @@ -94,50 +94,46 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa fun getAllPublicChats(): Map { val database = databaseHelper.readableDatabase var cursor: Cursor? = null - + val result = mutableMapOf() try { - val map = mutableMapOf() - cursor = database.rawQuery("select * from $groupChatMappingTableName", null) + cursor = database.rawQuery("select * from $publicChatTableName", null) while (cursor != null && cursor.moveToNext()) { - val threadID = cursor.getLong(Companion.threadID) - val string = cursor.getString(groupChatJSON) - val chat = LokiPublicChat.fromJSON(string) - if (chat != null) { map[threadID] = chat } + val threadID = cursor.getLong(threadID) + val string = cursor.getString(publicChat) + val publicChat = LokiPublicChat.fromJSON(string) + if (publicChat != null) { result[threadID] = publicChat } } - return map } catch (e: Exception) { - + // Do nothing } finally { cursor?.close() } - - return mapOf() + return result } fun getAllPublicChatServers(): Set { - return getAllPublicChats().values.fold(setOf()) { set, chat -> set.plus(chat.server) } + return getAllPublicChats().values.fold(setOf()) { set, chat -> set.plus(chat.server) } } override fun getPublicChat(threadID: Long): LokiPublicChat? { if (threadID < 0) { return null } val database = databaseHelper.readableDatabase - return database.get(groupChatMappingTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor -> - val string = cursor.getString(groupChatJSON) - LokiPublicChat.fromJSON(string) + return database.get(publicChatTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor -> + val publicChatAsJSON = cursor.getString(publicChat) + LokiPublicChat.fromJSON(publicChatAsJSON) } } - override fun setPublicChat(groupChat: LokiPublicChat, threadID: Long) { + override fun setPublicChat(publicChat: LokiPublicChat, threadID: Long) { if (threadID < 0) { return } - val database = databaseHelper.writableDatabase val contentValues = ContentValues(2) contentValues.put(Companion.threadID, threadID) - contentValues.put(Companion.groupChatJSON, JsonUtil.toJson(groupChat.toJSON())) - database.insertOrUpdate(groupChatMappingTableName, contentValues, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) + contentValues.put(Companion.publicChat, JsonUtil.toJson(publicChat.toJSON())) + database.insertOrUpdate(publicChatTableName, contentValues, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) } override fun removePublicChat(threadID: Long) { - databaseHelper.writableDatabase.delete(groupChatMappingTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) + databaseHelper.writableDatabase.delete(publicChatTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) } } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 6676dfcf5f..d6cb29279d 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -213,7 +213,7 @@ public class MessageSender { // Just send the message normally if it's a group message String recipientPublicKey = recipient.getAddress().serialize(); - if (GeneralUtilitiesKt.isGroupRecipient(context, recipientPublicKey)) { + if (GeneralUtilitiesKt.isPublicChat(context, recipientPublicKey)) { jobManager.add(new PushTextSendJob(messageId, recipient.getAddress())); return; } @@ -243,7 +243,7 @@ public class MessageSender { // Just send the message normally if it's a group message String recipientPublicKey = recipient.getAddress().serialize(); - if (GeneralUtilitiesKt.isGroupRecipient(context, recipientPublicKey)) { + if (GeneralUtilitiesKt.isPublicChat(context, recipientPublicKey)) { PushMediaSendJob.enqueue(context, jobManager, messageId, recipient.getAddress()); return; }