Skip to content

Commit

Permalink
Add boundary checks for property pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantGeekDev committed Jan 5, 2024
1 parent 256e451 commit 7b90b5a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 37 deletions.
2 changes: 1 addition & 1 deletion propertiesSampleData.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Villa 6",
"price": 670000,
"availability": true,
"videoFileId": "https://www.dropbox.com/sh/t6330gcog0lz7dh/AADqYOkfEnvIQ0RF6Lr0eRBja?dl=0&preview=Video+1+SaliSol+Hills+Showhouse+2023.mp4",
"videoFileId": "BAACAgQAAxkBAAMSZZfGuavHENo8Q6I0958piOATHC0AAlsPAAJrdMFQniWsDNpoNOs0BA",
"thumbnailUrl": "https://uc470239d7d0c1c41f915323d5c8.previews.dropboxusercontent.com/p/thumb/ACLJ7D6O6bqDe2gRpcdVMDPaxNwZYWAenzJD8IQuZKGoaWdojbcZHMHHw0X-6CUmisfriGocNXvxH1tLSty6kEh3PftuhgeMPVUlQuhD7KmGYWfmqnWQKPY9bwnKjU-qxJJv7c2StyA_xn6H4l4MCTF0dWVHalbKeTT5aW5ucsm5f6raAcqCXx7mRQto9AkM3lHzDi8dw7imp65me_EFKUmEziFK108IecRwKQ1KZdNWrjVIuAcaIyGzq51l--Kphv6rh9tHaSXx0DMv_MX0vtYbL751cve0h9YGrvGPnFUMKhP6oPqXAFzLnSJCc3qnbzfaGuaWeI7sjBLh5-MXtt8JTZfsU8-om8Kv1k0gtPF4dg/p.png",
"builtMetersSquared": 168,
"plotMetersSquared": 532,
Expand Down
89 changes: 57 additions & 32 deletions src/controllers/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {
generatePropertyDescription,
generatePropertyPhotoAlbum
} from "../services/Property/property.service.js";
import { propertyControlKeyboard } from "../menus/propertyMenu.js";
import {
fullPropertyControlKeyboard,
nextPropertyControlKeyboard,
previousPropertyControlKeyboard
} from "../menus/propertyMenu.js";

