From 592f75762f3ad9d13401345ded30c7e11eafa2bb Mon Sep 17 00:00:00 2001 From: bignutty <3515180-bignutty@users.noreply.gitlab.com> Date: Mon, 15 Jul 2024 23:00:18 +0200 Subject: [PATCH] add fahrenheit --- commands/interaction/slash/utils/weather.js | 137 ++++++++++++++------ commands/message/utils/weather.js | 130 ++++++++++++------- 2 files changed, 182 insertions(+), 85 deletions(-) diff --git a/commands/interaction/slash/utils/weather.js b/commands/interaction/slash/utils/weather.js index 2c30cc7..4c93338 100644 --- a/commands/interaction/slash/utils/weather.js +++ b/commands/interaction/slash/utils/weather.js @@ -1,6 +1,7 @@ const { darksky } = require('#api'); +const { paginator } = require('#client'); -const { createEmbed } = require('#utils/embed'); +const { createEmbed, page } = require('#utils/embed'); const { acknowledge } = require('#utils/interactions'); const { pill, iconPill, smallPill, weatherIcon, timestamp, icon, link, stringwrap} = require('#utils/markdown'); const { editOrReply } = require('#utils/message'); @@ -8,6 +9,69 @@ const { STATICS } = require('#utils/statics'); const { ApplicationCommandOptionTypes } = require('detritus-client/lib/constants'); +const modifiers = { + "°C": (i)=>i, + "°F": (i)=>(i*(9/5))+32 +} + +const unitNames = { + "°C": "Celcius", + "°F": "Fahrenheit" +} + +function temperature(value, units){ + return `${Math.floor(modifiers[units](value))}${units}` +} + +function renderWeatherCard(context, data, units){ + let description = `### ${weatherIcon(data.result.current.icon.id)} ​ ​ ​ ​ ${temperature(data.result.current.temperature.current, units)} • ${data.result.current.condition.label}\n\n${pill("Feels like")} ${smallPill(temperature(data.result.current.temperature.feels_like, units))} ​ ​ ​ ​ ${pill("Wind")} ${smallPill(data.result.current.wind.speed + " km/h")}` + + let secondaryPills = []; + if(data.result.current.humidity > 0) secondaryPills.push(`${pill("Humidity")} ${smallPill(Math.floor(data.result.current.humidity * 100) + "%")}`) + if(data.result.current.uvindex > 0) secondaryPills.push(`${pill("UV Index")} ${smallPill(data.result.current.uvindex)}`) + + if(secondaryPills.length >= 1) description += '\n' + secondaryPills.join(` ​ ​ ​ ​ `) + + description += `\n\n${iconPill("sun", "Sunrise")} ${timestamp(data.result.current.sun.sunrise, "t")} ​ ​ ${iconPill("moon", "Sunset")} ${timestamp(data.result.current.sun.sunset, "t")}` + + // Render weather alerts + if(data.result.warnings.length >= 1){ + for(const w of data.result.warnings.splice(0, 1)){ + if(description.includes(stringwrap(w.label, 50))) continue; + description += `\n\n${icon("warning")} **${stringwrap(w.label, 50)}**\n-# ${stringwrap(w.source, 50)} • ${link(w.url, "Learn More", "Learn more about this alert")}` + } + } + + // Render Forecasts + description += `\n` + + let space = 3; + if(units === "°F") space = 4; + for(const i of data.result.forecast){ + description += `\n${pill(i.day)} ​ ​ ${weatherIcon(i.icon)}` + if(temperature(i.temperature.max, units).toString().length === space) description += `${pill(temperature(i.temperature.max, units) + " ")}` + else description += `${pill(temperature(i.temperature.max, units))}` + description += `​**/**​` + if(temperature(i.temperature.min, units).toString().length === space) description += `${smallPill(temperature(i.temperature.min, units) + " ")}` + else description += `${smallPill(temperature(i.temperature.min, units))}` + } + + + let e = createEmbed("default", context, { + description, + timestamp: new Date(data.result.current.date) + }) + + e.footer.iconUrl = STATICS.weather + if(data.result.location) e.footer.text = data.result.location + + if(data.result.current.icon) e.thumbnail = { url: data.result.current.icon.url } + if(data.result.current.image) e.image = { url: data.result.current.image } + + + return e; +} + module.exports = { name: 'weather', description: 'Check the weather at a location.', @@ -26,6 +90,22 @@ module.exports = { type: ApplicationCommandOptionTypes.TEXT, required: true }, + { + name: 'units', + description: 'Temperature units to use.', + type: ApplicationCommandOptionTypes.TEXT, + choices: [ + { + value: "celcius", + name: "Celcius" + }, + { + value: "fahrenheit", + name: "Fahrenheit" + } + ], + required: false + }, { name: 'incognito', description: 'Makes the response only visible to you.', @@ -42,48 +122,23 @@ module.exports = { data = data.response.body - let description = `### ${weatherIcon(data.result.current.icon.id)} ​ ​ ​ ​ ${Math.floor(data.result.current.temperature.current)}°C • ${data.result.current.condition.label}\n\n${pill("Feels like")} ${smallPill(Math.floor(data.result.current.temperature.feels_like) + "°C")} ​ ​ ​ ​ ${pill("Wind")} ${smallPill(data.result.current.wind.speed + " km/h")}` + let units = ["°C", "°F"] + if(["f","fahrenheit","°f"].includes(args.units.toLowerCase())) units = ["°F", "°C"] - let secondaryPills = []; - if(data.result.current.humidity > 0) secondaryPills.push(`${pill("Humidity")} ${smallPill(Math.floor(data.result.current.humidity * 100) + "%")}`) - if(data.result.current.uvindex > 0) secondaryPills.push(`${pill("UV Index")} ${smallPill(data.result.current.uvindex)}`) + let pages = [] + pages.push(page(renderWeatherCard(context, data, units[0]))) + pages.push(page(renderWeatherCard(context, data, units[1]))) - if(secondaryPills.length >= 1) description += '\n' + secondaryPills.join(` ​ ​ ​ ​ `) - - description += `\n\n${iconPill("sun", "Sunrise")} ${timestamp(data.result.current.sun.sunrise, "t")} ​ ​ ${iconPill("moon", "Sunset")} ${timestamp(data.result.current.sun.sunset, "t")}` - - // Render weather alerts - if(data.result.warnings.length >= 1){ - for(const w of data.result.warnings.splice(0, 1)){ - if(description.includes(stringwrap(w.label, 50))) continue; - description += `\n\n${icon("warning")} **${stringwrap(w.label, 50)}**\n-# ${stringwrap(w.source, 50)} • ${link(w.url, "Learn More", "Learn more about this alert")}` - } - } - - // Render Forecasts - description += `\n` - for(const i of data.result.forecast){ - description += `\n${pill(i.day)} ​ ​ ${weatherIcon(i.icon)}` - if(Math.floor(i.temperature.max).toString().length === 1) description += `${pill(Math.floor(i.temperature.max) + "°C ")}` - else description += `${pill(Math.floor(i.temperature.max) + "°C")}` - description += `​**/**​` - if(Math.floor(i.temperature.min).toString().length === 1) description += `${smallPill(Math.floor(i.temperature.min) + "°C ")}` - else description += `${smallPill(Math.floor(i.temperature.min) + "°C")}` - } - - - let e = createEmbed("default", context, { - description, - timestamp: new Date(data.result.current.date) - }) - - e.footer.iconUrl = STATICS.weather - if(data.result.location) e.footer.text = data.result.location //+ " • " + context.client.user.username - - if(data.result.current.icon) e.thumbnail = { url: data.result.current.icon.url } - if(data.result.current.image) e.image = { url: data.result.current.image } - - return editOrReply(context, e) + await paginator.createPaginator({ + context, + pages, + buttons: [{ + customId: "next", + emoji: "<:ico_button_thermometer:1262512806633144382>", + label: `Toggle ${unitNames[units[0]]}/${unitNames[units[1]]}`, + style: 2 + }] + }); }catch(e){ console.log(e) return editOrReply(context, createEmbed("warning", context, `No weather data available for given location.`)) diff --git a/commands/message/utils/weather.js b/commands/message/utils/weather.js index 569f38d..83f29b1 100644 --- a/commands/message/utils/weather.js +++ b/commands/message/utils/weather.js @@ -1,6 +1,7 @@ const { darksky } = require('#api'); +const { paginator } = require('#client'); -const { createEmbed } = require('#utils/embed') +const { createEmbed, page } = require('#utils/embed') const { pill, iconPill, smallPill, weatherIcon, timestamp, icon, link} = require('#utils/markdown'); const { editOrReply } = require('#utils/message') const { STATICS } = require('#utils/statics'); @@ -8,6 +9,69 @@ const { STATICS } = require('#utils/statics'); // TODO: Turn this into a general purpose permissions constant const { Permissions } = require("detritus-client/lib/constants"); +const modifiers = { + "°C": (i)=>i, + "°F": (i)=>(i*(9/5))+32 +} + +const unitNames = { + "°C": "Celcius", + "°F": "Fahrenheit" +} + +function temperature(value, units){ + return `${Math.floor(modifiers[units](value))}${units}` +} + +function renderWeatherCard(context, data, units){ + let description = `### ${weatherIcon(data.result.current.icon.id)} ​ ​ ​ ​ ${temperature(data.result.current.temperature.current, units)} • ${data.result.current.condition.label}\n\n${pill("Feels like")} ${smallPill(temperature(data.result.current.temperature.feels_like, units))} ​ ​ ​ ​ ${pill("Wind")} ${smallPill(data.result.current.wind.speed + " km/h")}` + + let secondaryPills = []; + if(data.result.current.humidity > 0) secondaryPills.push(`${pill("Humidity")} ${smallPill(Math.floor(data.result.current.humidity * 100) + "%")}`) + if(data.result.current.uvindex > 0) secondaryPills.push(`${pill("UV Index")} ${smallPill(data.result.current.uvindex)}`) + + if(secondaryPills.length >= 1) description += '\n' + secondaryPills.join(` ​ ​ ​ ​ `) + + description += `\n\n${iconPill("sun", "Sunrise")} ${timestamp(data.result.current.sun.sunrise, "t")} ​ ​ ${iconPill("moon", "Sunset")} ${timestamp(data.result.current.sun.sunset, "t")}` + + // Render weather alerts + if(data.result.warnings.length >= 1){ + for(const w of data.result.warnings.splice(0, 1)){ + if(description.includes(stringwrap(w.label, 50))) continue; + description += `\n\n${icon("warning")} **${stringwrap(w.label, 50)}**\n-# ${stringwrap(w.source, 50)} • ${link(w.url, "Learn More", "Learn more about this alert")}` + } + } + + // Render Forecasts + description += `\n` + + let space = 3; + if(units === "°F") space = 4; + for(const i of data.result.forecast){ + description += `\n${pill(i.day)} ​ ​ ${weatherIcon(i.icon)}` + if(temperature(i.temperature.max, units).toString().length === space) description += `${pill(temperature(i.temperature.max, units) + " ")}` + else description += `${pill(temperature(i.temperature.max, units))}` + description += `​**/**​` + if(temperature(i.temperature.min, units).toString().length === space) description += `${smallPill(temperature(i.temperature.min, units) + " ")}` + else description += `${smallPill(temperature(i.temperature.min, units))}` + } + + + let e = createEmbed("default", context, { + description, + timestamp: new Date(data.result.current.date) + }) + + e.footer.iconUrl = STATICS.weather + if(data.result.location) e.footer.text = data.result.location + + if(data.result.current.icon) e.thumbnail = { url: data.result.current.icon.url } + if(data.result.current.image) e.image = { url: data.result.current.image } + + + return e; +} + module.exports = { name: 'weather', aliases: ['forecast'], @@ -15,11 +79,14 @@ module.exports = { metadata: { description: 'Displays information about the weather.', description_short: 'Local weather information', - examples: ['weather Otter, Germany'], + examples: ['weather Otter, Germany -t f'], category: 'utils', - usage: 'weather ', + usage: 'weather [-t ', slashCommand: "weather" }, + args: [ + {name: 't', default: 'celcius', type: 'units', help: "Temperature Units to use."}, + ], permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { context.triggerTyping(); @@ -29,50 +96,25 @@ module.exports = { data = data.response.body - let description = `### ${weatherIcon(data.result.current.icon.id)} ​ ​ ​ ​ ${Math.floor(data.result.current.temperature.current)}°C • ${data.result.current.condition.label}\n\n${pill("Feels like")} ${smallPill(Math.floor(data.result.current.temperature.feels_like) + "°C")} ​ ​ ​ ​ ${pill("Wind")} ${smallPill(data.result.current.wind.speed + " km/h")}` + let units = ["°C", "°F"] + if(["f","fahrenheit","°f"].includes(args.t.toLowerCase())) units = ["°F", "°C"] - let secondaryPills = []; - if(data.result.current.humidity > 0) secondaryPills.push(`${pill("Humidity")} ${smallPill(Math.floor(data.result.current.humidity * 100) + "%")}`) - if(data.result.current.uvindex > 0) secondaryPills.push(`${pill("UV Index")} ${smallPill(data.result.current.uvindex)}`) + let pages = [] + pages.push(page(renderWeatherCard(context, data, units[0]))) + pages.push(page(renderWeatherCard(context, data, units[1]))) - if(secondaryPills.length >= 1) description += '\n' + secondaryPills.join(` ​ ​ ​ ​ `) - - description += `\n\n${iconPill("sun", "Sunrise")} ${timestamp(data.result.current.sun.sunrise, "t")} ​ ​ ${iconPill("moon", "Sunset")} ${timestamp(data.result.current.sun.sunset, "t")}` - - // Render weather alerts - if(data.result.warnings.length >= 1){ - for(const w of data.result.warnings.splice(0, 1)){ - if(description.includes(stringwrap(w.label, 50))) continue; - description += `\n\n${icon("warning")} **${stringwrap(w.label, 50)}**\n-# ${stringwrap(w.source, 50)} • ${link(w.url, "Learn More", "Learn more about this alert")}` - } - } - - // Render Forecasts - description += `\n` - for(const i of data.result.forecast){ - description += `\n${pill(i.day)} ​ ​ ${weatherIcon(i.icon)}` - if(Math.floor(i.temperature.max).toString().length === 1) description += `${pill(Math.floor(i.temperature.max) + "°C ")}` - else description += `${pill(Math.floor(i.temperature.max) + "°C")}` - description += `​**/**​` - if(Math.floor(i.temperature.min).toString().length === 1) description += `${smallPill(Math.floor(i.temperature.min) + "°C ")}` - else description += `${smallPill(Math.floor(i.temperature.min) + "°C")}` - } - - - let e = createEmbed("default", context, { - description, - timestamp: new Date(data.result.current.date) - }) - - e.footer.iconUrl = STATICS.weather - if(data.result.location) e.footer.text = data.result.location //+ " • " + context.client.user.username - - if(data.result.current.icon) e.thumbnail = { url: data.result.current.icon.url } - if(data.result.current.image) e.image = { url: data.result.current.image } - - return editOrReply(context, e) + await paginator.createPaginator({ + context, + pages, + buttons: [{ + customId: "next", + emoji: "<:ico_button_thermometer:1262512806633144382>", + label: `Toggle ${unitNames[units[0]]}/${unitNames[units[1]]}`, + style: 2 + }] + }); }catch(e){ return editOrReply(context, createEmbed("warning", context, `No weather data available for given location.`)) } - }, + } }; \ No newline at end of file