mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 02:07:14 +02:00
553 lines
No EOL
18 KiB
HTML
553 lines
No EOL
18 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Title</title>
|
|
|
|
<link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600,700" rel="stylesheet">
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
|
<script src="toast.min.js"></script>
|
|
|
|
<style>
|
|
html {
|
|
height: 100%;
|
|
}
|
|
|
|
/* Style the tab */
|
|
div.tab {
|
|
overflow: hidden;
|
|
border: 1px solid #ccc;
|
|
background-color: #f1f1f1;
|
|
}
|
|
|
|
/* Style the buttons inside the tab */
|
|
div.tab button {
|
|
background-color: inherit;
|
|
float: left;
|
|
border: none;
|
|
outline: none;
|
|
cursor: pointer;
|
|
padding: 14px 16px;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
/* Change background color of buttons on hover */
|
|
div.tab button:hover {
|
|
background-color: #ddd;
|
|
}
|
|
|
|
/* Create an active/current tablink class */
|
|
div.tab button.active {
|
|
background-color: #ccc;
|
|
}
|
|
|
|
|
|
div.dockButton {
|
|
|
|
position: absolute; /*or fixed*/
|
|
right: 10px;
|
|
|
|
|
|
overflow: hidden;
|
|
border: 1px solid #ccc;
|
|
background-color: #f1f1f1;
|
|
}
|
|
|
|
div.dockButton button {
|
|
background-color: inherit;
|
|
float: right;
|
|
border: none;
|
|
outline: none;
|
|
cursor: pointer;
|
|
padding: 14px 16px;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
/* Change background color of buttons on hover */
|
|
div.dockButton button:hover {
|
|
background-color: #ddd;
|
|
}
|
|
|
|
/* Create an active/current tablink class */
|
|
div.dockButton button.active {
|
|
background-color: #ccc;
|
|
}
|
|
|
|
/* Style the tab content */
|
|
.TabContent {
|
|
display: none;
|
|
|
|
padding: 6px 12px;
|
|
border-top: none;
|
|
}
|
|
|
|
body {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow-x: hidden;
|
|
overflow-y: hidden;
|
|
margin: 0;
|
|
font-family: 'Raleway', sans-serif;
|
|
color: white;
|
|
background: linear-gradient(#2b2b2b, #0f212e);
|
|
}
|
|
|
|
.Content {
|
|
min-height: 100vh;
|
|
font-size: 20px;
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.TopBar {
|
|
height: 40px;
|
|
background: linear-gradient(#2b2b2b, #1e1e1e);
|
|
font-weight: bold;
|
|
padding: 10px 10px 10px 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100vw;
|
|
font-size: 28px;
|
|
}
|
|
|
|
.ChatLog {
|
|
height: calc(100vh - 169px);
|
|
width: calc(100vw - 40px);
|
|
padding: 20px;
|
|
font-size: 20px;
|
|
color: white;
|
|
background-color: black;
|
|
overflow-x: hidden;
|
|
overflow-y: scroll;
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
.ChatLogLine {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.ChatLogLineDisplayName {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.ChatLogLineMessage {
|
|
}
|
|
|
|
.LogLogLine {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.LogLogLineMessage {
|
|
/*font-style: italic;*/
|
|
}
|
|
|
|
.ChatInput {
|
|
color: #252525;
|
|
/*background: linear-gradient(#575757 20%, #252525 100%);*/
|
|
height: 60px !important;
|
|
}
|
|
|
|
.ChatInputText {
|
|
padding: 5px 0px 0px 5px;
|
|
height: 60px !important;
|
|
width: 100vw;
|
|
font-size: 20px !important;
|
|
}
|
|
|
|
.responsive {
|
|
width: 100%;
|
|
max-width: 420px;
|
|
height: auto;
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
|
|
<div class="Content">
|
|
<div id="TopBar" class="TopBar">
|
|
<div class="tab">
|
|
<button class="tablinks" onclick="switchTab(event, 'Local')" id="defaultOpen">Local</button>
|
|
<button class="tablinks" onclick="switchTab(event, 'Domain')">Domain</button>
|
|
<button class="tablinks" onclick="switchTab(event, 'FluffyDev')">FluffyDev</button>
|
|
</div>
|
|
<div class="topBarFiller">
|
|
</div>
|
|
<div class="dockButton">
|
|
<button class="dockButton_" onclick="redock()">Redock</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="Local" class="TabContent ChatLog">
|
|
</div>
|
|
|
|
<div id="Domain" class="TabContent ChatLog">
|
|
</div>
|
|
|
|
<div id="FluffyDev" class="TabContent ChatLog">
|
|
</div>
|
|
|
|
<div class="ChatInput">
|
|
<input type="text" class="ChatInputText" id="ChatInputText" size="256">
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
<script>
|
|
|
|
|
|
//linky function
|
|
//$('#ChatInputText').twemojiPicker();
|
|
(function ($) {
|
|
|
|
"use strict";
|
|
|
|
$.fn.linky = function (options) {
|
|
return this.each(function () {
|
|
var $el = $(this),
|
|
linkifiedContent = _linkify($el, options);
|
|
|
|
$el.html(linkifiedContent);
|
|
});
|
|
};
|
|
|
|
function _linkify($el, options) {
|
|
var links = {
|
|
twitter: {
|
|
baseUrl: "https://twitter.com/",
|
|
hashtagSearchUrl: "hashtag/"
|
|
},
|
|
instagram: {
|
|
baseUrl: "http://instagram.com/",
|
|
hashtagSearchUrl: null // Doesn't look like there is one?
|
|
},
|
|
github: {
|
|
baseUrl: "https://github.com/",
|
|
hashtagSearchUrl: null
|
|
}
|
|
},
|
|
defaultOptions = {
|
|
mentions: false,
|
|
hashtags: false,
|
|
urls: true,
|
|
linkTo: "twitter" // Let's default to Twitter
|
|
},
|
|
extendedOptions = $.extend(defaultOptions, options),
|
|
elContent = $el.html(),
|
|
// Regular expression courtesy of Matthew O'Riordan, see: http://goo.gl/3syEKK
|
|
urlRegEx = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;,:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+,~%\/\.\w\-]*)?\??(?:[\-\+=&;,:%@\.\w]*)#?(?:[\.\!\/\\\w]*))?)/g,
|
|
matches;
|
|
|
|
// Linkifying URLs
|
|
if (extendedOptions.urls) {
|
|
matches = elContent.match(urlRegEx);
|
|
if (matches) {
|
|
elContent = _linkifyUrls(matches, $el);
|
|
}
|
|
}
|
|
|
|
// Linkifying mentions
|
|
if (extendedOptions.mentions) {
|
|
elContent = _linkifyMentions(elContent, links[extendedOptions.linkTo].baseUrl);
|
|
}
|
|
|
|
// Linkifying hashtags
|
|
if (extendedOptions.hashtags) {
|
|
elContent = _linkifyHashtags(elContent, links[extendedOptions.linkTo]);
|
|
}
|
|
|
|
return elContent;
|
|
}
|
|
|
|
// For any URLs present, unless they are already identified within
|
|
// an `a` element, linkify them.
|
|
function _linkifyUrls(matches, $el) {
|
|
var elContent = $el.html();
|
|
|
|
$.each(matches, function () {
|
|
|
|
//var arr = [ "jpeg", "jpg", "gif", "png" ];
|
|
var protocol = this.split('://')[0];
|
|
var ext = this.split('.').pop();
|
|
|
|
switch (true) {
|
|
case ext == "png":
|
|
case ext == "jpg":
|
|
case ext == "gif":
|
|
case ext == "jpeg":
|
|
case ext == "PNG":
|
|
case ext == "JPG":
|
|
case ext == "GIF":
|
|
case ext == "JPEG":
|
|
elContent = elContent.replace(this, "<br/><img src='" + this + "'class=\"responsive\"><br/><a href=\"javascript:gotoClipboard('" + this + "');\" target='_blank'>" + this + "</a>");
|
|
break;
|
|
case ext == "iframe":
|
|
elContent = elContent.replace(this, "<br/><iframe src='" + this + "'width=\"440\" height=\"248\" frameborder=\"0\"></iframe>");
|
|
break;
|
|
case ext == "webm":
|
|
elContent = elContent.replace(this, "<br/><video controls class=\"responsive\"><source src='" + this + "' type='video/" + ext + "'></video><br/><a href=\"javascript:gotoClipboard('" + this + "');\">" + this + "</a>");
|
|
break;
|
|
case protocol === "HIFI":
|
|
case protocol === "hifi":
|
|
elContent = elContent.replace(this, "<br/><a href=\"javascript:gotoHiFi('" + this + "');\">" + this + "</a>");
|
|
break;
|
|
case !!this.match(/^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$/):
|
|
var youtubeMatch = this.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
|
|
if (youtubeMatch && youtubeMatch[2].length == 11 && this.match(/^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$/)) {
|
|
elContent = "<br/><iframe width='420' height='236' src='https://www.youtube.com/embed/" + youtubeMatch[2] + "' frameborder='0'></iframe><br/><a href=\"javascript:gotoURL('" + this + "');\">" + this + "</a>";
|
|
break;
|
|
}
|
|
// else fall through to default
|
|
default:
|
|
elContent = elContent.replace(this, "<br/><a href=\"javascript:gotoURL('" + this + "');\">" + this + "</a>");
|
|
break;
|
|
}
|
|
|
|
});
|
|
return elContent;
|
|
}
|
|
|
|
// Find any mentions (e.g. @andrs) and turn them into links that
|
|
// refer to the appropriate social profile (e.g. twitter or instagram).
|
|
function _linkifyMentions(text, baseUrl) {
|
|
return text.replace(/(^|\s|\(|>)@(\w+)/g, "$1<a href='" + baseUrl + "$2' target='_blank'>@$2</a>");
|
|
}
|
|
|
|
// Find any hashtags (e.g. #linkyrocks) and turn them into links that refer
|
|
// to the appropriate social profile.
|
|
function _linkifyHashtags(text, links) {
|
|
// If there is no search URL for a hashtag, there isn't much we can do
|
|
if (links.hashtagSearchUrl === null) return text;
|
|
return text.replace(/(^|\s|\(|>)#((\w|[\u00A1-\uFFFF])+)/g, "$1<a href='" + links.baseUrl + links.hashtagSearchUrl + "$2' target='_blank'>#$2</a>");
|
|
}
|
|
|
|
}(jQuery));
|
|
|
|
|
|
var appUUID;
|
|
|
|
function gotoHiFi(url) {
|
|
emitWebEvent({type: "CMD", cmd: "GOTO", url: url});
|
|
}
|
|
|
|
function gotoURL(url) {
|
|
emitWebEvent({type: "CMD", cmd: "URL", url: url});
|
|
}
|
|
|
|
function gotoClipboard(url) {
|
|
var options = {
|
|
style: {
|
|
main: {
|
|
background: "#9c27b0",
|
|
color: "white"
|
|
}
|
|
}
|
|
};
|
|
iqwerty.toast.Toast('Copied URL to Clipboard',options);
|
|
emitWebEvent({type: "CMD", cmd: "COPY", url: url});
|
|
}
|
|
|
|
function emitWebEvent(obj) {
|
|
if (window.qt) {
|
|
obj.appUUID = appUUID; // Appends the appUUID for checking that its from the correct html/qml.
|
|
EventBridge.emitWebEvent(JSON.stringify(obj)); // So you can just send a JSON object without having to stringify.
|
|
}
|
|
}
|
|
|
|
function rgbToHex(colour) {
|
|
var red = Number(colour.red).toString(16);
|
|
if (red.length < 2) {
|
|
red = "0" + red;
|
|
}
|
|
var green = Number(colour.green).toString(16);
|
|
if (green.length < 2) {
|
|
green = "0" + green;
|
|
}
|
|
var blue = Number(colour.blue).toString(16);
|
|
if (blue.length < 2) {
|
|
blue = "0" + blue;
|
|
}
|
|
return "#" + red + green + blue;
|
|
}
|
|
|
|
|
|
var messageData = {}; // The data that is sent along with the message.
|
|
var $ChatLog; // The scrolling chat log.
|
|
var $ChatInputText; // The text field for entering text.
|
|
var userName;
|
|
|
|
|
|
function getCurrTab() {
|
|
|
|
var TabContent = document.getElementsByClassName("TabContent");
|
|
for (var i = 0; i < TabContent.length; i++) {
|
|
if (TabContent[i].style.display === "inline") {
|
|
return TabContent[i];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function redock() {
|
|
emitWebEvent({type: "CMD", cmd: "REDOCK"});
|
|
location.reload();
|
|
}
|
|
|
|
function switchTab(evt, tabName) {
|
|
// Declare all variables
|
|
var i, TabContent, tablinks;
|
|
|
|
// Get all elements with class="tabcontent" and hide them
|
|
TabContent = document.getElementsByClassName("TabContent");
|
|
for (i = 0; i < TabContent.length; i++) {
|
|
TabContent[i].style.display = "none";
|
|
}
|
|
|
|
// Get all elements with class="tablinks" and remove the class "active"
|
|
tablinks = document.getElementsByClassName("tablinks");
|
|
for (i = 0; i < tablinks.length; i++) {
|
|
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
|
}
|
|
|
|
// Show the current tab, and add an "active" class to the button that opened the tab
|
|
document.getElementById(tabName).style.display = "inline";
|
|
evt.currentTarget.className += " active";
|
|
scrollChatLog(tabName);
|
|
}
|
|
|
|
function logMessage(userName, message, logScreen, colour) {
|
|
var LogScreen = $("#" + logScreen);
|
|
|
|
/*EventBridge.emitWebEvent(
|
|
JSON.stringify({
|
|
type: "sendMessage",
|
|
userName: userName,
|
|
message: message,
|
|
chatID: LogScreen.id
|
|
}));*/
|
|
|
|
var $logLine =
|
|
$('<div/>')
|
|
.addClass('LogLogLine')
|
|
.data('chat-message', message).css("color", rgbToHex(colour))
|
|
.appendTo(LogScreen);
|
|
var $logLineMessage =
|
|
$('<b/>')
|
|
.addClass('LogLogLineMessage')
|
|
.text(userName + ": ").css("color", rgbToHex(colour))
|
|
.appendTo(LogScreen);
|
|
var $logLineMessage2 =
|
|
$('<span/>')
|
|
.addClass('LogLogLineMessage')
|
|
.text(message).css("color", rgbToHex(colour)).linky()
|
|
.appendTo(LogScreen);/*
|
|
$logLineMessage2.html($logLineMessage2.html().replace(/(http:\/\/[^\s]+)/g, "<a href='$1' target='_blank'>$1</a>"));
|
|
$logLineMessage2.html($logLineMessage2.html().replace(/(https:\/\/[^\s]+)/g, "<a href='$1' target='_blank'>$1</a>"));
|
|
$logLineMessage2.html($logLineMessage2.html().replace(/(hifi:\/\/[^\s]+)/g, "<a href='$1' target='_blank'>$1</a>"));*/
|
|
}
|
|
|
|
function scrollChatLog(chatID) {
|
|
var $chatID = $("#" + chatID);
|
|
$chatID.scrollTop($chatID.scrollTop() + 100000);
|
|
}
|
|
|
|
function time() {
|
|
var d = new Date();
|
|
var h = (d.getHours()).toString();
|
|
var m = (d.getMinutes()).toString();
|
|
var s = (d.getSeconds()).toString();
|
|
var h2 = ("0" + h).slice(-2);
|
|
var m2 = ("0" + m).slice(-2);
|
|
var s2 = ("0" + s).slice(-2);
|
|
s2 += (d.getMilliseconds() / 1000).toFixed(2).slice(1);
|
|
return h2 + ":" + m2 + ":" + s2;
|
|
}
|
|
|
|
function main() {
|
|
|
|
var parsedUrl = new URL(window.location.href);
|
|
appUUID = parsedUrl.searchParams.get("appUUID");
|
|
|
|
//console.log("ChatPage: main");
|
|
|
|
$ChatLog = $('#Local');
|
|
$ChatInputText = $('#ChatInputText');
|
|
|
|
// Whenever the chat log resizes, or the input text gets or loses focus,
|
|
// scroll the chat log to the last line.
|
|
$ChatInputText.on('focus blur', function (event) {
|
|
//console.log("ChatInputText focus blur", $ChatInputText, event);
|
|
scrollChatLog(getCurrTab().id);
|
|
});
|
|
|
|
// Track when the user is typing, and handle the message when the user hits return.
|
|
$ChatInputText.on('keydown', function (event) {
|
|
if (event.keyCode === 13) {
|
|
var message = $ChatInputText.val().substr(0, 256);
|
|
$ChatInputText.val('');
|
|
if (message !== '') {
|
|
|
|
emitWebEvent({type: "MSG", message: message, tab: getCurrTab().id, time: time()});
|
|
|
|
console.log("getCurrTab: ", getCurrTab().id);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Start out with the input text in focus.
|
|
$ChatInputText.focus();
|
|
|
|
// Hook up a handler for events that come from hifi.
|
|
|
|
if (window.qt) {
|
|
setTimeout(function () {
|
|
console.log("connecting to eventbridge");
|
|
EventBridge.scriptEventReceived.connect(function (message) {
|
|
|
|
var temp = [];
|
|
|
|
try {
|
|
temp = JSON.parse(message);
|
|
} catch (e) {
|
|
//
|
|
}
|
|
|
|
if (temp.length === 1) {
|
|
var temp2 = temp[0];
|
|
logMessage("[" + temp2[0] + "] " + temp2[2], temp2[1], temp2[4], temp2[3]);
|
|
scrollChatLog(temp2[4]);
|
|
} else if (temp.length > 1) {
|
|
temp.forEach(function (msg) {
|
|
logMessage("[" + msg[0] + "] " + msg[2], msg[1], msg[4], msg[3]);
|
|
scrollChatLog(msg[4]);
|
|
});
|
|
}
|
|
});
|
|
}, 100); // Delay to allow everything to settle
|
|
}
|
|
|
|
// Start out with the input text in focus.
|
|
$ChatInputText.focus();
|
|
|
|
if (window.qt) {
|
|
setTimeout(function () {
|
|
emitWebEvent({
|
|
"type": "ready"
|
|
});
|
|
}, 250); // Delay to allow everything to settle
|
|
console.log("sending ready signal!");
|
|
}
|
|
}
|
|
|
|
// Start up once the document is loaded.
|
|
$(document).ready(main);
|
|
|
|
document.getElementById("defaultOpen").click();
|
|
</script>
|
|
|
|
</html> |