Skip to content

Commit

Permalink
Refactor code for more modularity
Browse files Browse the repository at this point in the history
  • Loading branch information
sopa301 committed Dec 17, 2023
1 parent 8330739 commit cfe76b7
Show file tree
Hide file tree
Showing 14 changed files with 275 additions and 224 deletions.
30 changes: 23 additions & 7 deletions src/scenes/addProjectScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import createDebug from 'debug';

import { Project } from '../models/Project';
import { BotContext } from '../BotContext';
import { getUserId, storeProjectInSession } from '../util/botContext';
import {
getProject,
getUserId,
storeProjectInSession,
} from '../util/botContext';
import {
askForProjectDescription,
askForProjectMembers,
Expand All @@ -12,11 +16,12 @@ import {
handleEditProjectDescriptionFactory,
handleEditProjectNameFactory,
makeSceneWithErrorHandling,
saveProject,
returnToPreviousMenuFactory,
} from '../util/scene';
import { createProjectInDb } from '../db/functions';

const debug = createDebug('bot:add_project_command');
const previousLocation = 'mainMenu';
const previousMenu = 'mainMenu';

/**
* Creates a new project in the database.
Expand All @@ -33,18 +38,29 @@ const createNewProject = async (ctx: BotContext, next: () => Promise<void>) => {
return goNextStep(ctx, next);
};

export const saveNewProject = async (
ctx: BotContext,
step: () => Promise<void>,
) => {
const project = getProject(ctx);
createProjectInDb(project);
await ctx.reply(`Project saved.`);
return goNextStep(ctx, step);
};

const addProjectScene = makeSceneWithErrorHandling(
'addProject',
debug,
addProject,
createNewProject,
askForProjectName,
handleEditProjectNameFactory(debug, previousLocation),
handleEditProjectNameFactory(previousMenu),
askForProjectDescription,
handleEditProjectDescriptionFactory(debug, previousLocation),
handleEditProjectDescriptionFactory(debug, previousMenu),
askForProjectMembers,
handleAddProjectMembersFactory(debug, previousLocation),
saveProject,
handleAddProjectMembersFactory(debug, previousMenu),
saveNewProject,
returnToPreviousMenuFactory(previousMenu),
);

export { addProjectScene };
64 changes: 35 additions & 29 deletions src/scenes/deleteProjectScene.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,58 @@
import createDebug from 'debug';

import { Markup } from 'telegraf';
import { Markup, MiddlewareFn } from 'telegraf';

import { deleteProjectInDb } from '../db/functions';

import { InvalidTextError } from '../exceptions';

import { BotContext, updateSessionDataBetweenScenes } from '../BotContext';
import { makeSceneWithErrorHandling } from '../util/scene';
import { getProject, getResponse } from '../util/botContext';
import {
askAndHandleMenuFactory,
goNextStep,
makeSceneWithErrorHandling,
returnToPreviousMenuFactory,
} from '../util/scene';
import { getProject } from '../util/botContext';

const debug = createDebug('bot:delete_project_command');
const previousMenu = 'manageProject';

/**
* Deletes a project from the database.
* @returns A middleware function that handles the deletion of a project.
*/
const askForDeleteConfirmation = async (ctx: BotContext) => {
const deleteProject = async (ctx: BotContext, next: () => Promise<void>) => {
updateSessionDataBetweenScenes(ctx);
debug(`Entering deleteProject scene.`);
await ctx.reply(
`You have selected to delete the project. Are you sure?`,
Markup.keyboard(['Yes', 'No']).resize(),
);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const handleDeleteProject = async (ctx: BotContext) => {
const text = getResponse(ctx);
if (text === 'Yes') {
debug(`User selected to delete the project.`);
const project = getProject(ctx);
await deleteProjectInDb(project.getId());
await ctx.reply(`Project deleted.`);
return ctx.scene.enter('mainMenu');
} else if (text === 'No') {
debug(`User selected not to delete the project.`);
await ctx.reply(`Project not deleted. Returning to the main menu.`);
return ctx.scene.enter('mainMenu');
} else {
throw new InvalidTextError('Please select either Yes or No.');
}
};
const question = `Are you sure you want to delete the project?`;
const map = new Map<string, MiddlewareFn<BotContext>>([
[
'Yes',
async (ctx) => {
const project = getProject(ctx);
await deleteProjectInDb(project.getId());
await ctx.reply(`Project deleted.`);
return ctx.scene.enter('mainMenu', Markup.removeKeyboard());
},
],
['No', returnToPreviousMenuFactory(previousMenu)],
]);

const [askForMenuChoice, handleMenuChoice] = askAndHandleMenuFactory(
debug,
undefined,
question,
map,
);

const deleteProjectScene = makeSceneWithErrorHandling(
'deleteProject',
debug,
askForDeleteConfirmation,
handleDeleteProject,
deleteProject,
askForMenuChoice,
handleMenuChoice,
);

export { deleteProjectScene };
5 changes: 3 additions & 2 deletions src/scenes/editProject/addPeopleScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import createDebug from 'debug';
import { BotContext, updateSessionDataBetweenScenes } from '../../BotContext';
import {
askForProjectMembers,
goNextStep,
handleAddProjectMembersFactory,
makeSceneWithErrorHandling,
returnToPreviousMenuFactory,
Expand All @@ -12,10 +13,10 @@ import {
const debug = createDebug('bot:add_people_command');
const previousMenu = 'manageProject';

const addPeople = async (ctx: BotContext) => {
const addPeople = async (ctx: BotContext, next: () => Promise<void>) => {
debug('Entered addPeople scene.');
updateSessionDataBetweenScenes(ctx);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const addPeopleScene = makeSceneWithErrorHandling(
Expand Down
12 changes: 8 additions & 4 deletions src/scenes/editProject/deletePeopleScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { getProject, getResponse } from '../../util/botContext';
import {
askForProjectMembers,
goNextStep,
makeSceneWithErrorHandling,
returnToPreviousMenuFactory,
saveProject,
Expand All @@ -16,13 +17,16 @@ import {
const debug = createDebug('bot:delete_people_command');
const previousMenu = 'manageProject';

const deletePeople = async (ctx: BotContext) => {
const deletePeople = async (ctx: BotContext, next: () => Promise<void>) => {
debug('Entered deletePeople scene.');
updateSessionDataBetweenScenes(ctx);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const handleDeleteProjectMembers = async (ctx: BotContext) => {
const handleDeleteProjectMembers = async (
ctx: BotContext,
next: () => Promise<void>,
) => {
const text = getResponse(ctx);
if (isBackCommand(text)) {
debug('User indicated to go back');
Expand All @@ -32,7 +36,7 @@ const handleDeleteProjectMembers = async (ctx: BotContext) => {
const project = getProject(ctx);
debug(`Removing ${personArr.length} project members: ${personArr}`);
project.removePersons(personArr);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const deletePeopleScene = makeSceneWithErrorHandling(
Expand Down
8 changes: 6 additions & 2 deletions src/scenes/editProject/editProjectDescriptionScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import createDebug from 'debug';
import { BotContext, updateSessionDataBetweenScenes } from '../../BotContext';
import {
askForProjectDescription,
goNextStep,
handleEditProjectDescriptionFactory,
makeSceneWithErrorHandling,
returnToPreviousMenuFactory,
Expand All @@ -12,10 +13,13 @@ import {
const debug = createDebug('bot:edit_project_description_command');
const previousMenu = 'editProject';

const editProjectDescription = async (ctx: BotContext) => {
const editProjectDescription = async (
ctx: BotContext,
next: () => Promise<void>,
) => {
debug('Entered editProjectDescription scene.');
updateSessionDataBetweenScenes(ctx);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const editProjectDescriptionScene = makeSceneWithErrorHandling(
Expand Down
7 changes: 4 additions & 3 deletions src/scenes/editProject/editProjectNameScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import createDebug from 'debug';
import { BotContext, updateSessionDataBetweenScenes } from '../../BotContext';
import {
askForProjectName,
goNextStep,
handleEditProjectNameFactory,
makeSceneWithErrorHandling,
returnToPreviousMenuFactory,
Expand All @@ -12,18 +13,18 @@ import {
const debug = createDebug('bot:edit_project_name_command');
const previousMenu = 'editProject';

const editProjectName = async (ctx: BotContext) => {
const editProjectName = async (ctx: BotContext, next: () => Promise<void>) => {
debug('Entered editProjectName scene.');
updateSessionDataBetweenScenes(ctx);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const editProjectNameScene = makeSceneWithErrorHandling(
'editProjectName',
debug,
editProjectName,
askForProjectName,
handleEditProjectNameFactory(debug, previousMenu),
handleEditProjectNameFactory(previousMenu),
saveProject,
returnToPreviousMenuFactory(previousMenu),
);
Expand Down
76 changes: 29 additions & 47 deletions src/scenes/editProject/editProjectScene.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,52 @@
import createDebug from 'debug';

import { Markup } from 'telegraf';
import { MiddlewareFn } from 'telegraf';

import { BotContext, updateSessionDataBetweenScenes } from '../../BotContext';
import { makeSceneWithErrorHandling } from '../../util/scene';
import { getResponse } from '../../util/botContext';
import { isBackCommand } from '../../util/userInput';
import {
askAndHandleMenuFactory,
goNextStep,
goToScene,
makeSceneWithErrorHandling,
} from '../../util/scene';

const debug = createDebug('bot:edit_project_command');
const previousMenu = 'manageProject';

/**
* Edits an existing project in the database.
* @returns A middleware function that handles the editing of a project.
*/
const editProject = async (ctx: BotContext) => {
const editProject = async (ctx: BotContext, next: () => Promise<void>) => {
debug('Entered editProject scene.');
updateSessionDataBetweenScenes(ctx);
// Add project edition logic here
await ctx.reply(
`What do you want to edit?`,
Markup.keyboard([
['Add People', 'Delete People'],
['Edit Project Name', 'Edit Project Description'],
['Back'],
]).resize(),
);
return ctx.wizard.next();
return goNextStep(ctx, next);
};

const handleEditProjectOption = async (ctx: BotContext) => {
const text = getResponse(ctx);
if (isBackCommand(text)) {
debug('User selected "Back"');
return ctx.scene.enter('manageProject', ctx.scene.session);
}
switch (text) {
case 'Add People': {
debug('User selected "Add People"');
return ctx.scene.enter('addPeople', ctx.scene.session);
}
case 'Delete People': {
debug('User selected "Delete People"');
return ctx.scene.enter('deletePeople', ctx.scene.session);
}
case 'Edit Project Name': {
debug('User selected "Edit Project Name"');
return ctx.scene.enter('editProjectName', ctx.scene.session);
}
case 'Edit Project Description': {
debug('User selected "Edit Project Description"');
return ctx.scene.enter('editProjectDescription', ctx.scene.session);
}
default: {
await ctx.reply(
'Invalid option. Please select a valid option from the keyboard.',
);
return ctx.wizard.back();
}
}
};
const question = 'What do you want to edit?';
const mapOptionToScene = new Map<string, MiddlewareFn<BotContext>>([
['Add People', async (ctx) => goToScene('addPeople', ctx)],
['Delete People', async (ctx) => goToScene('deletePeople', ctx)],
['Edit Project Name', async (ctx) => goToScene('editProjectName', ctx)],
[
'Edit Project Description',
async (ctx) => goToScene('editProjectDescription', ctx),
],
]);

const [askForMenuChoice, handleMenuChoice] = askAndHandleMenuFactory(
debug,
previousMenu,
question,
mapOptionToScene,
);

const editProjectScene = makeSceneWithErrorHandling(
'editProject',
debug,
editProject,
handleEditProjectOption,
askForMenuChoice,
handleMenuChoice,
);

export { editProjectScene };
Loading

0 comments on commit cfe76b7

Please sign in to comment.