Skip to content

Commit

Permalink
Refactor preview
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Sep 8, 2021
1 parent 08d0d44 commit 5bf450c
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 155 deletions.
6 changes: 1 addition & 5 deletions src/report/utils/wrap.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import wrapAnsi from 'wrap-ansi'

import { getScreenWidth, getPaddedScreenWidth } from '../tty.js'
import { getScreenWidth } from '../tty.js'

// Rows that are larger than the terminal screen width must be broken down
// (line wrapping). This is because:
Expand All @@ -13,10 +13,6 @@ export const wrapRows = function (string) {
return wrapString(string, getScreenWidth())
}

export const wrapPaddedRows = function (string) {
return wrapString(string, getPaddedScreenWidth())
}

const wrapString = function (string, width) {
return wrapAnsi(string, width, { hard: true, trim: false })
}
20 changes: 20 additions & 0 deletions src/run/preview/update/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { goodColor, noteColor } from '../../../report/utils/colors.js'

// Show keys available for user actions in previews.
// When there are no actions available, we keep an empty line to avoid jitter.
export const getActions = function (actions, leftWidth) {
const actionValues = Object.values(actions)

if (actionValues.length === 0) {
return ''
}

const actionsStr = actionValues.map(getAction).join(noteColor(', '))
return `${ACTIONS_LABEL.padEnd(leftWidth)}${actionsStr}`
}

const getAction = function ({ key, explanation }) {
return `${goodColor(key)} ${noteColor(`(${explanation})`)}`
}

export const ACTIONS_LABEL = 'Actions'
73 changes: 41 additions & 32 deletions src/run/preview/update/bottom_bar.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,54 @@
import stripFinalNewline from 'strip-final-newline'

import { handleContent } from '../../../report/handle.js'
import { goodColor, noteColor } from '../../../report/utils/colors.js'
import { wrapPaddedRows } from '../../../report/utils/wrap.js'
import { getLineSeparator } from '../../../report/utils/line.js'

import { getActions, ACTIONS_LABEL } from './actions.js'
import { getCounterRow, getCounter } from './counter.js'
import { getProgressRow } from './progress.js'

// Retrieve bottom bar of preview
export const getBottomBar = function ({
previewState: {
actions,
reporters: [
{
config: { colors },
},
],
},
leftWidth,
progressRow,
counterRow,
actions,
durationLeft,
percentage,
report,
index,
total,
combinationName,
description,
reporters: [
{
config: { colors },
},
],
}) {
const separator = getSeparator(report)
const leftWidth = getLeftWidth({ durationLeft, total })
const progressRow = getProgressRow({ durationLeft, percentage, leftWidth })
const counterRow = getCounterRow({
index,
total,
combinationName,
description,
leftWidth,
})
const actionsA = getActions(actions, leftWidth)
const content = `${progressRow}\n\n${counterRow}\n\n${actionsA}`
const content = `${separator}${progressRow}\n${counterRow}\n${actionsA}`
const bottomBar = handleContent({ content, colors, padding: true })
const bottomBarA = stripFinalNewline(bottomBar)
return bottomBarA
return bottomBar
}

