diff --git a/applications/armored-chat/README.md b/applications/armored-chat/README.md deleted file mode 100644 index d067f71..0000000 --- a/applications/armored-chat/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Armored Chat - -Armored Chat is a light-weight chat application that allows members of a world to communicate with text. - -## Features - -- (wip) E2EE Direct messages -- (wip) Group chats - -- (?) Message signing - -## Encryption - -TODO: - -- Key exchange -- When and where -- How - -## Group chats - -TODO: - -- How -- Limitations diff --git a/applications/armored-chat/armored_chat.js b/applications/armored-chat/armored_chat.js deleted file mode 100644 index 888eb09..0000000 --- a/applications/armored-chat/armored_chat.js +++ /dev/null @@ -1,258 +0,0 @@ -// -// armored_chat.js -// -// Created by Armored Dragon, 2024. -// Copyright 2024 Overte e.V. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -(function () { - "use strict"; - // TODO: Encryption + PMs - // TODO: Open in external web browser - - var app_is_visible = false; - var settings = { - max_history: 250, - compact_chat: false, - external_window: false, - }; - var app_data = { current_page: "domain" }; - // Global vars - var ac_tablet; - var chat_overlay_window; - var app_button; - const channels = ["domain", "local", "system"]; - var max_local_distance = 20; // Maximum range for the local chat - var message_history = Settings.getValue("ArmoredChat-Messages", []); - - startup(); - - function startup() { - ac_tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - - app_button = ac_tablet.addButton({ - icon: Script.resolvePath("./img/icon_white.png"), - activeIcon: Script.resolvePath("./img/icon_black.png"), - text: "CHAT", - isActive: app_is_visible, - }); - - // When script ends, remove itself from tablet - Script.scriptEnding.connect(function () { - console.log("Shutting Down"); - ac_tablet.removeButton(app_button); - chat_overlay_window.close(); - }); - - // Overlay button toggle - app_button.clicked.connect(toggleMainChatWindow); - - _openWindow(); - } - function toggleMainChatWindow() { - app_is_visible = !app_is_visible; - console.log(`App is now ${app_is_visible ? "visible" : "hidden"}`); - app_button.editProperties({ isActive: app_is_visible }); - chat_overlay_window.visible = app_is_visible; - - // External window was closed; the window does not exist anymore - if (chat_overlay_window.title == "" && app_is_visible) { - _openWindow(); - } - } - function _openWindow() { - chat_overlay_window = new Desktop.createWindow(Script.resourcesPath() + "qml/hifi/tablet/DynamicWebview.qml", { - title: "Chat", - size: { x: 550, y: 400 }, - additionalFlags: Desktop.ALWAYS_ON_TOP, - visible: app_is_visible, // FIXME Invalid? - presentationMode: Desktop.PresentationMode.VIRTUAL, - }); - - chat_overlay_window.closed.connect(toggleMainChatWindow); - chat_overlay_window.sendToQml({ url: Script.resolvePath("./index.html") }); - chat_overlay_window.webEventReceived.connect(onWebEventReceived); - } - - // Initialize default message subscriptions - Messages.subscribe("chat"); - // Messages.subscribe("system"); - - Messages.messageReceived.connect(receivedMessage); - - function receivedMessage(channel, message) { - channel = channel.toLowerCase(); - if (channel !== "chat") return; - - console.log(`Received message:\n${message}`); - var message = JSON.parse(message); - - message.channel = message.channel.toLowerCase(); - - // For now, while we are working on superseding Floof, we will allow compatibility with it. - // If for_app exists, it came from us and we are just sending the message so Floof can read it. - // We don't need to listen to this message. - if (message.for_app) return; - - // Check the channel is valid - if (!channels.includes(message.channel)) return; - - // If message is local, and if player is too far away from location, don't do anything - if (channel === "local" && Vec3.distance(MyAvatar.position, message.position) < max_local_distance) return; - - // NOTE: Floof chat compatibility. - message.type = "show_message"; - - // Update web view of to new message - _emitEvent({ type: "show_message", ...message }); - - // Save message to our history - let saved_message = message; - delete saved_message.position; - - saved_message.timeString = new Date().toLocaleTimeString(undefined, { hour12: false }); - saved_message.dateString = new Date().toLocaleDateString(undefined, { - month: "long", - day: "numeric", - }); - message_history.push(saved_message); - if (message_history.length > settings.max_history) message_history.shift(); - Settings.setValue("ArmoredChat-Messages", message_history); - - // Display on popup chat area - _overlayMessage({ sender: message.displayName, message: message }); - } - function onWebEventReceived(event) { - console.log(`New web event:\n${event}`); - // FIXME: Lazy! - // Checks to see if the event is a JSON object - if (!event.includes("{")) return; - - var parsed = JSON.parse(event); - - switch (parsed.type) { - case "page_update": - app_data.current_page = parsed.page; - break; - - case "send_message": - _sendMessage(parsed.message); - break; - - case "open_url": - new OverlayWebWindow({ source: parsed.url.toString(), width: 500, height: 400 }); - break; - - case "setting_update": - // Update local settings - settings[parsed.setting_name] = parsed.setting_value; - // Save local settings - _saveSettings(); - - switch (parsed.setting_name) { - case "external_window": - chat_overlay_window.presentationMode = parsed.setting_value ? Desktop.PresentationMode.NATIVE : Desktop.PresentationMode.VIRTUAL; - break; - case "max_history": - let new_history = message_history.splice(0, message_history.length - settings.max_history); - Settings.setValue("ArmoredChat-Messages", new_history); - break; - } - break; - - case "initialized": - // https://github.com/overte-org/overte/issues/824 - chat_overlay_window.visible = app_is_visible; // The "visible" field in the Desktop.createWindow does not seem to work. Force set it to the initial state (false) - _loadSettings(); - break; - case "action": - switch (parsed.action) { - case "clear_history": - Settings.setValue("ArmoredChat-Messages", []); - break; - } - } - } - // - // Sending messages - // These functions just shout out their messages. We are listening to messages in an other function, and will record all heard messages there - function _sendMessage(message) { - Messages.sendMessage( - "chat", - JSON.stringify({ - position: MyAvatar.position, - message: message, - displayName: MyAvatar.sessionDisplayName, - channel: app_data.current_page, - action: "send_chat_message", - }) - ); - - // FloofyChat Compatibility - Messages.sendMessage( - "Chat", - JSON.stringify({ - position: MyAvatar.position, - message: message, - displayName: MyAvatar.sessionDisplayName, - channel: app_data.current_page.charAt(0).toUpperCase() + app_data.current_page.slice(1), - type: "TransmitChatMessage", - for_app: "Floof", - }) - ); - - // Show overlay of the message you sent - _overlayMessage({ sender: MyAvatar.sessionDisplayName, message: message }); - } - function _overlayMessage(message) { - // Floofchat compatibility - // This makes it so that our own messages are not rendered. - // For now, Floofchat has priority over notifications as they use a strange system I don't want to touch yet. - if (!message.action) return; - - Messages.sendLocalMessage( - "Floof-Notif", - JSON.stringify({ - sender: message.sender, - text: message.message, - color: { red: 122, green: 122, blue: 122 }, - }) - ); - } - function _loadSettings() { - settings = Settings.getValue("ArmoredChat-Config", settings); - - _emitEvent({ type: "setting_update", setting_name: "max_history", setting_value: Number(settings.max_history) }); - - // Compact chat - if (settings.compact_chat) { - _emitEvent({ type: "setting_update", setting_name: "compact_chat", setting_value: true }); - } - - // External Window - if (settings.external_window) { - chat_overlay_window.presentationMode = settings.external_window ? Desktop.PresentationMode.NATIVE : Desktop.PresentationMode.VIRTUAL; - _emitEvent({ type: "setting_update", setting_name: "external_window", setting_value: true }); - } - - // Refill the history with the saved messages - message_history.forEach((message) => { - delete message.action; - _emitEvent({ type: "show_message", ...message }); - }); - } - function _saveSettings() { - console.log("Saving config"); - Settings.setValue("ArmoredChat-Config", settings); - } - /** - * Emit a packet to the HTML front end. Easy communication! - * @param {Object} packet - The Object packet to emit to the HTML - * @param {("setting_update"|"show_message")} packet.type - The type of packet it is - */ - function _emitEvent(packet = { type: "" }) { - chat_overlay_window.emitScriptEvent(JSON.stringify(packet)); - } -})(); diff --git a/applications/armored-chat/compact-messages.css b/applications/armored-chat/compact-messages.css deleted file mode 100644 index b5f0eef..0000000 --- a/applications/armored-chat/compact-messages.css +++ /dev/null @@ -1,22 +0,0 @@ -body .page .content.message-list .message { - display: grid; - box-sizing: border-box; - grid-template-columns: 1fr 1fr; - grid-gap: inherit; - padding: 2px; - margin-bottom: 5px; -} -body .page .content.message-list .message .pfp { - display: none !important; -} -body .page .content.message-list .message .name { - color: #dbdbdb; -} -body .page .content.message-list .message .timestamp { - text-align: right; - color: #dbdbdb; -} -body .page .content.message-list .message .body { - grid-column-start: 1; - grid-column-end: 3; -} \ No newline at end of file diff --git a/applications/armored-chat/compact-messages.scss b/applications/armored-chat/compact-messages.scss deleted file mode 100644 index ed40c1e..0000000 --- a/applications/armored-chat/compact-messages.scss +++ /dev/null @@ -1,29 +0,0 @@ -body { - .page { - .content.message-list { - .message { - display: grid; - box-sizing: border-box; - grid-template-columns: 1fr 1fr; - grid-gap: inherit; - padding: 2px; - margin-bottom: 5px; - - .pfp { - display: none !important; - } - .name { - color: #dbdbdb; - } - .timestamp { - text-align: right; - color: #dbdbdb; - } - .body { - grid-column-start: 1; - grid-column-end: 3; - } - } - } - } -} diff --git a/applications/armored-chat/encrpytion.js b/applications/armored-chat/encrpytion.js deleted file mode 100644 index fa2233f..0000000 --- a/applications/armored-chat/encrpytion.js +++ /dev/null @@ -1,22 +0,0 @@ -(function () { - // TODO: Sign messages - // TODO: Verify signatures - - let rsa = forge.pki.rsa; - let keypair; - - function newKeyPair() { - // 2048 bits. Not the most super-duper secure length of 4096. - // This value must remain low to ensure lower-power machines can use. - // We will generate new keys automatically every so often and will also allow user to refresh keys. - keypair = rsa.generateKeyPair({ bits: 2048, workers: -1 }); - } - function encrypt(message) { - if (!keypair) return null; - return keypair.publicKey.encrypt("Test message"); - } - function decrypt(message) { - if (!keypair) return null; - return keypair.privateKey.decrypt(encrypted); - } -})(); diff --git a/applications/armored-chat/img/icon_black.png b/applications/armored-chat/img/icon_black.png deleted file mode 100644 index 410dc40..0000000 Binary files a/applications/armored-chat/img/icon_black.png and /dev/null differ diff --git a/applications/armored-chat/img/icon_white.png b/applications/armored-chat/img/icon_white.png deleted file mode 100644 index e29bf99..0000000 Binary files a/applications/armored-chat/img/icon_white.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/send.svg b/applications/armored-chat/img/ui/send.svg deleted file mode 100644 index 82c70a6..0000000 --- a/applications/armored-chat/img/ui/send.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - diff --git a/applications/armored-chat/img/ui/send_black.png b/applications/armored-chat/img/ui/send_black.png deleted file mode 100644 index bc9ece7..0000000 Binary files a/applications/armored-chat/img/ui/send_black.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/send_white.png b/applications/armored-chat/img/ui/send_white.png deleted file mode 100644 index 2730d2f..0000000 Binary files a/applications/armored-chat/img/ui/send_white.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/settings_black.png b/applications/armored-chat/img/ui/settings_black.png deleted file mode 100644 index f6481a8..0000000 Binary files a/applications/armored-chat/img/ui/settings_black.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/settings_white.png b/applications/armored-chat/img/ui/settings_white.png deleted file mode 100644 index 12a35ad..0000000 Binary files a/applications/armored-chat/img/ui/settings_white.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/social_black.png b/applications/armored-chat/img/ui/social_black.png deleted file mode 100644 index 16777af..0000000 Binary files a/applications/armored-chat/img/ui/social_black.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/social_white.png b/applications/armored-chat/img/ui/social_white.png deleted file mode 100644 index 7677bd5..0000000 Binary files a/applications/armored-chat/img/ui/social_white.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/user.svg b/applications/armored-chat/img/ui/user.svg deleted file mode 100644 index 110e522..0000000 --- a/applications/armored-chat/img/ui/user.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - diff --git a/applications/armored-chat/img/ui/user_black.png b/applications/armored-chat/img/ui/user_black.png deleted file mode 100644 index b3ca6e0..0000000 Binary files a/applications/armored-chat/img/ui/user_black.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/user_white.png b/applications/armored-chat/img/ui/user_white.png deleted file mode 100644 index 74ec794..0000000 Binary files a/applications/armored-chat/img/ui/user_white.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/world_black.png b/applications/armored-chat/img/ui/world_black.png deleted file mode 100644 index c983e5d..0000000 Binary files a/applications/armored-chat/img/ui/world_black.png and /dev/null differ diff --git a/applications/armored-chat/img/ui/world_white.png b/applications/armored-chat/img/ui/world_white.png deleted file mode 100644 index 1f152b4..0000000 Binary files a/applications/armored-chat/img/ui/world_white.png and /dev/null differ diff --git a/applications/armored-chat/index.css b/applications/armored-chat/index.css deleted file mode 100644 index 2af882b..0000000 --- a/applications/armored-chat/index.css +++ /dev/null @@ -1,217 +0,0 @@ -body { - background-color: black; - color: white; - margin: 0; - height: 100vh; - width: 100vw; - font-family: Verdana, Geneva, Tahoma, sans-serif; - display: flex; - flex-direction: column; -} -body .header { - width: 100%; - height: 40px; - display: flex; - flex-direction: row; -} -body .header button { - width: 60px; - height: 100%; - border-radius: 0; - border: 0; - margin: 0; - padding: 0; - box-sizing: border-box; - transition: width ease-in-out 0.2s; -} -body .header button.active { - background-color: #6667ab; - color: white; - width: 100px; -} -body .header .left { - margin: 0 auto 0 0; -} -body .header .right { - margin: 0 0 0 auto; -} -body .page { - display: flex; - flex-direction: column; - flex-grow: 1; - overflow-y: auto; - width: 100%; -} -body .page .content { - width: 100%; - background-color: #111; - flex-grow: 1; -} -body .page .content.message-list { - overflow-y: auto; - overflow-x: hidden; - width: 100%; -} -body .page .content.message-list .message:nth-child(even) { - background-color: #1a1a1a; -} -body .page .content.message-list .message { - display: grid; - box-sizing: border-box; - grid-template-columns: 80px 5fr; - grid-gap: 0.75rem; - padding: 0.8rem 0.15rem; - width: 100%; - overflow-y: auto; -} -body .page .content.message-list .message .pfp { - height: 30px; - width: auto; - display: flex; -} -body .page .content.message-list .message .pfp img { - height: 100%; - width: auto; - margin: auto; - border-radius: 50px; - background-color: black; -} -body .page .content.message-list .message .name { - font-size: 1.15rem; - color: #dbdbdb; -} -body .page .content.message-list .message .body { - width: 100%; - word-wrap: anywhere; - overflow-x: hidden; -} -body .page .content.message-list .message .body a { - color: white; -} -body .page .content.message-list .message .body .image-container { - width: 100%; - max-width: 400px; - max-height: 300px; -} -body .page .content.message-list .message .body .image-container img { - width: auto; - height: 100%; -} -body .page .content.message-list .message .embeds { - width: 100%; - word-wrap: anywhere; - overflow-x: hidden; - overflow-x: hidden; -} -body .page .content.message-list .message .embeds a { - color: white; -} -body .page .content.message-list .message .embeds .image-container { - width: 100%; - max-width: 400px; - max-height: 300px; -} -body .page .content.message-list .message .embeds .image-container img { - max-width: 400px; - max-height: 300px; -} -body .page .content.message-list .message .timestamp { - text-align: center; - color: #dbdbdb; -} -body .page .content.settings .setting { - width: 100%; - display: flex; - padding: 0.5rem 0.25rem; - box-sizing: border-box; -} -body .page .content.settings .setting input { - margin: auto 0 auto auto; - height: 20px; -} -body .page .content.settings .setting-button input { - width: 100px; -} -body .page .content.settings .setting-value input { - width: 70px; -} -body .page .content.settings .setting-toggle input { - width: 20px; -} -body .page .content.settings .setting:nth-child(even) { - background-color: #1a1a1a; -} -body .footer { - width: 100%; - height: 40px; -} -body .footer.text-entry { - display: Flex; - flex-direction: row; -} -body .footer.text-entry input { - flex-grow: 1; - margin-right: 0; - border: 0; - font-size: 1.3rem; - min-width: 0; -} -body .footer.text-entry button { - width: 75px; - border: 0; - border-radius: 0; -} -body .hidden { - display: none !important; -} - -button { - width: 100px; - height: 100%; - background-color: white; - border-radius: 2px; - border: 0; - cursor: pointer; - outline: none; -} -button span { - width: 100%; - height: 100%; -} -button span img { - max-height: 70%; - width: auto; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - -webkit-user-drag: none; -} - -button:focus { - filter: brightness(50%); -} - -input { - outline: none; -} - -input:focus { - background-color: lightgray; -} - -@media screen and (max-width: 400px) { - body .header { - height: 30px; - } - body .header button { - width: 50px; - } - body .page .content.message-list .message { - grid-template-columns: 80px 5fr; - grid-gap: 0.75rem; - padding: 0.8rem 0.15rem; - } - body .page .content.message-list .message .pfp { - height: 30px; - } -} \ No newline at end of file diff --git a/applications/armored-chat/index.html b/applications/armored-chat/index.html deleted file mode 100644 index 193b915..0000000 --- a/applications/armored-chat/index.html +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - - - - - - - - -
-
- - - -
-
- -
-
-
-
-
- - - - - - - - - - -
- - -
- - - - - - - - diff --git a/applications/armored-chat/index.scss b/applications/armored-chat/index.scss deleted file mode 100644 index 42df092..0000000 --- a/applications/armored-chat/index.scss +++ /dev/null @@ -1,258 +0,0 @@ -body { - background-color: black; - color: white; - margin: 0; - - height: 100vh; - width: 100vw; - - font-family: Verdana, Geneva, Tahoma, sans-serif; - display: flex; - flex-direction: column; - - .header { - width: 100%; - height: 40px; - display: flex; - flex-direction: row; - - button { - width: 60px; - height: 100%; - border-radius: 0; - border: 0; - margin: 0; - padding: 0; - box-sizing: border-box; - transition: width ease-in-out 0.2s; - } - button.active { - background-color: #6667ab; - color: white; - width: 100px; - } - - .left { - margin: 0 auto 0 0; - } - - .right { - margin: 0 0 0 auto; - } - } - - .page { - display: flex; - flex-direction: column; - flex-grow: 1; - overflow-y: auto; - width: 100%; - - .content { - width: 100%; - background-color: #111; - flex-grow: 1; - } - - .content.message-list { - overflow-y: auto; - overflow-x: hidden; - width: 100%; - - .message:nth-child(even) { - background-color: #1a1a1a; - } - .message { - display: grid; - box-sizing: border-box; - grid-template-columns: 80px 5fr; - grid-gap: 0.75rem; - padding: 0.8rem 0.15rem; - width: 100%; - overflow-y: auto; - .pfp { - height: 30px; - - width: auto; - display: flex; - - img { - height: 100%; - width: auto; - margin: auto; - border-radius: 50px; - background-color: black; - } - } - - .name { - font-size: 1.15rem; - color: #dbdbdb; - } - - .body { - width: 100%; - word-wrap: anywhere; - overflow-x: hidden; - - a { - color: white; - } - - .image-container { - width: 100%; - max-width: 400px; - max-height: 300px; - - img { - width: auto; - height: 100%; - } - } - } - - .embeds { - width: 100%; - word-wrap: anywhere; - overflow-x: hidden; - - overflow-x: hidden; - a { - color: white; - } - - .image-container { - width: 100%; - max-width: 400px; - max-height: 300px; - - img { - max-width: 400px; - max-height: 300px; - } - } - } - - .timestamp { - text-align: center; - color: #dbdbdb; - } - } - } - - .content.settings { - .setting { - width: 100%; - display: flex; - padding: 0.5rem 0.25rem; - box-sizing: border-box; - - input{ - margin: auto 0 auto auto; - height: 20px; - } - } - .setting-button{ - input { - width: 100px; - } - } - .setting-value{ - input { - width: 70px; - } - } - .setting-toggle { - input { - width: 20px; - } - } - .setting:nth-child(even) { - background-color: #1a1a1a; - } - } - } - .footer { - width: 100%; - height: 40px; - } - - .footer.text-entry { - display: Flex; - flex-direction: row; - input { - flex-grow: 1; - margin-right: 0; - border: 0; - font-size: 1.3rem; - min-width: 0; - } - - button { - width: 75px; - border: 0; - border-radius: 0; - } - } - - .hidden { - display: none !important; - } -} - -button { - width: 100px; - height: 100%; - background-color: white; - border-radius: 2px; - border: 0; - cursor: pointer; - outline: none; - - span { - width: 100%; - height: 100%; - img { - max-height: 70%; - width: auto; - user-select: none; - -webkit-user-drag: none; - } - } -} -button:focus { - filter: brightness(50%); -} - -input { - outline: none; -} -input:focus { - background-color: lightgray; -} - -@media screen and (max-width: 400px) { - body { - .header { - height: 30px; - - button { - width: 50px; - } - } - - .page { - .content.message-list { - .message { - grid-template-columns: 80px 5fr; - grid-gap: 0.75rem; - padding: 0.8rem 0.15rem; - - .pfp { - height: 30px; - } - } - } - } - } -} diff --git a/applications/metadata.js b/applications/metadata.js index e26114e..15700c4 100644 --- a/applications/metadata.js +++ b/applications/metadata.js @@ -315,15 +315,6 @@ var metadata = { "applications": "icon": "replica/replica-i.png", "caption": "REPLICA" }, - { - "isActive": true, - "directory": "armored-chat", - "name": "Chat", - "description": "Chat application", - "jsfile": "armored-chat/armored_chat.js", - "icon": "armored-chat/img/icon_black.png", - "caption": "CHAT" - }, { "isActive": true, "directory": "domainMapper",