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 @@ > + + + @@ -84,6 +84,24 @@ {{ contact.lxmf_address || contact.remote_identity_hash }} + + + + + + + + + + + {{ $t("contacts.send_message") }} + + + + {{ $t("contacts.call_contact") }} + + {{ $t("contacts.share_contact") }} @@ -122,6 +149,7 @@ {{ $t("contacts.copy_contact_uri") }} + + + + + + + + {{ $t("messages.stranger_banner_text") }} + + + {{ $t("messages.add_to_contacts") }} + + + {{ $t("messages.dismiss") }} + + + 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") }} + + + + + + + {{ + $t("app.block_stranger_attachments") + }} + {{ + $t("app.block_stranger_attachments_description") + }} + + + + + + {{ $t("app.block_all_from_strangers") }} + {{ + $t("app.block_all_from_strangers_description") + }} + + + + +
{{ $t("app.stranger_protection_description") }}