mirror of
https://gitlab.com/bignutty/labscore.git
synced 2025-06-07 05:42:57 -04:00
224 lines
No EOL
7.2 KiB
JavaScript
224 lines
No EOL
7.2 KiB
JavaScript
const { maps, mapsSupplemental } = require('#api');
|
|
const { PERMISSION_GROUPS } = require('#constants');
|
|
|
|
const { hexToDecimalColor } = require("#utils/color");
|
|
const { createEmbed } = require('#utils/embed');
|
|
const { acknowledge } = require('#utils/interactions');
|
|
const { link, icon, iconAsEmojiObject, citation, stringwrap } = require('#utils/markdown');
|
|
const { editOrReply } = require('#utils/message')
|
|
const { STATICS, STATIC_ASSETS } = require('#utils/statics')
|
|
|
|
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: hexToDecimalColor(place.style.color)
|
|
})]
|
|
|
|
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").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.facts?.length) {
|
|
let fc = 1;
|
|
cards[0].fields = place.facts.map((f)=>{
|
|
let factField = {
|
|
name: f.label,
|
|
value: f.value,
|
|
inline: true
|
|
}
|
|
|
|
if(f.source){
|
|
factField.value += citation(fc++, f.source.url, f.source.label)
|
|
}
|
|
|
|
return factField;
|
|
})
|
|
}
|
|
|
|
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', 'm waffle houses near pentagon'],
|
|
category: 'search',
|
|
usage: 'maps <query>',
|
|
slashCommand: "maps"
|
|
},
|
|
permissionsClient: [...PERMISSION_GROUPS.baseline],
|
|
run: async (context, args) => {
|
|
await acknowledge(context);
|
|
|
|
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 ©${new Date().getFullYear()} 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 ©${new Date().getFullYear()} 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: stringwrap(p.place.name, 100),
|
|
value: `${i}`,
|
|
emoji: icon(`maps_${p.place.icon}_pin`),
|
|
description: stringwrap(p.place.address, 100)
|
|
}))
|
|
})
|
|
}
|
|
|
|
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.`))
|
|
}
|
|
},
|
|
}; |