mirror of
https://gitlab.com/bignutty/labscore.git
synced 2025-06-09 14:43:05 -04:00
add maps
This commit is contained in:
parent
79b096efb4
commit
fcb25fc639
7 changed files with 563 additions and 6 deletions
219
commands/interaction/slash/search/maps.js
Normal file
219
commands/interaction/slash/search/maps.js
Normal file
|
@ -0,0 +1,219 @@
|
|||
const { maps, mapsSupplemental } = require('#api');
|
||||
|
||||
const { createEmbed } = require('#utils/embed');
|
||||
const { acknowledge } = require('#utils/interactions');
|
||||
const { link, icon, iconAsEmojiObject } = require('#utils/markdown');
|
||||
const { editOrReply } = require('#utils/message')
|
||||
const { STATICS, STATIC_ASSETS } = require('#utils/statics');
|
||||
const { ApplicationCommandOptionTypes } = require('detritus-client/lib/constants');
|
||||
|
||||
// TODO: Turn this into a general purpose permissions constant
|
||||
const { Components } = require('detritus-client/lib/utils');
|
||||
|
||||
function renderPlaceCard(context, place) {
|
||||
let cards = [createEmbed("defaultNoFooter", context, {
|
||||
author: {
|
||||
iconUrl: place.style.icon.url,
|
||||
name: place.title,
|
||||
url: place.url
|
||||
},
|
||||
description: `${place.address.full}`,
|
||||
url: place.url,
|
||||
color: parseInt(place.style.color.substring(1, 7), 16)
|
||||
})]
|
||||
|
||||
if (place.display_type) {
|
||||
cards[0].description = `-# ${place.display_type}\n\n` + cards[0].description
|
||||
}
|
||||
|
||||
if (place.ratings?.score) {
|
||||
let ratingString = "";
|
||||
|
||||
ratingString += icon("maps_star_half").repeat(Math.floor(place.ratings.score))
|
||||
|
||||
if (place.ratings.score < 5) {
|
||||
if ((place.ratings.score - Math.floor(place.ratings.score)) >= 0.5) ratingString += icon("maps_star_half")
|
||||
else ratingString += icon("maps_star_empty");
|
||||
ratingString += icon("maps_star_empty").repeat(5 - Math.ceil(place.ratings.score))
|
||||
}
|
||||
|
||||
cards[0].description += `\n\n> -# ${ratingString} **${place.ratings.score}** (${link(place.ratings.url, place.ratings.reviews.toLocaleString("en-US"), "Amount of user reviews")})`
|
||||
}
|
||||
|
||||
if (place.description) {
|
||||
cards[0].description += `\n\n${place.description}`
|
||||
}
|
||||
|
||||
|
||||
if (place.photos?.length) {
|
||||
|
||||
cards[0].image = {
|
||||
url: place.photos.shift()
|
||||
}
|
||||
|
||||
if (place.photos.length) {
|
||||
for (const p of place.photos) {
|
||||
cards.push({
|
||||
url: place.url,
|
||||
image: {
|
||||
url: p
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
name: 'maps',
|
||||
description: 'Search for places on Google Maps.',
|
||||
contexts: [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
integrationTypes: [
|
||||
1
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'query',
|
||||
description: 'Google Maps search query.',
|
||||
type: ApplicationCommandOptionTypes.TEXT,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'incognito',
|
||||
description: 'Makes the response only visible to you.',
|
||||
type: ApplicationCommandOptionTypes.BOOLEAN,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
],
|
||||
run: async (context, args) => {
|
||||
await acknowledge(context, args.incognito);
|
||||
|
||||
try {
|
||||
let search = await maps(context, args.query)
|
||||
search = search.response.body
|
||||
|
||||
|
||||
// Create initial response page
|
||||
let embeds = [];
|
||||
|
||||
let mapCard = createEmbed("default", context, {
|
||||
image: {
|
||||
url: search.assets.map
|
||||
},
|
||||
footer: {
|
||||
iconUrl: STATICS.googlemaps,
|
||||
text: `Map Data ©2024 Google • ${context.application.name}`
|
||||
}
|
||||
})
|
||||
|
||||
embeds.push(mapCard)
|
||||
|
||||
let components = [];
|
||||
|
||||
// Instant Place Result
|
||||
if (search.place) {
|
||||
embeds = [...embeds, ...renderPlaceCard(context, search.place)]
|
||||
} else {
|
||||
let supplementalCache = {}
|
||||
|
||||
components = new Components({
|
||||
timeout: 100000,
|
||||
run: async (ctx) => {
|
||||
if (ctx.userId !== context.userId) return await ctx.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE);
|
||||
|
||||
try {
|
||||
// Disable component and update the default
|
||||
|
||||
let value = ctx.data.values[0];
|
||||
|
||||
let searchSupplemental;
|
||||
|
||||
for (let i = 0; i < components.components[0].components[0].options.length; i++) {
|
||||
let c = components.components[0].components[0];
|
||||
|
||||
components.components[0].components[0].options[i].default = (components.components[0].components[0].options[i].value == value)
|
||||
components.components[0].components[0].options[i].emoji = iconAsEmojiObject(`maps_${search.places[i].place.icon}_pin`)
|
||||
|
||||
// make the selected pin red
|
||||
if(c.options[i].value === value) components.components[0].components[0].options[i].emoji = iconAsEmojiObject(`maps_location_pin`);
|
||||
}
|
||||
|
||||
if (!supplementalCache[value]) {
|
||||
components.components[0].components[0].disabled = true;
|
||||
|
||||
await ctx.editOrRespond({
|
||||
embeds: [mapCard, createEmbed("defaultNoFooter", context, {
|
||||
image: {
|
||||
url: STATIC_ASSETS.chat_loading
|
||||
}
|
||||
})],
|
||||
components
|
||||
})
|
||||
|
||||
searchSupplemental = await mapsSupplemental(context, search.places[parseInt(value)].supplemental_key)
|
||||
|
||||
searchSupplemental = searchSupplemental.response.body
|
||||
supplementalCache[value] = searchSupplemental
|
||||
|
||||
components.components[0].components[0].disabled = false;
|
||||
} else {
|
||||
searchSupplemental = supplementalCache[value]
|
||||
}
|
||||
|
||||
mapCard = createEmbed("default", context, {
|
||||
image: {
|
||||
url: searchSupplemental.assets.map
|
||||
},
|
||||
footer: {
|
||||
iconUrl: STATICS.googlemaps,
|
||||
text: `Map Data ©2024 Google • ${context.application.name}`
|
||||
}
|
||||
})
|
||||
|
||||
await ctx.editOrRespond({
|
||||
embeds: [mapCard, ...renderPlaceCard(context, searchSupplemental.place)],
|
||||
components
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
components.components[0].components[0].disabled = false;
|
||||
await ctx.editOrRespond({
|
||||
embeds: [mapCard, createEmbed("error", context, "Something went wrong trying to view this place.")],
|
||||
components
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
components.addSelectMenu({
|
||||
type: 3,
|
||||
custom_id: "place-picker",
|
||||
placeholder: "Select a place",
|
||||
defaultValues: [],
|
||||
options: search.places.map((p, i) => ({
|
||||
label: p.place.name,
|
||||
value: `${i}`,
|
||||
emoji: icon(`maps_${p.place.icon}_pin`),
|
||||
description: p.place.address
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
return await editOrReply(context, {
|
||||
embeds,
|
||||
components
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.response?.body?.status && e.response.body.status == 2 && e.response.body.message) return editOrReply(context, createEmbed("warning", context, e.response.body.message))
|
||||
console.log(JSON.stringify(e.raw) || e)
|
||||
return editOrReply(context, createEmbed("error", context, `Something went wrong.`))
|
||||
}
|
||||
},
|
||||
};
|
209
commands/message/search/maps.js
Normal file
209
commands/message/search/maps.js
Normal file
|
@ -0,0 +1,209 @@
|
|||
const { maps, mapsSupplemental } = require('#api');
|
||||
|
||||
const { createEmbed } = require('#utils/embed')
|
||||
const { smallIconPill, link, icon, iconAsEmojiObject } = require('#utils/markdown');
|
||||
const { editOrReply } = require('#utils/message')
|
||||
const { STATICS, STATIC_ASSETS } = require('#utils/statics')
|
||||
|
||||
// TODO: Turn this into a general purpose permissions constant
|
||||
const { Permissions } = require("detritus-client/lib/constants");
|
||||
const { Components } = require('detritus-client/lib/utils');
|
||||
const { description } = require('../../interaction/slash/search/google');
|
||||
|
||||
function renderPlaceCard(context, place) {
|
||||
let cards = [createEmbed("defaultNoFooter", context, {
|
||||
author: {
|
||||
iconUrl: place.style.icon.url,
|
||||
name: place.title,
|
||||
url: place.url
|
||||
},
|
||||
description: `${place.address.full}`,
|
||||
url: place.url,
|
||||
color: parseInt(place.style.color.substring(1, 7), 16)
|
||||
})]
|
||||
|
||||
if (place.display_type) {
|
||||
cards[0].description = `-# ${place.display_type}\n\n` + cards[0].description
|
||||
}
|
||||
|
||||
if (place.ratings?.score) {
|
||||
let ratingString = "";
|
||||
|
||||
ratingString += icon("maps_star_half").repeat(Math.floor(place.ratings.score))
|
||||
|
||||
if (place.ratings.score < 5) {
|
||||
if ((place.ratings.score - Math.floor(place.ratings.score)) >= 0.5) ratingString += icon("maps_star_half")
|
||||
else ratingString += icon("maps_star_empty");
|
||||
ratingString += icon("maps_star_empty").repeat(5 - Math.ceil(place.ratings.score))
|
||||
}
|
||||
|
||||
cards[0].description += `\n\n> -# ${ratingString} **${place.ratings.score}** (${link(place.ratings.url, place.ratings.reviews.toLocaleString("en-US"), "Amount of user reviews")})`
|
||||
}
|
||||
|
||||
if (place.description) {
|
||||
cards[0].description += `\n\n${place.description}`
|
||||
}
|
||||
|
||||
|
||||
if (place.photos?.length) {
|
||||
|
||||
cards[0].image = {
|
||||
url: place.photos.shift()
|
||||
}
|
||||
|
||||
if (place.photos.length) {
|
||||
for (const p of place.photos) {
|
||||
cards.push({
|
||||
url: place.url,
|
||||
image: {
|
||||
url: p
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
name: 'maps',
|
||||
aliases: ['m','map','googlemaps','gm'],
|
||||
label: 'query',
|
||||
metadata: {
|
||||
description: 'Searches for places on Google Maps.',
|
||||
description_short: 'Search google maps',
|
||||
examples: ['m Empire State Building'],
|
||||
category: 'search',
|
||||
usage: 'maps <query>',
|
||||
slashCommand: "maps"
|
||||
},
|
||||
permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY, Permissions.READ_MESSAGE_HISTORY],
|
||||
run: async (context, args) => {
|
||||
context.triggerTyping();
|
||||
if (!args.query) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (query).`))
|
||||
try {
|
||||
let search = await maps(context, args.query)
|
||||
search = search.response.body
|
||||
|
||||
|
||||
// Create initial response page
|
||||
let embeds = [];
|
||||
|
||||
let mapCard = createEmbed("default", context, {
|
||||
image: {
|
||||
url: search.assets.map
|
||||
},
|
||||
footer: {
|
||||
iconUrl: STATICS.googlemaps,
|
||||
text: `Map Data ©2024 Google • ${context.application.name}`
|
||||
}
|
||||
})
|
||||
|
||||
embeds.push(mapCard)
|
||||
|
||||
let components = [];
|
||||
|
||||
// Instant Place Result
|
||||
if (search.place) {
|
||||
embeds = [...embeds, ...renderPlaceCard(context, search.place)]
|
||||
} else {
|
||||
let supplementalCache = {}
|
||||
|
||||
components = new Components({
|
||||
timeout: 100000,
|
||||
onTimeout: async()=>{
|
||||
if(!context.response.deleted) await editOrReply({ embeds: context.response.embeds })
|
||||
},
|
||||
run: async (ctx) => {
|
||||
if (ctx.userId !== context.userId) return await ctx.respond(InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE);
|
||||
|
||||
try {
|
||||
// Disable component and update the default
|
||||
|
||||
let value = ctx.data.values[0];
|
||||
|
||||
let searchSupplemental;
|
||||
|
||||
for (let i = 0; i < components.components[0].components[0].options.length; i++) {
|
||||
let c = components.components[0].components[0];
|
||||
|
||||
components.components[0].components[0].options[i].default = (components.components[0].components[0].options[i].value == value)
|
||||
components.components[0].components[0].options[i].emoji = iconAsEmojiObject(`maps_${search.places[i].place.icon}_pin`)
|
||||
|
||||
// make the selected pin red
|
||||
if(c.options[i].value === value) components.components[0].components[0].options[i].emoji = iconAsEmojiObject(`maps_location_pin`);
|
||||
}
|
||||
|
||||
if (!supplementalCache[value]) {
|
||||
components.components[0].components[0].disabled = true;
|
||||
|
||||
await ctx.editOrRespond({
|
||||
embeds: [mapCard, createEmbed("defaultNoFooter", context, {
|
||||
image: {
|
||||
url: STATIC_ASSETS.chat_loading
|
||||
}
|
||||
})],
|
||||
components
|
||||
})
|
||||
|
||||
searchSupplemental = await mapsSupplemental(context, search.places[parseInt(value)].supplemental_key)
|
||||
|
||||
searchSupplemental = searchSupplemental.response.body
|
||||
supplementalCache[value] = searchSupplemental
|
||||
|
||||
components.components[0].components[0].disabled = false;
|
||||
} else {
|
||||
searchSupplemental = supplementalCache[value]
|
||||
}
|
||||
|
||||
mapCard = createEmbed("default", context, {
|
||||
image: {
|
||||
url: searchSupplemental.assets.map
|
||||
},
|
||||
footer: {
|
||||
iconUrl: STATICS.googlemaps,
|
||||
text: `Map Data ©2024 Google • ${context.application.name}`
|
||||
}
|
||||
})
|
||||
|
||||
await ctx.editOrRespond({
|
||||
embeds: [mapCard, ...renderPlaceCard(context, searchSupplemental.place)],
|
||||
components
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
components.components[0].components[0].disabled = false;
|
||||
await ctx.editOrRespond({
|
||||
embeds: [mapCard, createEmbed("error", context, "Something went wrong trying to view this place.")],
|
||||
components
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
components.addSelectMenu({
|
||||
type: 3,
|
||||
custom_id: "place-picker",
|
||||
placeholder: "Select a place",
|
||||
defaultValues: [],
|
||||
options: search.places.map((p, i) => ({
|
||||
label: p.place.name,
|
||||
value: `${i}`,
|
||||
emoji: icon(`maps_${p.place.icon}_pin`),
|
||||
description: p.place.address
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
return await editOrReply(context, {
|
||||
embeds,
|
||||
components
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.response?.body?.status && e.response.body.status == 2 && e.response.body.message) return editOrReply(context, createEmbed("warning", context, e.response.body.message))
|
||||
console.log(JSON.stringify(e.raw) || e)
|
||||
return editOrReply(context, createEmbed("error", context, `Something went wrong.`))
|
||||
}
|
||||
},
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue