511 lines · 16.1 KB · HTML
RawDownload
<!--//  ChatPage.html////  Created by Faye Li on 3 Feb 2017//  Modified by Don Hopkins (dhopkins@donhopkins.com).//  Copyright 2017 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html--><html>    <head>        <title>Chat</title>        <meta charset="utf-8">        <meta name="viewport" content="width=device-width, initial-scale=1">        <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>        <style>            input[type=button],            button {                font-family: 'Raleway';                font-weight: bold;                font-size: 20px;                vertical-align: top;                width: 100%;                height: 40px;                min-width: 120px;                padding: 0px 18px;                margin-top: 5px;                margin-right: 6px;                border-radius: 5px;                border: none;                color: #fff;                background-color: #000;                background: linear-gradient(#343434 20%, #000 100%);                cursor: pointer;            }             .commandButton {                width: 100px !important;            }             input[type=text] {                font-family: 'Raleway';                font-weight: bold;                font-size: 20px;                vertical-align: top;                height: 40px;                color: #000;                width: 100%;                background-color: #fff;                background: linear-gradient(#343434 20%, #fff 100%);            }             input[type=button].red {                color: #fff;                background-color: #94132e;                background: linear-gradient(#d42043 20%, #94132e 100%);            }            input[type=button].blue {                color: #fff;                background-color: #1080b8;                background: linear-gradient(#00b4ef 20%, #1080b8 100%);            }            input[type=button].white {                color: #121212;                background-color: #afafaf;                background: linear-gradient(#fff 20%, #afafaf 100%);            }             input[type=button]:enabled:hover {                background: linear-gradient(#000, #000);                border: none;            }            input[type=button].red:enabled:hover {                background: linear-gradient(#d42043, #d42043);                border: none;            }            input[type=button].blue:enabled:hover {                background: linear-gradient(#00b4ef, #00b4ef);                border: none;            }            input[type=button].white:enabled:hover {                background: linear-gradient(#fff, #fff);                border: none;            }             input[type=button]:active {                background: linear-gradient(#343434, #343434);            }            input[type=button].red:active {                background: linear-gradient(#94132e, #94132e);            }            input[type=button].blue:active {                background: linear-gradient(#1080b8, #1080b8);            }            input[type=button].white:active {                background: linear-gradient(#afafaf, #afafaf);            }             input[type=button]:disabled {                color: #252525;                background: linear-gradient(#575757 20%, #252525 100%);            }             input[type=button][pressed=pressed] {                color: #00b4ef;            }             body {                width: 100%;                overflow-x: hidden;                overflow-y: hidden;                margin: 0;                font-family: 'Raleway', sans-serif;                color: white;                background: linear-gradient(#2b2b2b, #0f212e);            }             .Content {                font-size: 20px;                width: 100%;                height: 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: 100%;                font-size: 28px;                flex-grow: 0;            }             .ChatLog {                padding: 20px;                font-size: 20px;                flex-grow: 1;                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 {                display: flex;                flex-direction: row;                flex-grow: 0;            }             .ChatInputText {                padding: 20px 20px 20px 20px;                height: 60px !important;                font-size: 20px !important;                flex-grow: 1;                display: flex;                flex-direction: column;            }         </style>    </head>    <body>         <div class="Content">             <div class="TopBar">                <b>Chat</b>            </div>             <div class="ChatLog" id="ChatLog"></div>             <div class="ChatInput">              <input type="text" class="ChatInputText" id="ChatInputText" size="256" maxlength="256" />            </div>         </div>     </body>     <script>         //console.log("ChatPage: loading script...");         var messageData = {}; // The data that is sent along with the message.         var typing = false; // True while the user is typing.        var typingTimerDuration = 1; // How long to wait before ending typing, in seconds.        var typingTimer = null; // The timer to end typing.        var $ChatLog; // The scrolling chat log.        var $ChatInputText; // The text field for entering text.         // Recreate the lines in chatLog as the DOM in $ChatLog.        function updateChatLog() {            $ChatLog.html('');            for (var i = 0, n = chatLog.length; i < n; i++) {                var a = chatLog[i];                var avatarID = a[0];                var displayName = a[1];                var message = a[2];                var data = a[3];                //console.log("updateChatLog", i, a, displayName, message);                if (avatarID) {                    receiveChatMessage(avatarID, displayName, message, data);                } else {                    logMessage(message);                }            }        }         // Call this no every keystroke.        function type() {            beginTyping();            handleType();        }         // Reset the typing timer, and notify if we're starting.        function beginTyping() {            if (typingTimer) {                clearTimeout(typingTimer);            }             typingTimer = setTimeout(function() {                typing = false;                handleEndTyping();            }, typingTimerDuration * 1000);             if (typing) {                return;            }             typing = true;            handleBeginTyping();        }         // Clear the typing timer and notify if we're finished.        function endTyping() {            if (typingTimer) {                clearTimeout(typingTimer);                typingTimer = null;            }             if (!typing) {                return;            }             typing = false;            handleEndTyping();        }         // Notify the interface script on every keystroke.        function handleType() {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "Type"                }));        }         // Notify the interface script when we begin typing.        function handleBeginTyping() {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "BeginTyping"                }));        }         // Notify the interface script when we end typing.        function handleEndTyping() {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "EndTyping"                }));        }         // Append a chat message to $ChatLog.        function receiveChatMessage(avatarID, displayName, message, data) {            var $logLine =                $('<div/>')                    .addClass('ChatLogLine')                    .data('chat-avatarID', avatarID)                    .data('chat-displayName', displayName)                    .data('chat-message', message)                    .data('chat-data', data)                    .appendTo($ChatLog);            var $logLineDisplayName =                $('<span/>')                    .addClass('ChatLogLineDisplayName')                    .text(displayName + ': ')                    .on('mouseenter', function(event) {                        identifyAvatar(avatarID);                        //event.cancelBubble();                        $logLineDisplayName.css({                            color: '#00ff00',                            'text-decoration': 'underline'                        });                    })                    .on('mouseleave', function(event) {                        unidentifyAvatar(avatarID);                        //event.cancelBubble();                        $logLineDisplayName.css({                            color: 'white',                            'text-decoration': 'none'                        });                    })                    .click(function(event) {                        faceAvatar(avatarID, displayName);                        //event.cancelBubble();                    })                    .appendTo($logLine);            var $logLineMessage =                $('<span/>')                    .addClass('ChatLogLineMessage')                    .text(message)                    .appendTo($logLine);        }         // Append a log message to $ChatLog.        function logMessage(message) {            var $logLine =                $('<div/>')                    .addClass('LogLogLine')                    .data('chat-message', message)                    .appendTo($ChatLog);            var $logLineMessage =                $('<span/>')                    .addClass('LogLogLineMessage')                    .text(message)                    .appendTo($logLine);        }         // Scroll $ChatLog so the last line is visible.        function scrollChatLog() {            var $logLine = $ChatLog.children().last();            if (!$logLine || !$logLine.length) {                return;            }            var chatLogHeight = $ChatLog.outerHeight(true);            var logLineTop = ($logLine.offset().top - $ChatLog.offset().top);            var logLineBottom = logLineTop + $logLine.outerHeight(true);            var scrollUp = logLineBottom - chatLogHeight;            if (scrollUp > 0) {                $ChatLog.scrollTop($ChatLog.scrollTop() + scrollUp);            }        }         // Tell the interface script we have initialized.        function emitReadyEvent() {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "Ready"                }));        }         // The user entered an empty chat message.        function emptyChatMessage() {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "EmptyChatMessage",                    data: null                }));        }         // The user entered a non-empty chat message.        function handleChatMessage(message, data) {            //console.log("handleChatMessage", message);            EventBridge.emitWebEvent(                JSON.stringify({                    type: "HandleChatMessage",                    message: message,                    data: data                }));        }         // Clear the chat log, of course.        function clearChatLog() {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "ClearChatLog"                }));        }         // Identify an avatar.        function identifyAvatar(avatarID) {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "IdentifyAvatar",                    avatarID: avatarID                }));        }         // Stop identifying an avatar.        function unidentifyAvatar(avatarID) {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "UnidentifyAvatar",                    avatarID: avatarID                }));        }         // Face an avatar.        function faceAvatar(avatarID, displayName) {            EventBridge.emitWebEvent(                JSON.stringify({                    type: "FaceAvatar",                    avatarID: avatarID,                    displayName: displayName                }));        }         // Let's get this show on the road!        function main() {             //console.log("ChatPage: main");             $ChatLog = $('#ChatLog');            $ChatInputText = $('#ChatInputText');             // Whenever the chat log resizes, or the input text gets or loses focus,             // scroll the chat log to the last line.            $ChatLog.on('resize', function(event) {                //console.log("ChatLog resize", $ChatLog, event);                scrollChatLog();            });            $ChatInputText.on('focus blur', function(event) {                //console.log("ChatInputText focus blur", $ChatInputText, event);                scrollChatLog();            });             // Track when the user is typing, and handle the message when the user hits return.            $ChatInputText.on('keydown', function(event) {                type();                if (event.keyCode == 13) {                    var message = $ChatInputText.val().substr(0, 256);                    $ChatInputText.val('');                    if (message == '') {                        emptyChatMessage();                    } else {                        handleChatMessage(message, messageData);                    }                    endTyping();                }            });             // Start out with the input text in focus.            $ChatInputText.focus();             // Hook up a handler for events that come from hifi.            EventBridge.scriptEventReceived.connect(function (message) {                 //console.log("ChatPage: main: scriptEventReceived", message);                 var messageData = JSON.parse(message);                var messageType = messageData['type'];                 switch (messageType) {                     case "Update":                        chatLog = messageData['chatLog'];                        updateChatLog();                        scrollChatLog();                        break;                     case "ReceiveChatMessage":                        receiveChatMessage(messageData['avatarID'], messageData['displayName'], messageData['message'], message['data']);                        scrollChatLog();                        break;                     case "LogMessage":                        logMessage(messageData['message']);                        scrollChatLog();                        break;                     default:                        console.log("WEB: received unexpected script event message: " + message);                        break;                 }

Lines 1–500 of 511.