export const propertiesController = new Composer<CustomContext>();
let currentPropertyIndex = 0;
Expand All @@ -24,44 +28,65 @@ propertiesController.command("properties", async ctx => {
await ctx.replyWithVideo(videoFileId);
await ctx.replyWithMediaGroup(propertyPhotoAlbum);
await ctx.reply(`Property ${currentPropertyIndex + 1}/${totalProperties}`, {
reply_markup: propertyControlKeyboard
reply_markup: nextPropertyControlKeyboard
});

propertiesController.callbackQuery("next-property", async ctx => {
ctx.answerCallbackQuery("");
currentPropertyIndex++;
const currentProperty = properties[currentPropertyIndex];
const totalProperties = properties.length;
const { videoFileId, albumUrls } = currentProperty;
const propertyDescription = generatePropertyDescription(currentProperty);
const propertyPhotoAlbum = generatePropertyPhotoAlbum(albumUrls);
await ctx.reply(`Property ${currentPropertyIndex + 1}/${totalProperties}`);
await ctx.reply(propertyDescription, {
parse_mode: "MarkdownV2"
});
await ctx.replyWithVideo(videoFileId);
await ctx.replyWithMediaGroup(propertyPhotoAlbum);
await ctx.reply(`Property ${currentPropertyIndex + 1}/${totalProperties}`, {
reply_markup: propertyControlKeyboard
});
if (currentPropertyIndex + 1 < totalProperties) {
currentPropertyIndex++;

const currentProperty = properties[currentPropertyIndex];
const totalProperties = properties.length;
const { videoFileId, albumUrls } = currentProperty;
const propertyDescription = generatePropertyDescription(currentProperty);
const propertyPhotoAlbum = generatePropertyPhotoAlbum(albumUrls);
await ctx.reply(
`Property ${currentPropertyIndex + 1}/${totalProperties}`
);
await ctx.reply(propertyDescription, {
parse_mode: "MarkdownV2"
});
await ctx.replyWithVideo(videoFileId);
await ctx.replyWithMediaGroup(propertyPhotoAlbum);
await ctx.reply(
`Property ${currentPropertyIndex + 1}/${totalProperties}`,
{
reply_markup:
currentPropertyIndex + 1 < totalProperties
? fullPropertyControlKeyboard
: previousPropertyControlKeyboard
}
);
}
});

propertiesController.callbackQuery("previous-property", async ctx => {
ctx.answerCallbackQuery("");
currentPropertyIndex--;
const currentProperty = properties[currentPropertyIndex];
const totalProperties = properties.length;
const { videoFileId, albumUrls } = currentProperty;
const propertyDescription = generatePropertyDescription(currentProperty);
const propertyPhotoAlbum = generatePropertyPhotoAlbum(albumUrls);
await ctx.reply(`Property ${currentPropertyIndex + 1}/${totalProperties}`);
await ctx.reply(propertyDescription, {
parse_mode: "MarkdownV2"
});
await ctx.replyWithVideo(videoFileId);
await ctx.replyWithMediaGroup(propertyPhotoAlbum);
await ctx.reply(`Property ${currentPropertyIndex + 1}/${totalProperties}`, {
reply_markup: propertyControlKeyboard
});
if (currentPropertyIndex > 1) {
currentPropertyIndex--;
const currentProperty = properties[currentPropertyIndex];
const totalProperties = properties.length;
const { videoFileId, albumUrls } = currentProperty;
const propertyDescription = generatePropertyDescription(currentProperty);
const propertyPhotoAlbum = generatePropertyPhotoAlbum(albumUrls);
await ctx.reply(
`Property ${currentPropertyIndex + 1}/${totalProperties}`
);
await ctx.reply(propertyDescription, {
parse_mode: "MarkdownV2"
});
await ctx.replyWithVideo(videoFileId);
await ctx.replyWithMediaGroup(propertyPhotoAlbum);
await ctx.reply(
`Property ${currentPropertyIndex + 1}/${totalProperties}`,
{
reply_markup:
currentPropertyIndex + 1 > 1
? fullPropertyControlKeyboard
: nextPropertyControlKeyboard
}
);
}
});
});
12 changes: 11 additions & 1 deletion src/menus/propertyMenu.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { InlineKeyboard } from "grammy";

export const propertyControlKeyboard = new InlineKeyboard()
export const fullPropertyControlKeyboard = new InlineKeyboard()
.text("« Previous Property", "previous-property")
.text("Next Property » ", "next-property");

export const nextPropertyControlKeyboard = new InlineKeyboard().text(
"Next Property » ",
"next-property"
);

export const previousPropertyControlKeyboard = new InlineKeyboard().text(
"« Previous Property",
"previous-property"
);
4 changes: 2 additions & 2 deletions src/services/Property/property.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import type { Property } from "../../types/database.js";
export const generatePropertyDescription = (property: Property): string => {
const {
name,
collectionName,
collection,
availability,
price,
plotMetersSquared,
builtMetersSquared
} = property;

// Property description uses Telegram's Markdown V2
const propertyDescription = `*🏠 ${collectionName}: ${name}*\n\nPlot Size: ${plotMetersSquared}m2 \nBuilt Meters: ${builtMetersSquared}m2\nPrice: ${price
const propertyDescription = `*🏠 ${collection}: ${name}*\n\nPlot Size: ${plotMetersSquared}m2 \nBuilt Meters: ${builtMetersSquared}m2\nPrice: ${price
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}${
availability ? "" : "Reserved"
Expand Down
2 changes: 1 addition & 1 deletion src/types/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface User {

export interface Property {
_id: string;
collectionName: "SaliSol Hills" | "SaliSol Resort" | "SaliSol Golf";
collection: "SaliSol Hills" | "SaliSol Resort" | "SaliSol Golf";
name: string;
price: number;
availability: boolean;
Expand Down

0 comments on commit 7b90b5a

Please sign in to comment.