diff --git a/Linphone/Assets.xcassets/lock-simple-bold.imageset/Contents.json b/Linphone/Assets.xcassets/lock-simple-bold.imageset/Contents.json
new file mode 100644
index 000000000..9040ecedb
--- /dev/null
+++ b/Linphone/Assets.xcassets/lock-simple-bold.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "lock-simple-bold.svg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Linphone/Assets.xcassets/lock-simple-bold.imageset/lock-simple-bold.svg b/Linphone/Assets.xcassets/lock-simple-bold.imageset/lock-simple-bold.svg
new file mode 100644
index 000000000..f8e860b57
--- /dev/null
+++ b/Linphone/Assets.xcassets/lock-simple-bold.imageset/lock-simple-bold.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Linphone/Assets.xcassets/lock-simple.imageset/Contents.json b/Linphone/Assets.xcassets/lock-simple.imageset/Contents.json
new file mode 100644
index 000000000..aefae6c90
--- /dev/null
+++ b/Linphone/Assets.xcassets/lock-simple.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "lock-simple.svg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Linphone/Assets.xcassets/lock-simple.imageset/lock-simple.svg b/Linphone/Assets.xcassets/lock-simple.imageset/lock-simple.svg
new file mode 100644
index 000000000..0fc6a8a6e
--- /dev/null
+++ b/Linphone/Assets.xcassets/lock-simple.imageset/lock-simple.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Linphone/Localizable/cs.lproj/Localizable.strings b/Linphone/Localizable/cs.lproj/Localizable.strings
index 74bc592e1..d4791882d 100644
--- a/Linphone/Localizable/cs.lproj/Localizable.strings
+++ b/Linphone/Localizable/cs.lproj/Localizable.strings
@@ -414,6 +414,8 @@
"conversation_composing_label_multiple" = "%@ píšou…";
"conversation_composing_label_single" = "%@ píše…";
"conversation_end_to_end_encrypted_bottom_sheet_link" = "https://linphone.org/en/features/#security";
+"conversation_end_to_end_encrypted_event_title" = "Koncově šifrovaná konverzace";
+"conversation_end_to_end_encrypted_event_subtitle" = "Zprávy v této konverzaci jsou koncově šifrovány. Dešifrovat je může pouze váš protějšek.";
"conversation_event_device_added" = "Nové zařízení pro %@";
"conversation_event_participant_added" = "%@ se připojil";
"conversation_event_subject_changed" = "Nový předmět: %@";
diff --git a/Linphone/Localizable/en.lproj/Localizable.strings b/Linphone/Localizable/en.lproj/Localizable.strings
index a02ce5436..427023c6c 100644
--- a/Linphone/Localizable/en.lproj/Localizable.strings
+++ b/Linphone/Localizable/en.lproj/Localizable.strings
@@ -201,6 +201,8 @@
"conversation_dialog_set_subject" = "Set conversation subject";
"conversation_dialog_subject_hint" = "Conversation subject";
"conversation_end_to_end_encrypted_bottom_sheet_link" = "https://linphone.org/en/features/#security";
+"conversation_end_to_end_encrypted_event_title" = "End-to-end encrypted conversation";
+"conversation_end_to_end_encrypted_event_subtitle" = "Messages in this conversation are e2e encrypted. Only your correspondent can decrypt them.";
"conversation_ephemeral_messages_duration_disabled" = "Disabled";
"conversation_ephemeral_messages_duration_multiple_days" = "%d days";
"conversation_ephemeral_messages_duration_one_day" = "1 day";
diff --git a/Linphone/Localizable/fr.lproj/Localizable.strings b/Linphone/Localizable/fr.lproj/Localizable.strings
index 23be93da6..6aaf80373 100644
--- a/Linphone/Localizable/fr.lproj/Localizable.strings
+++ b/Linphone/Localizable/fr.lproj/Localizable.strings
@@ -201,6 +201,8 @@
"conversation_dialog_set_subject" = "Nommer la conversation";
"conversation_dialog_subject_hint" = "Nom de la conversation";
"conversation_end_to_end_encrypted_bottom_sheet_link" = "https://linphone.org/en/features/#security";
+"conversation_end_to_end_encrypted_event_title" = "Conversation chiffrée de bout en bout";
+"conversation_end_to_end_encrypted_event_subtitle" = "Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer.";
"conversation_ephemeral_messages_duration_disabled" = "Désactiver";
"conversation_ephemeral_messages_duration_multiple_days" = "%d jours";
"conversation_ephemeral_messages_duration_one_day" = "1 jour";
diff --git a/Linphone/Localizable/uk.lproj/Localizable.strings b/Linphone/Localizable/uk.lproj/Localizable.strings
index 0e3c0e468..505429ed9 100644
--- a/Linphone/Localizable/uk.lproj/Localizable.strings
+++ b/Linphone/Localizable/uk.lproj/Localizable.strings
@@ -424,6 +424,8 @@
"conversation_composing_label_multiple" = "%@ скомпоновано…";
"conversation_composing_label_single" = "%@ скомпоновано…";
"conversation_end_to_end_encrypted_bottom_sheet_link" = "https://linphone.org/en/features/#security";
+"conversation_end_to_end_encrypted_event_title" = "Наскрізне шифрування розмови";
+"conversation_end_to_end_encrypted_event_subtitle" = "Повідомлення в цій розмові зашифровані за методом електронного шифрування (e2e). Розшифрувати їх може лише ваш співрозмовник.";
"conversation_event_admin_set" = "%@ є адміном";
"conversation_event_admin_unset" = "%@ більше не є адміном";
"conversation_event_ephemeral_messages_lifetime_changed" = "Термін дії тимчасових повідомлень тепер %@";
diff --git a/Linphone/UI/Main/Conversations/Fragments/UIList.swift b/Linphone/UI/Main/Conversations/Fragments/UIList.swift
index 7179f78a8..8b168a1f2 100644
--- a/Linphone/UI/Main/Conversations/Fragments/UIList.swift
+++ b/Linphone/UI/Main/Conversations/Fragments/UIList.swift
@@ -135,6 +135,13 @@ struct UIList: UIViewRepresentable {
tableView.backgroundColor = UIColor(.white)
tableView.scrollsToTop = true
+ if SharedMainViewModel.shared.displayedConversation != nil && SharedMainViewModel.shared.displayedConversation!.encryptionEnabled {
+ let footerView = Self.makeFooterView()
+ footerView.frame = CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 120)
+ footerView.transform = CGAffineTransformMakeScale(1, -1)
+ tableView.tableFooterView = footerView
+ }
+
// Create the floating UIButton
let button = FloatingButton(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
button.translatesAutoresizingMaskIntoConstraints = false
@@ -172,6 +179,47 @@ struct UIList: UIViewRepresentable {
return containerView
}
+ static func makeFooterView() -> UIView {
+ let host = UIHostingController(
+ rootView:
+ VStack {
+ HStack {
+ Image("lock-simple-bold")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.blueInfo500)
+ .frame(width: 25, height: 25)
+ .padding(10)
+
+ VStack(spacing: 5) {
+ Text("conversation_end_to_end_encrypted_event_title")
+ .foregroundStyle(Color.blueInfo500)
+ .default_text_style_700(styleSize: 14)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .multilineTextAlignment(.leading)
+
+ Text("conversation_end_to_end_encrypted_event_subtitle")
+ .foregroundStyle(Color.gray400)
+ .default_text_style(styleSize: 12)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .multilineTextAlignment(.leading)
+ }
+ }
+ .padding(10)
+ .cornerRadius(10)
+ .overlay(
+ RoundedRectangle(cornerRadius: 10)
+ .inset(by: 0.5)
+ .stroke(Color.blueInfo500, lineWidth: 0.5)
+ )
+ .padding(10)
+ }
+ .frame(height: 120)
+ )
+ host.view.backgroundColor = .clear
+ return host.view
+ }
+
// func updateUIView(_ tableView: UITableView, context: Context) {
func updateUIView(_ uiView: UIView, context: Context) {
if let button = uiView.viewWithTag(102) as? FloatingButton {
@@ -422,10 +470,11 @@ struct UIList: UIViewRepresentable {
}
func progressView(_ section: Int) -> UIView? {
- if section > parent.conversationViewModel.conversationMessagesSection.count
+ if section < parent.conversationViewModel.conversationMessagesSection.count
&& parent.conversationViewModel.conversationMessagesSection[section].rows.count < parent.conversationViewModel.displayedConversationHistorySize {
let header = UIHostingController(rootView:
ProgressView()
+ .frame(height: 50)
.frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .center)
).view
header?.backgroundColor = UIColor(.white)
@@ -516,6 +565,18 @@ struct UIList: UIViewRepresentable {
return configuration
}
+
+ func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
+ if section == tableView.numberOfSections - 1 {
+ let contentHeight = tableView.contentSize.height
+ let tableHeight = tableView.frame.height
+ let progressViewDisplayed = section < parent.conversationViewModel.conversationMessagesSection.count
+ && parent.conversationViewModel.conversationMessagesSection[section].rows.count < parent.conversationViewModel.displayedConversationHistorySize
+ let extraSpace = max(progressViewDisplayed ? 50 : 0, tableHeight - contentHeight - 20)
+ return extraSpace
+ }
+ return 0
+ }
}
}