diff --git a/index.html b/index.html
index 462dd6f..1058eb2 100644
--- a/index.html
+++ b/index.html
@@ -7,16 +7,7 @@
-
-
-
Welcome to prismarine-web-client! Chat appears here.
-
-
-
+
diff --git a/index.js b/index.js
index 9717153..a60c59f 100644
--- a/index.js
+++ b/index.js
@@ -2,6 +2,7 @@
require('./lib/menu')
require('./lib/loading_screen')
require('./lib/hotbar')
+require('./lib/chat')
const net = require('net')
@@ -13,7 +14,6 @@ const { WorldView, Viewer } = require('prismarine-viewer/viewer')
const pathfinder = require('mineflayer-pathfinder')
const { Vec3 } = require('vec3')
global.THREE = require('three')
-const Chat = require('./lib/chat')
const maxPitch = 0.5 * Math.PI
const minPitch = -0.5 * Math.PI
@@ -25,8 +25,7 @@ async function main () {
menu.style = 'display: none;'
document.getElementById('hotbar').style = 'display:block'
document.getElementById('crosshair').style = 'display:block'
- document.getElementById('chat-wrapper').style = 'display:block'
- document.getElementById('chat-wrapper2').style = 'display:block'
+ document.getElementById('chatbox').style = 'display:block'
document.getElementById('loading-background').style = 'display:block'
connect(options)
@@ -36,6 +35,7 @@ async function main () {
async function connect (options) {
const loadingScreen = document.getElementById('loading-background')
const hotbar = document.getElementById('hotbar')
+ const chat = document.getElementById('chatbox')
const viewDistance = 6
const hostprompt = options.server
@@ -119,7 +119,7 @@ async function connect (options) {
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
- const chat = Chat.init(bot._client, renderer)
+ chat.init(bot._client, renderer)
// Create viewer
const viewer = new Viewer(renderer)
diff --git a/lib/chat.js b/lib/chat.js
index 6cb196b..3eb90fd 100644
--- a/lib/chat.js
+++ b/lib/chat.js
@@ -1,3 +1,5 @@
+const { LitElement, html, css } = require('lit-element')
+
const styles = {
black: 'color:#000000',
dark_blue: 'color:#0000AA',
@@ -33,193 +35,254 @@ const dictionary = {
'chat.type.text': '<%s> %s'
}
-export function init (client, renderer) {
- const chat = document.querySelector('#chat')
- const chatInput = document.querySelector('#chatinput')
+class ChatBox extends LitElement {
+ static get styles () {
+ return css`
+ .chat-wrapper {
+ position: fixed;
+ background-color: rgba(0, 0, 0, 0.5);
+ z-index:10;
+ }
- const chatHistory = []
- let chatHistoryPos = 0
+ .chat-display-wrapper {
+ bottom: calc(8px * 16);
+ padding: 4px;
+ max-height: calc(90px * 8);
+ width: calc(320px * 4);
+ }
- renderer.domElement.requestPointerLock = renderer.domElement.requestPointerLock ||
- renderer.domElement.mozRequestPointerLock ||
- renderer.domElement.webkitRequestPointerLock
+ .chat-input-wrapper {
+ bottom: calc(2px * 16);
+ width: 100%;
+ overflow: hidden;
+ background-color: rgba(0, 0, 0, 0);
+ }
- // Show chat
- chat.style.display = 'block'
+ .chat {
+ overflow: hidden;
+ color: white;
+ font-size: 16px;
+ margin: 0px;
+ line-height: 100%;
+ text-shadow: 2px 2px 0px #3f3f3f;
+ font-family: mojangles, minecraft, monospace;
+ width: 100%;
+ max-height: calc(90px * 8)
+ }
- const chatState = {
- inChat: false
+ input[type=text], #chatinput {
+ background-color: rgba(0, 0, 0, 0.5);
+ display: none;
+ }
+
+ li {
+ display: block;
+ }
+ `
}
- // Esc event - Doesnt work with onkeypress?!
- document.onkeydown = function (e) {
- if (!chatState.inChat) return
- e = e || window.event
- if (e.keyCode === 27 || e.key === 'Escape' || e.key === 'Esc') {
- disableChat()
- } else if (e.keyCode === 38) {
- if (chatHistoryPos === 0) return
- chatInput.value = chatHistory[--chatHistoryPos] !== undefined ? chatHistory[chatHistoryPos] : ''
- } else if (e.keyCode === 40) {
- if (chatHistoryPos === chatHistory.length) return
- chatInput.value = chatHistory[++chatHistoryPos] !== undefined ? chatHistory[chatHistoryPos] : ''
+ render () {
+ return html`
+
+
+
Welcome to prismarine-web-client! Chat appears here.
+
+
+
+ `
+ }
+
+ init (client, renderer) {
+ this.inChat = false
+ const chat = this.shadowRoot.querySelector('#chat')
+ const chatInput = this.shadowRoot.querySelector('#chatinput')
+
+ const chatHistory = []
+ let chatHistoryPos = 0
+
+ renderer.domElement.requestPointerLock = renderer.domElement.requestPointerLock ||
+ renderer.domElement.mozRequestPointerLock ||
+ renderer.domElement.webkitRequestPointerLock
+
+ // Show chat
+ chat.style.display = 'block'
+
+ const self = this
+
+ // Esc event - Doesnt work with onkeypress?!
+ document.onkeydown = function (e) {
+ if (!self.inChat) return
+ e = e || window.event
+ if (e.keyCode === 27 || e.key === 'Escape' || e.key === 'Esc') {
+ disableChat()
+ } else if (e.keyCode === 38) {
+ if (chatHistoryPos === 0) return
+ chatInput.value = chatHistory[--chatHistoryPos] !== undefined ? chatHistory[chatHistoryPos] : ''
+ } else if (e.keyCode === 40) {
+ if (chatHistoryPos === chatHistory.length) return
+ chatInput.value = chatHistory[++chatHistoryPos] !== undefined ? chatHistory[chatHistoryPos] : ''
+ }
}
- }
- // Chat events
- document.onkeypress = function (e) {
- e = e || window.event
- if (chatState.inChat === false) {
- if (e.code === 'KeyT') {
- enableChat(false)
+ // Chat events
+ document.onkeypress = function (e) {
+ e = e || window.event
+ if (self.inChat === false) {
+ if (e.code === 'KeyT') {
+ enableChat(false)
+ }
+
+ if (e.code === 'Slash') {
+ enableChat(true)
+ }
+ return false
}
- if (e.code === 'Slash') {
- enableChat(true)
+ if (!self.inChat) return
+ e.stopPropagation()
+ if (e.code === 'Enter') {
+ chatHistory.push(chatInput.value)
+ client.write('chat', { message: chatInput.value })
+ disableChat()
}
- return false
+ }
+ // Enable inputs back when focused
+ /* document.addEventListener("pointerlockchange", function(event) {
+ const canvas = document.getElementById("noa-canvas");
+ if (
+ document.pointerLockElement === canvas ||
+ document.mozPointerLockElement === canvas
+ ) {
+ // Someone focused the game back so we hide chat.
+ chatState.inChat = false;
+ hideChat();
+ }
+ }); */
+ function enableChat (isCommand) {
+ // Set inChat value
+ self.inChat = true
+ // Exit the pointer lock
+ document.exitPointerLock()
+ // Show chat input
+ chatInput.style.display = 'block'
+ // Show extended chat history
+ chat.style.maxHeight = 'calc(90px * 8)'
+ chat.scrollTop = chat.scrollHeight // Stay bottom of the list
+ if (isCommand) { // handle commands
+ chatInput.value = '/'
+ }
+ // Focus element
+ chatInput.focus()
+ chatHistoryPos = chatHistory.length
}
- if (!chatState.inChat) return
- e.stopPropagation()
- if (e.code === 'Enter') {
- chatHistory.push(chatInput.value)
- client.write('chat', { message: chatInput.value })
- disableChat()
+ function disableChat () {
+ // Set inChat value
+ self.inChat = false
+
+ // Hide chat
+ hideChat()
+
+ renderer.domElement.requestPointerLock()
}
- }
- // Enable inputs back when focused
- /* document.addEventListener("pointerlockchange", function(event) {
- const canvas = document.getElementById("noa-canvas");
- if (
- document.pointerLockElement === canvas ||
- document.mozPointerLockElement === canvas
- ) {
- // Someone focused the game back so we hide chat.
- chatState.inChat = false;
- hideChat();
+
+ function hideChat () {
+ // Clear chat input
+ chatInput.value = ''
+ // Unfocus it
+ chatInput.blur()
+ // Hide it
+ chatInput.style.display = 'none'
+ // Hide extended chat history
+ chat.style.maxHeight = 'calc(90px * 4)'
+ chat.scrollTop = chat.scrollHeight // Stay bottom of the list
}
- }); */
- function enableChat (isCommand) {
- // Set inChat value
- chatState.inChat = true
- // Exit the pointer lock
- document.exitPointerLock()
- // Show chat input
- chatInput.style.display = 'block'
- // Show extended chat history
- chat.style.maxHeight = 'calc(90px * 8)'
- chat.scrollTop = chat.scrollHeight // Stay bottom of the list
- if (isCommand) { // handle commands
- chatInput.value = '/'
+
+ function readExtra (extra) {
+ const shouldReturn = []
+ for (const i in extra) {
+ if (extra[i].text) {
+ shouldReturn.push({
+ text: extra[i].text,
+ color: extra[i].color,
+ bold: !!extra[i].bold,
+ italic: !!extra[i].italic,
+ underlined: !!extra[i].underlined,
+ strikethrough: !!extra[i].strikethrough,
+ obfuscated: !!extra[i].obfuscated
+ })
+ } else {
+ readExtra(extra).forEach(function (el) {
+ shouldReturn.push(el)
+ })
+ }
+ }
+ return shouldReturn
}
- // Focus element
- chatInput.focus()
- chatHistoryPos = chatHistory.length
- }
- function disableChat () {
- // Set inChat value
- chatState.inChat = false
-
- // Hide chat
- hideChat()
-
- renderer.domElement.requestPointerLock()
- }
-
- function hideChat () {
- // Clear chat input
- chatInput.value = ''
- // Unfocus it
- chatInput.blur()
- // Hide it
- chatInput.style.display = 'none'
- // Hide extended chat history
- chat.style.maxHeight = 'calc(90px * 4)'
- chat.scrollTop = chat.scrollHeight // Stay bottom of the list
- }
-
- function readExtra (extra) {
- const shouldReturn = []
- for (const i in extra) {
- if (extra[i].text) {
- shouldReturn.push({
- text: extra[i].text,
- color: extra[i].color,
- bold: !!extra[i].bold,
- italic: !!extra[i].italic,
- underlined: !!extra[i].underlined,
- strikethrough: !!extra[i].strikethrough,
- obfuscated: !!extra[i].obfuscated
+ client.on('chat', (packet) => {
+ // Reading of chat message
+ const fullmessage = JSON.parse(packet.message.toString())
+ let msglist = []
+ if (
+ fullmessage.extra &&
+ fullmessage.extra.length > 0 &&
+ !fullmessage.translate
+ ) {
+ msglist = readExtra(fullmessage.extra)
+ } else if (fullmessage.text && fullmessage.text.length > 0) {
+ msglist.push({ text: fullmessage.text, color: undefined })
+ } else if (dictionary[fullmessage.translate]) {
+ let msg = dictionary[fullmessage.translate]
+ fullmessage.with.forEach(obj => {
+ if (obj.insertion && obj.text) {
+ msg = msg.replace('%s', obj.text)
+ }
+ if (obj.extra) {
+ if (obj.text && obj.text.length > 0) {
+ msglist.push({ text: obj.text, color: undefined })
+ } else {
+ const text = readExtra(obj.extra)
+ if (text.length > 1) {
+ console.log('Unsupported chat alert :(')
+ }
+ msg = msg.replace('%s', text[0].text)
+ msglist.push({ text: msg, color: undefined })
+ }
+ }
})
} else {
- readExtra(extra).forEach(function (el) {
- shouldReturn.push(el)
- })
+ // msglist.push({
+ // text:
+ // "Unsupported message (Please report this):\n" +
+ // JSON.stringify(fullmessage),
+ // color: undefined
+ // });
}
- }
- return shouldReturn
- }
-
- client.on('chat', (packet) => {
- // Reading of chat message
- const fullmessage = JSON.parse(packet.message.toString())
- let msglist = []
- if (
- fullmessage.extra &&
- fullmessage.extra.length > 0 &&
- !fullmessage.translate
- ) {
- msglist = readExtra(fullmessage.extra)
- } else if (fullmessage.text && fullmessage.text.length > 0) {
- msglist.push({ text: fullmessage.text, color: undefined })
- } else if (dictionary[fullmessage.translate]) {
- let msg = dictionary[fullmessage.translate]
- fullmessage.with.forEach(obj => {
- if (obj.insertion && obj.text) {
- msg = msg.replace('%s', obj.text)
- }
- if (obj.extra) {
- if (obj.text && obj.text.length > 0) {
- msglist.push({ text: obj.text, color: undefined })
- } else {
- const text = readExtra(obj.extra)
- if (text.length > 1) {
- console.log('Unsupported chat alert :(')
- }
- msg = msg.replace('%s', text[0].text)
- msglist.push({ text: msg, color: undefined })
- }
- }
+ const li = document.createElement('li')
+ msglist.forEach(msg => {
+ const span = document.createElement('span')
+ span.appendChild(document.createTextNode(msg.text))
+ span.setAttribute(
+ 'style',
+ `${msg.color ? styles[msg.color.toLowerCase()] : styles.white}; ${
+ msg.bold ? styles.bold + ';' : ''
+ }${msg.italic ? styles.italic + ';' : ''}${
+ msg.strikethrough ? styles.strikethrough + ';' : ''
+ }${msg.underlined ? styles.underlined + ';' : ''}`
+ )
+ li.appendChild(span)
})
- } else {
- // msglist.push({
- // text:
- // "Unsupported message (Please report this):\n" +
- // JSON.stringify(fullmessage),
- // color: undefined
- // });
- }
- const li = document.createElement('li')
- msglist.forEach(msg => {
- const span = document.createElement('span')
- span.appendChild(document.createTextNode(msg.text))
- span.setAttribute(
- 'style',
- `${msg.color ? styles[msg.color.toLowerCase()] : styles.white}; ${
- msg.bold ? styles.bold + ';' : ''
- }${msg.italic ? styles.italic + ';' : ''}${
- msg.strikethrough ? styles.strikethrough + ';' : ''
- }${msg.underlined ? styles.underlined + ';' : ''}`
- )
- li.appendChild(span)
+ chat.appendChild(li)
+ chat.scrollTop = chat.scrollHeight // Stay bottom of the list
})
- chat.appendChild(li)
- chat.scrollTop = chat.scrollHeight // Stay bottom of the list
- })
- hideChat()
-
- return chatState
+ hideChat()
+ }
}
+
+window.customElements.define('chat-box', ChatBox)
diff --git a/lib/loading_screen.js b/lib/loading_screen.js
index 450f474..51370ff 100644
--- a/lib/loading_screen.js
+++ b/lib/loading_screen.js
@@ -34,16 +34,6 @@ class LoadingScreen extends LitElement {
static get styles () {
return css`
- @font-face {
- font-family: minecraft;
- src: url(minecraftia.woff);
- }
-
- @font-face {
- font-family: mojangles;
- src: url(mojangles.ttf);
- }
-
h1 {
font-family: mojangles, minecraft, monospace;
}
diff --git a/styles.css b/styles.css
index e2fbf86..3b19594 100644
--- a/styles.css
+++ b/styles.css
@@ -1,22 +1,28 @@
-@font-face {
- font-family: minecraft;
- src: url(minecraftia.woff);
-}
-
-@font-face {
- font-family: mojangles;
- src: url(mojangles.ttf);
-}
-
html {
height: 100%;
overflow: hidden;
}
+
+@font-face {
+ font-family: minecraft;
+ src: url(minecraftia.woff);
+}
+
+@font-face {
+ font-family: mojangles;
+ src: url(mojangles.ttf);
+}
body {
margin:0;
padding:0;
font-family: sans-serif;
background: linear-gradient(#141e30, #243b55);
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
canvas {
@@ -27,46 +33,6 @@ canvas {
padding: 0;
}
-.chat-wrapper {
- position: fixed;
- background-color: rgba(0, 0, 0, 0.5);
-}
-
-.chat-display-wrapper {
- bottom: calc(8px * 16);
- padding: 4px;
- max-height: calc(90px * 8);
- width: calc(320px * 4);
-}
-
-.chat-input-wrapper {
- bottom: calc(2px * 16);
- width: 100%;
- overflow: hidden;
- background-color: rgba(0, 0, 0, 0);
-}
-
-.chat {
- overflow: hidden;
- color: white;
- font-size: 16px;
- margin: 0px;
- line-height: 100%;
- text-shadow: 2px 2px 0px #3f3f3f;
- font-family: mojangles, minecraft, monospace;
- width: 100%;
- max-height: calc(90px * 8)
-}
-
-input[type=text], #chatinput {
- background-color: rgba(0, 0, 0, 0.5);
- display: none;
-}
-
-li {
- display: block;
-}
-
#crosshair {
image-rendering: optimizeSpeed;
image-rendering: -moz-crisp-edges;
@@ -82,12 +48,3 @@ li {
transform: translate(calc(-50% + 120px * 4), calc(-50% + 120px * 4));
clip-path: inset(0px calc(240px * 4) calc(240px * 4) 0px);
}
-
-body {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}