Add web client, update CLI client
This commit is contained in:
parent
41c9e7f53f
commit
a4b6721ebc
|
@ -2,6 +2,8 @@ package xyz.maxwellj.chookpen.client
|
||||||
|
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import java.util.Scanner
|
import java.util.Scanner
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -52,7 +54,7 @@ fun main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val client = OkHttpClient.Builder()
|
val client = OkHttpClient.Builder()
|
||||||
//.pingInterval(30, TimeUnit.SECONDS)
|
.pingInterval(30, TimeUnit.SECONDS)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
|
|
BIN
client-web/InterVariable.ttf
Normal file
BIN
client-web/InterVariable.ttf
Normal file
Binary file not shown.
137
client-web/index.css
Normal file
137
client-web/index.css
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "inter";
|
||||||
|
src: url("InterVariable.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: white;
|
||||||
|
background: rgb(231,255,68);
|
||||||
|
background: linear-gradient(336deg, rgba(231,255,68,0.67) 0%, rgba(73,255,145,0.67) 43%, rgba(104,79,255,1) 100%);
|
||||||
|
font-family: inter;
|
||||||
|
background-attachment: fixed;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
color: white;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
font-family: "inter";
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiny {
|
||||||
|
font-size: 5pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 20pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 15pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messagebox {
|
||||||
|
overflow-y: auto;
|
||||||
|
border 0px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 50%;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
color: white;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
max-width: 95%;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box p {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.box h3 {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.box img {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.box button {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bluebutton {
|
||||||
|
color: white;
|
||||||
|
font-size: 12pt;
|
||||||
|
background: rgba(0, 0, 255, 0.3);
|
||||||
|
font-family: inter;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.greenbutton {
|
||||||
|
color: white;
|
||||||
|
font-size: 12pt;
|
||||||
|
background: rgba(0, 255, 0, 0.3);
|
||||||
|
font-family: inter;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.redbutton {
|
||||||
|
color: white;
|
||||||
|
font-size: 12pt;
|
||||||
|
background: rgba(255, 0, 0, 0.3);
|
||||||
|
font-family: inter;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.backbutton {
|
||||||
|
color: white;
|
||||||
|
font-size: 12pt;
|
||||||
|
background: rgba(255, 0, 0, 0.3);
|
||||||
|
font-family: inter;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
43
client-web/index.html
Normal file
43
client-web/index.html
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Chookpen</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="index.css">
|
||||||
|
<link rel="shortcut icon" type="image/jpg" href="favicon.ico"/>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="login">
|
||||||
|
<div class="section">
|
||||||
|
<div class="box">
|
||||||
|
<h3>Chookpen</h3>
|
||||||
|
<input type="text" id="username" placeholder="Username"><br>
|
||||||
|
<input type="password" id="password" placeholder="Password"><br>
|
||||||
|
<button class="bluebutton" onclick="connect()">Log in</button>
|
||||||
|
<button class="greenbutton" onclick="register()">Register</button>
|
||||||
|
<button class="redbutton" onclick="showConfig()">Show Server Config</button>
|
||||||
|
<div id="serverStatus"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box" style="display: none;" id="serverconfig">
|
||||||
|
<input type="text" id="serverUrl" value="bobcompass.online" placeholder="Server URL"><br>
|
||||||
|
<input type="text" id="serverPort" value="443" placeholder="Server Port"><br>
|
||||||
|
<input type="checkbox" id="securityStatus" checked>
|
||||||
|
<label for="securityStatus">Use HTTPS/WSS</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hidden" id="messaging">
|
||||||
|
<div class="section">
|
||||||
|
<div class="box">
|
||||||
|
<h3>Chookpen</h3>
|
||||||
|
<div id="messagebox" class="box" style="height: 600px;"><div style="color: grey;">Chookpen for Web is ready. Happy chatting!</div></div>
|
||||||
|
<input type="text" id="messageInput" placeholder="Send a message...">
|
||||||
|
<button onclick="sendMessage()" class="bluebutton">Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
117
client-web/index.js
Normal file
117
client-web/index.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
alert("Chookpen is currently in early development, expect bugs! Please don't try breaking the public server, do that with your own test server (read more in the Git repo). Thanks for trying Chookpen!")
|
||||||
|
|
||||||
|
let ws;
|
||||||
|
let username;
|
||||||
|
let password;
|
||||||
|
|
||||||
|
function showConfig() {
|
||||||
|
const serverconfig = document.getElementById('serverconfig')
|
||||||
|
if (serverconfig) {
|
||||||
|
serverconfig.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function md5(string) {
|
||||||
|
return CryptoJS.MD5(string).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUrl() {
|
||||||
|
const serverUrl = document.getElementById('serverUrl').value.trim();
|
||||||
|
const serverPort = document.getElementById('serverPort').value;
|
||||||
|
const useWss = document.getElementById('securityStatus').checked;
|
||||||
|
const protocol = useWss ? 'wss' : 'ws';
|
||||||
|
|
||||||
|
const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
|
||||||
|
|
||||||
|
return `${protocol}://${cleanUrl}:${serverPort}/api/websocket`;
|
||||||
|
}
|
||||||
|
function getSignupUrl() {
|
||||||
|
const serverUrl = document.getElementById('serverUrl').value.trim();
|
||||||
|
const serverPort = document.getElementById('serverPort').value;
|
||||||
|
const useWss = document.getElementById('securityStatus').checked;
|
||||||
|
const protocol = useWss ? 'https' : 'http';
|
||||||
|
|
||||||
|
const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
|
||||||
|
|
||||||
|
return `${protocol}://${cleanUrl}:${serverPort}/api/createaccount/`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
username = document.getElementById('username').value;
|
||||||
|
password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
alert('Please enter a username and password');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wsUrl = getUrl();
|
||||||
|
if (ws) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
Notification.requestPermission();
|
||||||
|
console.log('Connected!');
|
||||||
|
document.getElementById('login').style.display = 'none';
|
||||||
|
document.getElementById('messaging').style.display = 'block';
|
||||||
|
ws.send(`username:{${username}}token:{${md5(password)}}command:{login}commandArg:{${username}}`);
|
||||||
|
ws.send(`username:{${username}}token:{${md5(password)}}message:{Joined the room}`);
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
if (event.data === "ping") {
|
||||||
|
ws.send("pong");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(event.data);
|
||||||
|
const messagesDiv = document.getElementById('messagebox');
|
||||||
|
const messageElement = document.createElement('div');
|
||||||
|
if (messageElement) {
|
||||||
|
if (messagesDiv) {
|
||||||
|
messagesDiv.appendChild(messageElement);
|
||||||
|
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
||||||
|
messageElement.className = 'message';
|
||||||
|
messageElement.textContent = event.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (document.hidden) {
|
||||||
|
const notifiction = new Notification("Chookpen", {body: messageElement.textContent});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendMessage() {
|
||||||
|
const messageInput = document.getElementById('messageInput');
|
||||||
|
const message = messageInput.value.trim();
|
||||||
|
|
||||||
|
if (message && ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
ws.send(`username:{${username}}token:{${md5(password)}}message:{${message}}`);
|
||||||
|
messageInput.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('messageInput').addEventListener('keypress', (event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('password').addEventListener('keypress', (event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function register() {
|
||||||
|
username = document.getElementById('username').value;
|
||||||
|
password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
alert('Please enter a username and password');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(`${getSignupUrl()}username:{${username}}token:{${md5(password)}}`);
|
||||||
|
}
|
|
@ -13,6 +13,9 @@ import java.io.BufferedReader
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
fun md5(input:String): String {
|
fun md5(input:String): String {
|
||||||
val md = MessageDigest.getInstance("MD5")
|
val md = MessageDigest.getInstance("MD5")
|
||||||
return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
|
return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
|
||||||
|
@ -447,8 +450,11 @@ fun authKey(inputData: String): String {
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
WsSessionManager.peopleOnline.removeAt(0)
|
WsSessionManager.peopleOnline.removeAt(0)
|
||||||
WsSessionManager.sessionsList.removeAt(0)
|
WsSessionManager.sessionsList.removeAt(0)
|
||||||
val app = Javalin.create()
|
val app = Javalin.create { config ->
|
||||||
.get("/") { ctx -> ctx.result("dingus") }
|
config.staticFiles.add("/public")
|
||||||
|
}.get("/") { ctx ->
|
||||||
|
ctx.redirect("/index.html")
|
||||||
|
}
|
||||||
.get("/api/send/{content}") { ctx ->
|
.get("/api/send/{content}") { ctx ->
|
||||||
val result = handleSentMessage(ctx.pathParam("content"))
|
val result = handleSentMessage(ctx.pathParam("content"))
|
||||||
if (result == "Success") {
|
if (result == "Success") {
|
||||||
|
|
1
server/src/main/resources/public/InterVariable.ttf
Symbolic link
1
server/src/main/resources/public/InterVariable.ttf
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../client-web/InterVariable.ttf
|
1
server/src/main/resources/public/index.css
Symbolic link
1
server/src/main/resources/public/index.css
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../client-web/index.css
|
1
server/src/main/resources/public/index.html
Symbolic link
1
server/src/main/resources/public/index.html
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../client-web/index.html
|
1
server/src/main/resources/public/index.js
Symbolic link
1
server/src/main/resources/public/index.js
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../client-web/index.js
|
Loading…
Reference in New Issue
Block a user