Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Floofchat with ArmoredChat #961

Merged
merged 33 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
002fdf0
Initial Commit.
Armored-Dragon May 17, 2024
0d5eb93
Added Settings.
Armored-Dragon May 18, 2024
7b50f91
Clear already logged messages.
Armored-Dragon May 18, 2024
66fd217
Maximum messages setting.
Armored-Dragon May 21, 2024
391a33d
Fixed saved date on messages.
Armored-Dragon May 21, 2024
c48e9d3
Clickable links.
Armored-Dragon May 22, 2024
2a42bce
Minor formatting adjustments.
Armored-Dragon May 22, 2024
9d9b57d
Fix notification width.
Armored-Dragon May 22, 2024
7920610
README
Armored-Dragon May 22, 2024
9bf5f3d
Linking fix.
Armored-Dragon May 22, 2024
86f8e29
Quick Message hotbar.
Armored-Dragon May 23, 2024
0bc11e8
Fix for #975 sticky keys.
Armored-Dragon May 23, 2024
1cddc5a
Added message padding.
Armored-Dragon May 23, 2024
ed3e629
Image embedding.
Armored-Dragon May 23, 2024
0a7b64d
Prevent VR quick_message bar.
Armored-Dragon May 23, 2024
c1e5115
Updated README.
Armored-Dragon May 23, 2024
7ef3322
Moved system chat to script-archive.
Armored-Dragon May 23, 2024
c734e0d
Updated Readme.
Armored-Dragon May 25, 2024
60a4662
Updated URL regex.
Armored-Dragon May 25, 2024
8301bfd
Added development manual.
Armored-Dragon May 26, 2024
82605c5
Scroll to bottom on launch.
Armored-Dragon May 27, 2024
01306b3
Scroll to bottom when changing page.
Armored-Dragon May 27, 2024
7fc1a3d
Fixed scrolling too far.
Armored-Dragon Jun 8, 2024
eb84de8
Corrected case on variables.
Armored-Dragon Jun 8, 2024
192d80a
Floofchat compatibility.
Armored-Dragon Jun 8, 2024
7e100a1
Raise VR Keyboard when textfield is selected
Armored-Dragon Jun 28, 2024
2012cce
Merge branch 'master' into ArmoredChat
Armored-Dragon Jun 29, 2024
ce79cc8
Merge branch 'overte-org:master' into ArmoredChat
Armored-Dragon Jun 30, 2024
c6d2e56
Fix keyboard being invoked when not in VR.
Armored-Dragon Jul 6, 2024
6cf6e6c
Disallow all text formatting by default.
Armored-Dragon Jul 8, 2024
252b33b
Removed commented code.
Armored-Dragon Jul 8, 2024
fe46258
Sanity check on message channel.
Armored-Dragon Jul 9, 2024
9964d91
Fixed message subscription.
Armored-Dragon Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes
240 changes: 240 additions & 0 deletions scripts/communityScripts/armored-chat/armored_chat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
//
// 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

(() => {
"use strict";

var app_is_visible = false;
var settings = {
external_window: false,
maximum_messages: 200,
};

// Global vars
var tablet;
var chat_overlay_window;
var app_button;
const channels = ["domain", "local"];
var message_history = Settings.getValue("ArmoredChat-Messages", []) || [];
var max_local_distance = 20; // Maximum range for the local chat
var pal_data = AvatarManager.getPalData().data;

Messages.subscribe("chat");
Messages.messageReceived.connect(receivedMessage);
AvatarManager.avatarAddedEvent.connect((session_id) => {
_avatarAction("connected", session_id);
});
AvatarManager.avatarRemovedEvent.connect((session_id) => {
_avatarAction("left", session_id);
});

startup();

function startup() {
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");

app_button = 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");
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.resolvePath("./armored_chat.qml"),
{
title: "Chat",
size: { x: 550, y: 400 },
additionalFlags: Desktop.ALWAYS_ON_TOP,
visible: app_is_visible,
presentationMode: Desktop.PresentationMode.VIRTUAL,
}
);

chat_overlay_window.closed.connect(toggleMainChatWindow);
chat_overlay_window.fromQml.connect(fromQML);
}
function receivedMessage(channel, message) {
// Is the message a chat message?
channel = channel.toLowerCase();
if (channel !== "chat") return;
console.log(`Received message:\n${message}`);
var message = JSON.parse(message);

message.channel = message.channel.toLowerCase(); // Make sure the "local", "domain", etc. is formatted consistently

if (!channels.includes(message.channel)) return; // Check the channel
if (
message.channel == "local" &&
Vec3.distance(MyAvatar.position, message.position) >
max_local_distance
)
return; // If message is local, and if player is too far away from location, don't do anything

// Update qml view of to new message
_emitEvent({ type: "show_message", ...message });

Messages.sendLocalMessage(
"Floof-Notif",
JSON.stringify({
sender: message.displayName,
text: message.message,
})
);

// Save message to 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, {
year: "numeric",
month: "long",
day: "numeric",
});
message_history.push(saved_message);
while (message_history.length > settings.maximum_messages) {
message_history.shift();
}
Settings.setValue("ArmoredChat-Messages", message_history);
}

function fromQML(event) {
console.log(`New QML event:\n${JSON.stringify(event)}`);

switch (event.type) {
case "send_message":
_sendMessage(event.message, event.channel);
break;
case "setting_change":
settings[event.setting] = event.value; // Update local settings
_saveSettings(); // Save local settings

switch (event.setting) {
case "external_window":
chat_overlay_window.presentationMode = event.value
? Desktop.PresentationMode.NATIVE
: Desktop.PresentationMode.VIRTUAL;
break;
case "maximum_messages":
// Do nothing
break;
}

break;
case "action":
switch (event.action) {
case "erase_history":
Settings.setValue("ArmoredChat-Messages", []);
_emitEvent({
type: "clear_messages",
});
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;
}
}
function _sendMessage(message, channel) {
Messages.sendMessage(
"chat",
JSON.stringify({
position: MyAvatar.position,
message: message,
displayName: MyAvatar.sessionDisplayName,
channel: channel,
action: "send_chat_message",
})
);
}
function _avatarAction(type, session_id) {
Script.setTimeout(() => {
if (type == "connected") {
pal_data = AvatarManager.getPalData().data;
}

// Get the display name of the user
let display_name = "";
display_name =
AvatarManager.getPalData([session_id])?.data[0]
?.sessionDisplayName || null;
if (display_name == null) {
for (let i = 0; i < pal_data.length; i++) {
if (pal_data[i].sessionUUID == session_id) {
display_name = pal_data[i].sessionDisplayName;
}
}
}

// Format the packet
let message = {};
message.message = `${display_name} ${type}`;

_emitEvent({ type: "avatar_connected", ...message });
}, 1500);
}
function _loadSettings() {
settings = Settings.getValue("ArmoredChat-Config", settings);

if (message_history) {
// Load message history
message_history.forEach((message) => {
delete message.action;
_emitEvent({ type: "show_message", ...message });
});
}

// Send current settings to the app
_emitEvent({ type: "initial_settings", settings: settings });

console.log(`\n\n\n` + JSON.stringify(settings));
}
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.sendToQml(packet);
}
})();
Loading
Loading