// Show keys available for user actions in previews.
// When there are no actions available, we keep an empty line to avoid jitter.
const getActions = function (actions, leftWidth) {
const actionValues = Object.values(actions)

if (actionValues.length === 0) {
return ''
}

const actionsStr = actionValues.map(getAction).join(noteColor(', '))
return wrapPaddedRows(`${ACTIONS_LABEL.padEnd(leftWidth)}${actionsStr}`)
const getSeparator = function (report) {
return report === '' ? '' : `${getLineSeparator()}\n`
}

const getAction = function ({ key, explanation }) {
return `${goodColor(key)} ${noteColor(`(${explanation})`)}`
const getLeftWidth = function ({ durationLeft, total }) {
return (
Math.max(
durationLeft.length,
getCounter(total, total).length,
ACTIONS_LABEL.length,
) + LEFT_WIDTH_PADDING
)
}

export const ACTIONS_LABEL = 'Actions'
const LEFT_WIDTH_PADDING = 2
91 changes: 0 additions & 91 deletions src/run/preview/update/bottom_elements.js

This file was deleted.

25 changes: 3 additions & 22 deletions src/run/preview/update/content.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,12 @@
import { getBottomBar } from './bottom_bar.js'
import { getBottomBarElements } from './bottom_elements.js'
import { addInitialScrollAction, addScrollAction } from './scrolling_action.js'
import { updateScrolling } from './scrolling_update.js'

// Retrieve preview content.
export const getPreviewContent = function (previewState) {
addInitialScrollAction(previewState)
const { leftWidth, separator, progressRow, counterRow } =
getBottomBarElements(previewState)
const bottomBar = getBottomBar({
previewState,
leftWidth,
progressRow,
counterRow,
})
const { report, maxScrollTop } = updateScrolling(
previewState,
bottomBar,
separator,
)
const bottomBar = getBottomBar(previewState)
const { report, maxScrollTop } = updateScrolling(previewState, bottomBar)
addScrollAction({ previewState, maxScrollTop })
const separatorA = report === '' ? '' : separator
const bottomBarA = getBottomBar({
previewState,
leftWidth,
progressRow,
counterRow,
})
return `${report}${separatorA}${bottomBarA}`
return `${report}${bottomBar}`
}
30 changes: 30 additions & 0 deletions src/run/preview/update/counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { noteColor, titleColor } from '../../../report/utils/colors.js'

// Retrieve row with combination name and counter
export const getCounterRow = function ({
index,
total,
combinationName,
description,
leftWidth,
}) {
const counter = getCounter(index, total).padEnd(leftWidth)
const descriptionA = getDescription(description, combinationName)
return `${counter}${titleColor(combinationName)}${descriptionA}\n`
}

// The `counter` is between `durationLeft` and `progressBar` so that there is
// no empty space when `durationLeft` is unknown.
export const getCounter = function (index, total) {
return `(${index + 1}/${total})`
}

const getDescription = function (description, combinationName) {
if (description === '') {
return ''
}

const descriptionA =
combinationName === '' ? description : ` (${description})`
return noteColor(descriptionA)
}
27 changes: 27 additions & 0 deletions src/run/preview/update/progress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { getPaddedScreenWidth } from '../../../report/tty.js'
import { goodColor, separatorColor } from '../../../report/utils/colors.js'

// Retrieve row with progress bar
export const getProgressRow = function ({
durationLeft,
percentage,
leftWidth,
}) {
const durationLeftA = durationLeft.padEnd(leftWidth)
const progressBar = getProgressBar(durationLeftA, percentage)
return `${durationLeftA}${progressBar}\n`
}

const getProgressBar = function (durationLeft, percentage) {
const progressBarWidth = getPaddedScreenWidth() - durationLeft.length
const filled = Math.floor(progressBarWidth * percentage)
const filledChars = goodColor(FILL_CHAR.repeat(filled))
const voidedChars = separatorColor(
VOID_CHAR.repeat(progressBarWidth - filled),
)
return `${filledChars}${voidedChars}`
}

// Works with all terminals
const FILL_CHAR = '\u2588'
const VOID_CHAR = '\u2591'
9 changes: 4 additions & 5 deletions src/run/preview/update/scrolling_update.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { getScreenHeight } from '../../../report/tty.js'
// size shrinks
// - This prevents jittering when the scrolling completely down and the report
// size shrinks
export const updateScrolling = function (previewState, bottomBar, separator) {
const availableHeight = getAvailableHeight(bottomBar, separator)
export const updateScrolling = function (previewState, bottomBar) {
const availableHeight = getAvailableHeight(bottomBar)
const { report, scrollTop, maxScrollTop } = applyScrolling(
previewState,
availableHeight,
Expand All @@ -25,11 +25,10 @@ export const updateScrolling = function (previewState, bottomBar, separator) {
}

// Terminals print the row after the last newline, i.e. we need to subtract 1
const getAvailableHeight = function (bottomBar, separator) {
const getAvailableHeight = function (bottomBar) {
const screenHeight = getScreenHeight()
const separatorHeight = getNewlineIndexes(separator).length
const bottomBarHeight = getNewlineIndexes(bottomBar).length
return Math.max(screenHeight - separatorHeight - bottomBarHeight - 1, 0)
return Math.max(screenHeight - bottomBarHeight - 1, 0)
}

const applyScrolling = function ({ report, scrollTop }, availableHeight) {
Expand Down

0 comments on commit 5bf450c

Please sign in to comment.