// Cards module - everything related to cards should go here (database install is automatic for AO server so no feature module) import inquirer from 'inquirer' import { aoEnv } from './settings.js' import { getCard, getCardByName, createCard, prioritizeCard, completeCard, uncheckCard, refocusCard } from './api.js' import { headerStyle } from './styles.js' // The card menu is complex and so has been split into this separate file export async function cardMenu() { console.log(`\n${headerStyle('My Deck')}`) const cardChoices = [ { name: 'Top priorities', value: 'priorities', short: 'priorities' }, // hand? (7) (add #s in parens) { name: 'Cards in hand', value: 'subcards', short: 'hand' }, // (current) deck? (60) { name: 'Browse full deck', value: 'browse', short: 'browse' }, // archive? (10,000) 'Back to AO Menu' ] const answer = await inquirer.prompt({ name: 'card_menu', type: 'list', message: 'Please choose:', choices: cardChoices, pageSize: cardChoices.length, }) switch(answer.card_menu) { case 'priorities': while(await prioritiesMenu()) {} break case 'subcards': while(await subcardsMenu()) {} break case 'browse': while(await browseMenu()) {} break default: return false } return true } // Displays the priorities of the given taskId in a menu. Selecting a card shows a menu for that card. If taskId is null, member card is used. async function prioritiesMenu(taskId = null) { console.log(`\n${headerStyle('My Priorities')}`) let prioritiesChoices = [] const memberId = aoEnv('AO_CLI_SESSION_MEMBERID') if(!memberId) { console.log('Not logged in.') return false } if(!taskId) { // Get the priorities of my member card taskId = memberId } const fetchedCards = await getCard(taskId, 'priorities') if(!fetchedCards || fetchedCards.length < 1) { console.log('Failed to fetch member card, this is bad.') return false } const card = fetchedCards[0] const priorityCards = fetchedCards.slice(1) // First card is member card itself let priorities = card.priorities.slice() priorities.reverse() console.log('You have', priorityCards.length, 'priorities:') prioritiesChoices = priorities.map((priorityTaskId, i) => { const priorityCard = priorityCards.find(p => p.taskId === priorityTaskId) if(!priorityCard) { return 'Missing card, repair your database' } return { name: priorityCard.name, value: { index: i, card: priorityCard }, short: priorityCard.name.substring(0, 70) + priorityCard.name.length >= 70 ? '...' : '' } }) prioritiesChoices.push( { name: 'Create priority', value: 'create_here', short: 'new priority' }, { name: 'Back to AO Menu', value: false, short: 'back' } ) const answer = await inquirer.prompt({ name: 'priorities_menu', type: 'rawlist', message: 'Please choose:', choices: prioritiesChoices, loop: false }) switch(answer.priorities_menu) { case false: return false case 'create_here': let previousCardCreatedText do { console.log('previousCardCreatedText is', previousCardCreatedText) previousCardCreatedText = await createCardInteractive() } while(previousCardCreatedText != '\n') return true case 'Missing card, repair your database': console.log('Database repair yet implemented, sorry.') return true } let chosenTask = answer.priorities_menu.card const chosenTaskId = chosenTask.taskId let previousAnswer do { previousAnswer = await priorityCardMenu(chosenTask, answer.priorities_menu.index) if(previousAnswer) { const fetchedCards = await getCard(chosenTaskId, false) if(!fetchedCards || fetchedCards.length < 1) { console.log('The card has disappeared. Maybe it was deleted, or cards held by no one are automatically cleaned up every five minutes.') return false } chosenTask = fetchedCards[0] } } while(previousAnswer !== false) console.log('Card menu not yet implemented.') return true } // Short action-oriented menu for cards in the priorities list // Index is the position of the card in the list that it is in, used for fencepost case to display upboat contextually async function priorityCardMenu(card, index) { if(!card) { console.log('priorityCardMenu: card is required.') return false } const taskId = card.taskId const memberId = aoEnv('AO_CLI_SESSION_MEMBERID') if(!memberId) { console.log('Not logged in.') return false } const isChecked = card.claimed.includes(memberId) console.log(`\n${headerStyle('Priority: ' + card.name)}`) let priorityChoices = [] if(index != 0) { priorityChoices.push({ name: 'Upboat', value: 'upboat', short: 'upboat' }) } priorityChoices.push( { name: isChecked ? 'Uncheck' : 'Check off', value: 'check', short: 'check!' }, { name: 'Downboat', value: 'downboat', short: 'downboat' }, //{ name: 'Browse within', value: 'browse', short: 'browse' } { name: 'Back to Priorities', value: false, short: 'back' } ) const answer = await inquirer.prompt({ name: 'priority_card_menu', type: 'list', message: 'Please choose:', choices: priorityChoices, pageSize: priorityChoices.length, }) switch(answer.priority_card_menu) { case 'check': if(isChecked) { await uncheckCard(taskId) } else { await completeCard(taskId) } break case 'upboat': await prioritizeCard(taskId, memberId) return false case 'downboat': await refocusCard(taskId, memberId) return false case 'browse': break default: return false } return true } async function subcardsMenu() { console.log('Not yet implemented') } async function browseMenu() { console.log('Not yet implemented') } // Ask the user to create a card, checks if it already exists, and then creates it if it doesn't async function createCardInteractive(prioritized = true) { const memberId = aoEnv('AO_CLI_SESSION_MEMBERID') if(!memberId) { console.log('Not logged in.') return false } const answer = await inquirer.prompt({ name: 'new_card_text', type: 'input', message: 'New card or Enter to end:', }) if(answer.new_card_text.trim().length <= 0) { return false } // Check if the card alerady exists const fetchedCards = await getCardByName(answer.new_card_text, false) if(fetchedCards && fetchedCards.length >= 1) { if(fetchedCards.length >= 2) { console.log('More than one copy of this card was found. This should not happen.') } if(prioritized) { console.log('Card already exists, prioritizing.') const prioritizeResult = prioritizeCard(fetchedCards[0].taskId, memberId) if(!prioritizeResult.ok) { console.log('May have failed to prioritize card.') } } return false } console.log('card does not exist yet. creating...', answer.new_card_text) const result = await createCard(answer.new_card_text, false, true) return answer.new_card_text }