You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
7.6 KiB
196 lines
7.6 KiB
import {
|
|
DateQuestion,
|
|
EditorQuestion,
|
|
ListQuestion,
|
|
NumberQuestion,
|
|
} from "inquirer";
|
|
import {Separator} from "../Inquire.js";
|
|
import {InquireFunction} from "../Inquire.js";
|
|
import {SleepQuality, SleepRecord, sleepRecordToString, WakeQuality} from "../../datatypes/SleepRecord.js";
|
|
import {DateTime} from "luxon";
|
|
import chalk from "chalk";
|
|
import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js";
|
|
|
|
export interface SleepRecordPromptOptions extends Partial<Omit<EditorQuestion, "name"|"type"|"default"> & Omit<DateQuestion, "name"|"type"|"default"> & Omit<ListQuestion, "name"|"type"|"default"> & Omit<NumberQuestion, "name"|"type"|"default">>{
|
|
default?: SleepRecord,
|
|
}
|
|
|
|
export interface SleepRecordPromptDependencies {
|
|
readonly inquire: InquireFunction<EditorQuestion, string> & InquireFunction<DateQuestion, Date|null> & InquireFunction<ListQuestion & {default: SleepQuality|undefined}, SleepQuality|undefined> & InquireFunction<ListQuestion & {default: WakeQuality|undefined}, WakeQuality|undefined> & InquireFunction<NumberQuestion, number>
|
|
}
|
|
|
|
export function sleepRecordPrompt(deps: SleepRecordPromptDependencies): {
|
|
(options: SleepRecordPromptOptions): Promise<SleepRecord|null>,
|
|
mainMenu: EntryMainMenuChoice<"sleepRecords">,
|
|
} {
|
|
return makeEntryMainMenuChoice({
|
|
property: "sleepRecords",
|
|
name: (input) => typeof input !== "object" || input.length === 0 ? `Add sleep record` : `Change sleep record ${chalk.dim(`(currently ${chalk.greenBright(sleepRecordToString(input[0]))})`)}`,
|
|
key: "z",
|
|
injected: (options) => promptForSleepRecord(options, deps),
|
|
toOptions: (value) => typeof value !== "object" || value.length === 0 ? {} : {default: value[0]},
|
|
toProperty: (value) => value === null ? undefined : [value],
|
|
})
|
|
}
|
|
|
|
export async function promptForSleepRecord(options: SleepRecordPromptOptions, {inquire}: SleepRecordPromptDependencies): Promise<SleepRecord | null> {
|
|
const oldBedTime = options.default?.sleepAt
|
|
const newBedTime = await inquire({
|
|
...options,
|
|
type: "date",
|
|
message: "About when did you get to sleep?",
|
|
clearable: true,
|
|
startCleared: false,
|
|
default: oldBedTime ?? DateTime.local().set({hour: 23, minute: 0, second: 0, millisecond: 0}).minus({days: 1}).toJSDate(),
|
|
format: {
|
|
year: undefined,
|
|
weekday: "short",
|
|
month: "short",
|
|
day: "numeric",
|
|
hour: "numeric",
|
|
minute: "numeric",
|
|
second: undefined,
|
|
fractionalSecondDigits: undefined,
|
|
timeZoneName: "short",
|
|
},
|
|
startingDatePart: "hour",
|
|
deltas: {
|
|
weekday: 1,
|
|
hour: [1, 5, 10],
|
|
minute: [15, 5, 1],
|
|
default: 0
|
|
}
|
|
})
|
|
const oldSleepQuality = options.default?.sleepQuality
|
|
const newSleepQuality = await inquire({
|
|
...options,
|
|
type: "list",
|
|
message: `How'd you sleep?`,
|
|
choices: [
|
|
{
|
|
value: SleepQuality.ACIDIC,
|
|
name: `Acidic ${chalk.dim("(extremely poor/extremely restless/heavy acid reflux)")}`
|
|
},
|
|
{
|
|
value: SleepQuality.RESTLESS,
|
|
name: `Restless ${chalk.dim("(very poor/very restless/fever dreamy)")}`
|
|
},
|
|
{
|
|
value: SleepQuality.NIGHTMARISH,
|
|
name: `Nightmarish ${chalk.dim("(poor/restless/plagued with nightmares)")}`
|
|
},
|
|
{
|
|
value: SleepQuality.TIMESKIP,
|
|
name: `Timeskip ${chalk.dim("(neutral/passage of time not recognized)")}`
|
|
},
|
|
{
|
|
value: SleepQuality.DREAMLESS,
|
|
name: `Dreamless ${chalk.dim("(good/peaceful/no dreams had or remembered)")}`
|
|
},
|
|
{
|
|
value: SleepQuality.DREAMY,
|
|
name: `Dreamy ${chalk.dim("(very good/peaceful/neutral to somewhat pleasant dreams)")}`
|
|
},
|
|
{
|
|
value: SleepQuality.ECSTASY,
|
|
name: `Ecstasy ${chalk.dim("(extremely good/very peaceful/very pleasant dreams)")}`
|
|
},
|
|
new Separator(),
|
|
{
|
|
value: undefined,
|
|
name: `Uncertain`
|
|
},
|
|
],
|
|
default: oldSleepQuality ?? SleepQuality.TIMESKIP,
|
|
pageSize: 999,
|
|
})
|
|
const oldInterruptions = options.default?.interruptions
|
|
const newInterruptionsRaw = await inquire({
|
|
...options,
|
|
type: "number",
|
|
message: "How many times did you end up waking up during the sleep?",
|
|
default: oldInterruptions ?? -1,
|
|
})
|
|
const newInterruptions = newInterruptionsRaw < 0 ? undefined : Math.round(newInterruptionsRaw)
|
|
const oldWakeTime = options.default?.wakeAt
|
|
const newWakeTime = await inquire({
|
|
...options,
|
|
type: "date",
|
|
message: "Around when did you get up?",
|
|
clearable: true,
|
|
startCleared: false,
|
|
default: oldWakeTime ?? DateTime.local().set({hour: 7, minute: 0, second: 0, millisecond: 0}).toJSDate(),
|
|
format: {
|
|
year: undefined,
|
|
weekday: "short",
|
|
month: "short",
|
|
day: "numeric",
|
|
hour: "numeric",
|
|
minute: "numeric",
|
|
second: undefined,
|
|
fractionalSecondDigits: undefined,
|
|
timeZoneName: "short",
|
|
},
|
|
startingDatePart: "hour",
|
|
deltas: {
|
|
hour: [1, 5, 10],
|
|
minute: [15, 5, 1],
|
|
default: 0
|
|
}
|
|
})
|
|
const oldWakeQuality = options.default?.wakeQuality
|
|
const newWakeQuality = await inquire({
|
|
...options,
|
|
type: "list",
|
|
message: `How'd you feel when you got up?`,
|
|
choices: [
|
|
{
|
|
value: WakeQuality.AGONIZED,
|
|
name: `Agonized ${chalk.dim("(in physical pain/barely able or unable to get out of bed)")}`
|
|
},
|
|
{
|
|
value: WakeQuality.EXHAUSTED,
|
|
name: `Exhausted ${chalk.dim("(very tired/not wanting to get out of bed)")}`
|
|
},
|
|
{
|
|
value: WakeQuality.DROWSY,
|
|
name: `Drowsy ${chalk.dim("(a bit sleepy but willing to get out of bed)")}`
|
|
},
|
|
{
|
|
value: WakeQuality.RESTED,
|
|
name: `Rested ${chalk.dim("(well rested and ready to get going)")}`
|
|
},
|
|
{
|
|
value: WakeQuality.ENERGIZED,
|
|
name: `Energized ${chalk.dim("(thoroughly recharged and eager to get up and running)")}`
|
|
},
|
|
new Separator(),
|
|
{
|
|
value: undefined,
|
|
name: `Uncertain`
|
|
},
|
|
],
|
|
default: oldWakeQuality ?? WakeQuality.DROWSY,
|
|
pageSize: 999,
|
|
})
|
|
const oldDreamJournal = options.default?.dreams
|
|
const newDreamJournalRaw = (await inquire({
|
|
...options,
|
|
type: "editor",
|
|
message: typeof oldDreamJournal === "string" ? `Edit dream journal for this sleep session:` : `Type up dream journal for this sleep session:`,
|
|
default: oldDreamJournal,
|
|
})).trimEnd()
|
|
const newDreamJournal = newDreamJournalRaw === "" ? undefined : newDreamJournalRaw
|
|
const result: SleepRecord = {
|
|
dreams: newDreamJournal,
|
|
interruptions: newInterruptions,
|
|
sleepAt: newBedTime ?? undefined,
|
|
sleepQuality: newSleepQuality,
|
|
wakeAt: newWakeTime ?? undefined,
|
|
wakeQuality: newWakeQuality,
|
|
}
|
|
return (
|
|
Object.keys(result).map((key: keyof SleepRecord) => result[key]).some(value => (value !== undefined))
|
|
? result
|
|
: null)
|
|
} |