diff --git a/meshchatx/src/frontend/components/NotificationBell.vue b/meshchatx/src/frontend/components/NotificationBell.vue index 8800479..7c93386 100644 --- a/meshchatx/src/frontend/components/NotificationBell.vue +++ b/meshchatx/src/frontend/components/NotificationBell.vue @@ -319,9 +319,12 @@ export default { }, async onWebsocketMessage(message) { const json = JSON.parse(message.data); - if (json.type === "lxmf.delivery") { + if ( + json.type === "lxmf.delivery" || + json.type === "telephone_missed_call" || + json.type === "new_voicemail" + ) { await this.loadNotifications(); - // If dropdown is open, mark new notifications as viewed if (this.isDropdownOpen) { await this.markNotificationsAsViewed(); } diff --git a/meshchatx/src/frontend/components/call/CallPage.vue b/meshchatx/src/frontend/components/call/CallPage.vue index 8c108fd..b72e122 100644 --- a/meshchatx/src/frontend/components/call/CallPage.vue +++ b/meshchatx/src/frontend/components/call/CallPage.vue @@ -777,6 +777,17 @@ > + + + + +
+
+ + +
b.destination_hash === this.selectedPeer.destination_hash ); }, + onContactUpdatedForBanner(data) { + if (this.selectedPeer?.destination_hash === data?.remote_identity_hash) { + this.isStrangerPeer = false; + this.strangerBannerDismissed = true; + } + }, + async checkIfStrangerPeer() { + if (!this.selectedPeer) { + this.isStrangerPeer = false; + return; + } + if (this.selectedPeer.is_contact || this.selectedPeer.contact_image) { + this.isStrangerPeer = false; + return; + } + try { + const response = await window.axios.get( + `/api/v1/telephone/contacts/check/${this.selectedPeer.destination_hash}` + ); + this.isStrangerPeer = !response.data.is_contact; + } catch { + this.isStrangerPeer = !this.selectedPeer.is_contact && !this.selectedPeer.contact_image; + } + }, + async addStrangerAsContact() { + if (!this.selectedPeer) return; + try { + const displayName = + this.selectedPeer.custom_display_name ?? this.selectedPeer.display_name ?? "Unknown"; + await fetch(`/api/v1/telephone/contacts`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + remote_identity_hash: this.selectedPeer.destination_hash, + lxmf_address: this.selectedPeer.destination_hash, + name: displayName, + }), + }); + this.isStrangerPeer = false; + this.strangerBannerDismissed = true; + GlobalEmitter.emit("contact-updated", { + remote_identity_hash: this.selectedPeer.destination_hash, + }); + this.$emit("reload-conversations"); + } catch (e) { + console.error("Failed to add contact:", e); + } + }, loadDraft(destinationHash) { try { const drafts = JSON.parse(localStorage.getItem("meshchat.drafts") || "{}"); diff --git a/meshchatx/src/frontend/components/settings/SettingsPage.vue b/meshchatx/src/frontend/components/settings/SettingsPage.vue index 655189b..63981c6 100644 --- a/meshchatx/src/frontend/components/settings/SettingsPage.vue +++ b/meshchatx/src/frontend/components/settings/SettingsPage.vue @@ -142,6 +142,49 @@
+
+
+
+
Security
+

{{ $t("app.stranger_protection") }}

+

{{ $t("app.stranger_protection_description") }}

+
+
+
+ + +
+
+