Total change, Adding a GUI
This commit is contained in:
parent
4d31a133a9
commit
202a920815
@ -1,4 +1,4 @@
|
|||||||
{
|
x{
|
||||||
"name": "sshchat",
|
"name": "sshchat",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "A peer to peer chat client that uses hyper-protocol and connects to the ssh.surf API",
|
"description": "A peer to peer chat client that uses hyper-protocol and connects to the ssh.surf API",
|
||||||
@ -14,9 +14,11 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"b4a": "^1.6.1",
|
"b4a": "^1.6.1",
|
||||||
|
"blessed": "^0.1.81",
|
||||||
"graceful-goodbye": "^1.2.0",
|
"graceful-goodbye": "^1.2.0",
|
||||||
"hypercore-crypto": "^3.3.0",
|
"hypercore-crypto": "^3.3.0",
|
||||||
"hyperswarm": "^4.3.5",
|
"hyperswarm": "^4.3.5",
|
||||||
|
"neo-blessed": "^0.2.0",
|
||||||
"readline": "^1.3.0",
|
"readline": "^1.3.0",
|
||||||
"unirest": "^0.6.0"
|
"unirest": "^0.6.0"
|
||||||
}
|
}
|
||||||
|
152
sshChat.js
152
sshChat.js
@ -1,3 +1,4 @@
|
|||||||
|
const blessed = require('neo-blessed');
|
||||||
// Require the needed libs
|
// Require the needed libs
|
||||||
const Hyperswarm = require('hyperswarm')
|
const Hyperswarm = require('hyperswarm')
|
||||||
const crypto = require('hypercore-crypto')
|
const crypto = require('hypercore-crypto')
|
||||||
@ -22,6 +23,7 @@ let DAPI_KEY
|
|||||||
let LOGGEDIN = false
|
let LOGGEDIN = false
|
||||||
let MYKEY = []
|
let MYKEY = []
|
||||||
let conns = []
|
let conns = []
|
||||||
|
let connectedUsers = [];
|
||||||
let USERNAME = ["annon" + rand]
|
let USERNAME = ["annon" + rand]
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
@ -30,10 +32,104 @@ function sleep(ms) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clearCursor() {
|
|
||||||
readline.moveCursor(process.stdout, 0, -2) // up one line
|
function addUser(user, peerId) {
|
||||||
readline.clearLine(process.stdout, 0) // from cursor to end
|
connectedUsers.push({ name: user, peerId: peerId });
|
||||||
readline.moveCursor(process.stdout, 0, 2) // up one line
|
sidebarBox.setContent(connectedUsers.map(user => `${user.name} - ${user.peerId}`).join("\n"));
|
||||||
|
screen.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeUser(peerId) {
|
||||||
|
connectedUsers = connectedUsers.filter(user => user.peerId !== peerId);
|
||||||
|
sidebarBox.setContent("Connected Peers: \n" + connectedUsers.map(user => `${user.name} - ${user.peerId}`).join("\n"));
|
||||||
|
screen.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the screen
|
||||||
|
const screen = blessed.screen({
|
||||||
|
smartCSR: true,
|
||||||
|
fastCSR: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let mainBox = blessed.box({
|
||||||
|
parent: screen,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '80%',
|
||||||
|
height: '80%',
|
||||||
|
border: {
|
||||||
|
type: 'line'
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fg: 'white',
|
||||||
|
bg: 'black'
|
||||||
|
},
|
||||||
|
keys: true,
|
||||||
|
vi: true,
|
||||||
|
alwaysScroll: true,
|
||||||
|
scrollable: true,
|
||||||
|
scrollbar: {
|
||||||
|
style: {
|
||||||
|
bg: 'yellow'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function updateScroll() {
|
||||||
|
mainBox.scrollTo(mainBox.getScrollHeight());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the STDIN box for chat input and command input
|
||||||
|
const stdinBox = blessed.textbox({
|
||||||
|
bottom: '0',
|
||||||
|
left: '0',
|
||||||
|
width: '80%',
|
||||||
|
height: '21%',
|
||||||
|
border: {
|
||||||
|
type: 'line'
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fg: 'white',
|
||||||
|
bg: 'black',
|
||||||
|
border: {
|
||||||
|
fg: '#f0f0f0'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
inputOnFocus: true,
|
||||||
|
input: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the sidebar box for connected peers
|
||||||
|
const sidebarBox = blessed.box({
|
||||||
|
top: '0',
|
||||||
|
right: '0',
|
||||||
|
width: '20%',
|
||||||
|
height: '100%',
|
||||||
|
content: '',
|
||||||
|
border: {
|
||||||
|
type: 'line'
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fg: 'white',
|
||||||
|
bg: 'black',
|
||||||
|
border: {
|
||||||
|
fg: '#f0f0f0'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sidebarBox.setLabel("Connected Peers: (Currently None)")
|
||||||
|
|
||||||
|
|
||||||
|
const originalLog = console.log;
|
||||||
|
console.log = (...args) => {
|
||||||
|
mainBox.setContent(mainBox.getContent() + `\n${args.join(' ')}`);
|
||||||
|
updateScroll()
|
||||||
|
stdinBox.clearValue();
|
||||||
|
|
||||||
|
screen.render()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a random public key
|
// Generate a random public key
|
||||||
@ -104,7 +200,6 @@ async function handleCommand(input) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
console.log(`${USERNAME[0]}: ${input}`)
|
console.log(`${USERNAME[0]}: ${input}`)
|
||||||
clearCursor()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
swarm.on('connection', conn => {
|
swarm.on('connection', conn => {
|
||||||
@ -122,12 +217,16 @@ swarm.on('connection', conn => {
|
|||||||
|
|
||||||
const name = b4a.toString(conn.remotePublicKey, 'hex')
|
const name = b4a.toString(conn.remotePublicKey, 'hex')
|
||||||
console.log(`* got a connection from ${name} (${USERNAME[0]}) *`)
|
console.log(`* got a connection from ${name} (${USERNAME[0]}) *`)
|
||||||
|
addUser(USERNAME[0], name)
|
||||||
|
sidebarBox.setLabel("Connected Peers: " + connectedUsers.length)
|
||||||
|
screen.render()
|
||||||
conns.push(conn)
|
conns.push(conn)
|
||||||
conn.once('close', () => conns.splice(conns.indexOf(conn), 1))
|
conn.once('close', () => conns.splice(conns.indexOf(conn), 1))
|
||||||
conn.on('data', data => {
|
conn.on('data', data => {
|
||||||
if (data.toString().startsWith('CLOSED:')) {
|
if (data.toString().startsWith('CLOSED:')) {
|
||||||
// Extract the key from the message string
|
// Extract the key from the message string
|
||||||
const key = data.toString().split(':')[1].trim();
|
const key = data.toString().split(':')[1].trim();
|
||||||
|
removeUser(key)
|
||||||
console.log(`Removing peer ${key}`);
|
console.log(`Removing peer ${key}`);
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
@ -147,20 +246,11 @@ swarm.on('error', (err) => {
|
|||||||
console.log('Error connecting to peer:', err);
|
console.log('Error connecting to peer:', err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Use readline to accept input from the user
|
|
||||||
const rl = readline.createInterface({
|
|
||||||
input: process.stdin,
|
|
||||||
output: process.stdout
|
|
||||||
})
|
|
||||||
|
|
||||||
// When the user inputs a line of text, broadcast it to all connections
|
|
||||||
rl.on('line', input => {
|
|
||||||
handleCommand(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Join a common topic
|
// Join a common topic
|
||||||
const topic = process.argv[2] ? b4a.from(process.argv[2], 'hex') : crypto.randomBytes(32)
|
const topic = process.argv[2] ? b4a.from(process.argv[2], 'hex') : crypto.randomBytes(32)
|
||||||
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const discovery = swarm.join(topic, {
|
const discovery = swarm.join(topic, {
|
||||||
lookup: true,
|
lookup: true,
|
||||||
@ -171,10 +261,36 @@ setTimeout(() => {
|
|||||||
|
|
||||||
// The flushed promise will resolve when the topic has been fully announced to the DHT
|
// The flushed promise will resolve when the topic has been fully announced to the DHT
|
||||||
discovery.flushed().then(() => {
|
discovery.flushed().then(() => {
|
||||||
console.log(`joined topic: ${b4a.toString(topic, 'hex')}\n(Share this key to others so they may join.)`)
|
mainBox.setLabel("Topic: " + b4a.toString(topic, 'hex') + " (Share to connect)")
|
||||||
console.log('You are now in a chatroom for your topic, feel free to chat.\n')
|
stdinBox.setLabel("To login: >login [TOKEN]")
|
||||||
console.log('Want to login to the SSH.SURF API? Type ">login [APIKEY]" to login.\nPease close using CTRL+X or use the >exit command\n')
|
screen.render()
|
||||||
})
|
})
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Append the boxes to the screen
|
||||||
|
screen.append(mainBox);
|
||||||
|
screen.append(stdinBox);
|
||||||
|
screen.append(sidebarBox);
|
||||||
|
|
||||||
|
|
||||||
|
// Handle input in the stdinBox
|
||||||
|
stdinBox.on('submit', (input) => {
|
||||||
|
// handle the input here
|
||||||
|
// for example :
|
||||||
|
handleCommand(input);
|
||||||
|
// clear the input field
|
||||||
|
stdinBox.focus();
|
||||||
|
|
||||||
|
// screen.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
// setInterval(() => {
|
||||||
|
// mainBox.scrollTo(mainBox.getScrollHeight());
|
||||||
|
// }, 1000);
|
||||||
|
stdinBox.focus();
|
||||||
|
// Render the screen
|
||||||
|
|
||||||
|
screen.render()
|
Loading…
Reference in New Issue
Block a user