contact
Version:
private, one-to-one or many-to-many command line chat
98 lines (87 loc) • 2.41 kB
JavaScript
import * as iterm from './iterm.js'
import * as readline from 'node:readline'
import ansi from 'ansi-escape-sequences'
import util from 'node:util'
class CliView extends EventTarget {
rl
roomId
outputStream
init (options = {}) {
this.outputStream = options.output
this.rl = readline.createInterface({
input: options.input,
output: options.output,
completer: options.completer,
history: options.history,
removeHistoryDuplicates: true,
tabSize: 2
})
this.rl.prompt()
this.rl.on('line', line => {
if (this.outputStream.isTTY) {
this.outputStream.moveCursor(0, -1)
}
this.dispatchEvent(new CustomEvent('line', { detail: line.trim() }))
this.rl.prompt()
})
this.rl.on('close', () => {
this.dispatchEvent(new CustomEvent('close'))
})
this.rl.on('SIGCONT', () => {
this.rl.resume()
})
this.rl.on('history', (history) => {
this.dispatchEvent(new CustomEvent('history', { detail: history }))
})
}
clearLine () {
if (this.outputStream?.isTTY) {
this.outputStream.clearLine(0)
this.outputStream.cursorTo(0)
}
}
setRoomId (roomId) {
this.roomId = roomId
this.rl.setPrompt(`[${roomId}] > `)
iterm.badge(roomId)
}
async displayMessage (msg, options = {}) {
this.clearLine()
if (typeof msg === 'string') {
this.outputStream.write(msg + '\n')
} else {
this.outputStream.write(util.inspect(msg, { colors: true }) + '\n')
}
if (!options.skipPrompt) {
this?.rl?.prompt(true)
}
}
async displayMessages (msgs, options = {}) {
}
async displayNotification (headers, options = {}) {
this.clearLine()
const subType = headers['sub-type']
const roomId = headers['room-id']
const from = headers.from
let text = ''
if (subType === 'join-room') {
text = `${from} joined the room`
} else if (subType === 'leave-room') {
text = `${from} left the room`
} else if (subType === 'unread-message') {
text = `Unread message in room ${roomId} from ${from}`
} else {
text = `${subType} ${from}`
}
this.outputStream.write(ansi.format(text, ['yellow', 'italic']) + '\n')
if (!options.skipPrompt) {
this.rl.prompt(true)
}
}
close () {
this.clearLine()
this.rl?.close()
iterm.badge()
}
}
export default CliView