UNPKG

@noffle/cabal

Version:
147 lines (121 loc) 4.64 kB
var output = require('./output') var chalk = require('chalk') var blit = require('txt-blit') var util = require('./util') const HEADER_ROWS = 6 module.exports = { big, small } function small (state) { var screen = [] var titlebarSize = Math.ceil(linkSize(state) / process.stdout.columns) // title bar blit(screen, renderTitlebar(state, process.stdout.columns), 0, titlebarSize - 1) // chat messages blit(screen, renderMessages(state, process.stdout.columns, process.stdout.rows - HEADER_ROWS), 0, 3) // horizontal dividers blit(screen, renderHorizontalLine('-', process.stdout.columns, chalk.blue), 0, process.stdout.rows - 2) blit(screen, renderHorizontalLine('-', process.stdout.columns, chalk.blue), 0, titlebarSize + 1) // user input prompt blit(screen, renderPrompt(state), 0, process.stdout.rows - 1) return output(screen.join('\n')) } function big (state) { var screen = [] // title bar blit(screen, renderTitlebar(state, process.stdout.columns), 0, 0) // channels pane blit(screen, renderChannels(state, 16, process.stdout.rows - HEADER_ROWS), 0, 3) // chat messages blit(screen, renderMessages(state, process.stdout.columns - 17 - 17, process.stdout.rows - HEADER_ROWS), 18, 3) // nicks pane blit(screen, renderNicks(state, 15, process.stdout.rows - HEADER_ROWS), process.stdout.columns - 15, 3) // vertical dividers blit(screen, renderVerticalLine('|', process.stdout.rows - 6, chalk.blue), 16, 3) blit(screen, renderVerticalLine('|', process.stdout.rows - 6, chalk.blue), process.stdout.columns - 17, 3) // horizontal dividers blit(screen, renderHorizontalLine('-', process.stdout.columns, chalk.blue), 0, process.stdout.rows - 3) blit(screen, renderHorizontalLine('-', process.stdout.columns, chalk.blue), 0, 2) // user input prompt blit(screen, renderPrompt(state), 0, process.stdout.rows - 2) return output(screen.join('\n')) } function linkSize (state) { if (state.cabal.db.key) return `cabal://${state.cabal.db.key.toString('hex')}`.length else return 'cabal://...' } function renderPrompt (state) { var name = state.user ? (state.user.name || state.user.key.substring(0, 8)) : 'unknown' return [ `[${chalk.cyan(name)}:${state.channel}] ${state.neat.input.line()}` ] } function renderTitlebar (state, width) { return [ chalk.bgBlue(util.centerText(chalk.white.bold('CABAL'), width)), util.rightAlignText(chalk.white(`cabal://${state.cabal.key.toString('hex')}`), width) ] } function renderChannels (state, width, height) { return state.channels .map(function (channel, idx) { var channelTruncated = channel.substring(0, width - 5) if (state.channel === channel) { return ' ' + chalk.bgBlue((idx + 1) + '. ' + channelTruncated) } else { return ' ' + chalk.gray((idx + 1) + '. ') + chalk.white(channelTruncated) } }) } function renderVerticalLine (chr, height, chlk) { return new Array(height).fill(chlk ? chlk(chr) : chr) } function renderHorizontalLine (chr, width, chlk) { var txt = new Array(width).fill(chr).join('') if (chlk) txt = chlk(txt) return [txt] } function renderNicks (state, width, height) { var users = Object.keys(state.users) .map(key => state.users[key]) .sort(cmpUser) users = users .map(function (user) { var name = '' var sigil = '' // if (user.online) sigil = chalk.green('+') if (user && user.name) name += user.name.slice(0, width) else name += user.key.slice(0, Math.min(8, width)) if (!user.online) name = chalk.gray(name) return sigil + name }) return users } function cmpUser (a, b) { if (a.online && !b.online) return -1 if (b.online && !a.online) return 1 if (a.name && !b.name) return -1 if (b.name && !a.name) return 1 if (a.name && b.name) return a.name < b.name ? -1 : 1 return a.key < b.key ? -1 : 1 } function renderMessages (state, width, height) { var msgs = state.messages // Character-wrap to area edge var allLines = msgs.reduce(function (accum, msg) { accum.push.apply(accum, util.wrapAnsi(msg, width)) return accum }, []) state.scrollback = Math.min(state.scrollback, allLines.length - height) if (allLines.length < height) { state.scrollback = 0 } var lines = (allLines.length < height) ? allLines.concat(Array(height - allLines.length).fill('')) : allLines.slice( allLines.length - height - state.scrollback, allLines.length - state.scrollback ) if (state.scrollback > 0) { lines = lines.slice(0, lines.length - 2).concat(['', 'More messages below . . .']) } return lines }