OverviewFilesCommitsIssuesDocsReleasesPeers

keet-tui / lib / components / room-list.js

72 lines · javascript ref:
import * as style from '../style.js'

export function roomListView (model, width, height) {
  const rooms = model.rooms || []
  const selected = model.selectedRoomIndex
  const lines = []

  // Title
  lines.push(style.bold(style.center(' Rooms ', width)))
  lines.push(style.hline(width, 'rounded'))

  if (rooms.length === 0) {
    lines.push(style.dim(style.center('No rooms', width)))
    while (lines.length < height) lines.push('')
    return lines
  }

  const listHeight = height - 3 // title + separator + bottom
  const scrollOffset = computeScroll(selected, rooms.length, listHeight)

  for (let i = 0; i < listHeight; i++) {
    const idx = scrollOffset + i
    if (idx >= rooms.length) {
      lines.push('')
      continue
    }

    const room = rooms[idx]
    const title = room.title || room.roomId.slice(0, 12)
    const isSelected = idx === selected
    const isActive = room.roomId === model.activeRoomId

    let line = ' '
    if (isActive) line += style.green('\u25cf') + ' '
    else line += '  '

    line += style.truncate(title, width - 4)

    if (room.unread) {
      line = style.padRight(line, width - 4)
      line += style.bold(style.yellow(' ' + room.unread))
    }

    line = style.padRight(line, width)

    if (isSelected) {
      line = style.invert(line)
    }

    lines.push(line)
  }

  // Scroll indicator
  if (rooms.length > listHeight) {
    const pct = Math.round((scrollOffset / Math.max(1, rooms.length - listHeight)) * 100)
    lines.push(style.dim(style.center(pct + '%', width)))
  } else {
    lines.push('')
  }

  while (lines.length < height) lines.push('')
  return lines
}

function computeScroll (selected, total, viewHeight) {
  if (total <= viewHeight) return 0
  let offset = selected - Math.floor(viewHeight / 2)
  if (offset < 0) offset = 0
  if (offset > total - viewHeight) offset = total - viewHeight
  return offset
}