presence: cv2ify
This commit is contained in:
		
							parent
							
								
									f0d23e2367
								
							
						
					
					
						commit
						5a235ad023
					
				
					 1 changed files with 122 additions and 83 deletions
				
			
		| 
						 | 
				
			
			@ -2,13 +2,19 @@ const Command = require("#lib/command.js");
 | 
			
		|||
 | 
			
		||||
const sharp = require("sharp");
 | 
			
		||||
 | 
			
		||||
const {ActivityTypeNames, CDNEndpoints, Games, HangStatusStrings, HANG_STATUS_ICONS} = require("#util/dconstants.js");
 | 
			
		||||
const {
 | 
			
		||||
  ActivityTypeNames,
 | 
			
		||||
  CDNEndpoints,
 | 
			
		||||
  Games,
 | 
			
		||||
  /*HangStatusStrings,
 | 
			
		||||
  HANG_STATUS_ICONS*/
 | 
			
		||||
} = require("#util/dconstants.js");
 | 
			
		||||
const {Icons} = require("#util/constants.js");
 | 
			
		||||
const {formatUsername} = require("#util/misc.js");
 | 
			
		||||
const {formatUsername, getTopColor} = require("#util/misc.js");
 | 
			
		||||
const {lookupUser} = require("#util/selection.js");
 | 
			
		||||
const {formatTime} = require("#util/time.js");
 | 
			
		||||
 | 
			
		||||
const HangStatusImages = {};
 | 
			
		||||
/*const HangStatusImages = {};
 | 
			
		||||
(async () => {
 | 
			
		||||
  for (const key of Object.keys(HANG_STATUS_ICONS)) {
 | 
			
		||||
    const svg = await fetch(HANG_STATUS_ICONS[key])
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +22,7 @@ const HangStatusImages = {};
 | 
			
		|||
      .then((b) => Buffer.from(b));
 | 
			
		||||
    HangStatusImages[key] = await sharp(svg, {density: 2400}).resize(128).toBuffer();
 | 
			
		||||
  }
 | 
			
		||||
})();
 | 
			
		||||
})();*/
 | 
			
		||||
 | 
			
		||||
const NOWPLAYING_BAR_LENGTH = 32;
 | 
			
		||||
const NOWPLAYING_BAR_CHAR = "\u2014";
 | 
			
		||||
| 
						 | 
				
			
			@ -85,33 +91,64 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
      icons.push(Icons.presence[platform][status]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const embeds = [];
 | 
			
		||||
    const components = [];
 | 
			
		||||
    const files = [];
 | 
			
		||||
 | 
			
		||||
    for (const index in target.activities) {
 | 
			
		||||
      const activity = target.activities[index];
 | 
			
		||||
      if (activity.type == 4) {
 | 
			
		||||
        const embed = {};
 | 
			
		||||
        let label;
 | 
			
		||||
        if (activity.details) {
 | 
			
		||||
          switch (activity.details) {
 | 
			
		||||
            case "listen":
 | 
			
		||||
              label = "\ud83c\udfb5 On repeat";
 | 
			
		||||
              break;
 | 
			
		||||
            case "watch":
 | 
			
		||||
              label = "\ud83d\udcfa Watching lately";
 | 
			
		||||
              break;
 | 
			
		||||
            case "play":
 | 
			
		||||
              label = "\ud83c\udfae Playing lately";
 | 
			
		||||
              break;
 | 
			
		||||
            case "think":
 | 
			
		||||
              label = "\ud83d\udca1 Shower thought";
 | 
			
		||||
              break;
 | 
			
		||||
            case "love":
 | 
			
		||||
              label = "\u2764\ufe0f Loving lately";
 | 
			
		||||
              break;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let status = "";
 | 
			
		||||
        if (label) status = `-# ${label}\n`;
 | 
			
		||||
        let url;
 | 
			
		||||
        if (activity.emoji) {
 | 
			
		||||
          if (activity.emoji.id) {
 | 
			
		||||
            const url = CDNEndpoints.EMOJI(activity.emoji.id, activity.emoji.animated);
 | 
			
		||||
            embed.author = {
 | 
			
		||||
              url,
 | 
			
		||||
              icon_url: url,
 | 
			
		||||
              name: activity.state ?? "\u200b",
 | 
			
		||||
            url = CDNEndpoints.EMOJI(activity.emoji.id, activity.emoji.animated);
 | 
			
		||||
          } else {
 | 
			
		||||
            url = `https://jdecked.github.io/twemoji/v/latest/72x72/${[...activity.emoji.name]
 | 
			
		||||
              .map((char) => char.codePointAt().toString(16))
 | 
			
		||||
              .join("-")}.png`;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        status += activity.state ?? "\u200b";
 | 
			
		||||
 | 
			
		||||
        status += `\n\n-# <t:${Math.floor(activity.created_at / 1000)}:f>`;
 | 
			
		||||
 | 
			
		||||
        const content = {
 | 
			
		||||
          type: 10,
 | 
			
		||||
          content: status,
 | 
			
		||||
        };
 | 
			
		||||
          } else {
 | 
			
		||||
            embed.title = `${activity.emoji.name} ${activity.state ?? ""}`;
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          embed.title = activity.state ?? "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        embed.timestamp = new Date(activity.created_at).toISOString();
 | 
			
		||||
 | 
			
		||||
        embeds.push(embed);
 | 
			
		||||
      } else if (activity.type == 6) {
 | 
			
		||||
        if (url) {
 | 
			
		||||
          components.push({
 | 
			
		||||
            type: 9,
 | 
			
		||||
            components: [content],
 | 
			
		||||
            accessory: {type: 11, media: {url}},
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          components.push(content);
 | 
			
		||||
        }
 | 
			
		||||
        /*} else if (activity.type == 6) {
 | 
			
		||||
        const embed = {};
 | 
			
		||||
 | 
			
		||||
        embed.title = "Hang Status";
 | 
			
		||||
| 
						 | 
				
			
			@ -135,12 +172,11 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
 | 
			
		||||
        embed.timestamp = new Date(activity.created_at).toISOString();
 | 
			
		||||
 | 
			
		||||
        embeds.push(embed);
 | 
			
		||||
        embeds.push(embed);*/
 | 
			
		||||
      } else {
 | 
			
		||||
        const embed = {
 | 
			
		||||
          title: `${ActivityTypeNames[activity.type]} **${activity.name}**`,
 | 
			
		||||
          fields: [],
 | 
			
		||||
        };
 | 
			
		||||
        const comp = [];
 | 
			
		||||
        comp.push({type: 10, content: `${ActivityTypeNames[activity.type]} **${activity.name}**`});
 | 
			
		||||
 | 
			
		||||
        const descLines = [];
 | 
			
		||||
        if (activity.type == 2) {
 | 
			
		||||
          if (activity.details) {
 | 
			
		||||
| 
						 | 
				
			
			@ -207,32 +243,25 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        if (activity.assets?.large_text && activity.type != 2) {
 | 
			
		||||
          embed.fields.push({
 | 
			
		||||
            name: "Large Text",
 | 
			
		||||
            value: activity.assets.large_text,
 | 
			
		||||
          });
 | 
			
		||||
          descLines.push("### Large Text", activity.assets.large_text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (activity.assets?.small_text) {
 | 
			
		||||
          embed.fields.push({
 | 
			
		||||
            name: "Small Text",
 | 
			
		||||
            value: activity.assets.small_text,
 | 
			
		||||
          });
 | 
			
		||||
          descLines.push("### Small Text", activity.assets.small_text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (activity.application_id) {
 | 
			
		||||
          embed.fields.push({
 | 
			
		||||
            name: "Application ID",
 | 
			
		||||
            value: `\`${activity.application_id}\``,
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
        descLines.push(
 | 
			
		||||
          `\n-# ${activity.application_id ? activity.application_id + " \u2022 " : ""}<t:${Math.floor(
 | 
			
		||||
            activity.created_at / 1000
 | 
			
		||||
          )}:f>`
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        embed.description = descLines.join("\n");
 | 
			
		||||
        const content = {type: 10, content: descLines.join("\n")};
 | 
			
		||||
        let thumbnail;
 | 
			
		||||
        const image_links = [];
 | 
			
		||||
 | 
			
		||||
        if (activity.assets) {
 | 
			
		||||
          if (activity.assets.large_image != null) {
 | 
			
		||||
            const image_links = [];
 | 
			
		||||
 | 
			
		||||
            let largeUrl;
 | 
			
		||||
            if (activity.assets.large_image.startsWith("mp:")) {
 | 
			
		||||
              largeUrl = activity.assets.large_image.replace("mp:", "https://media.discordapp.net/");
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +271,7 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
              largeUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.large_image);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            image_links.push(`[Large Image](${fixMediaProxyURL(largeUrl)})`);
 | 
			
		||||
            image_links.push({label: "Large Image", url: fixMediaProxyURL(largeUrl)});
 | 
			
		||||
 | 
			
		||||
            let smallUrl;
 | 
			
		||||
            if (activity.assets.small_image != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -254,18 +283,18 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
                smallUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.small_image);
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              image_links.push(`[Small Image](${fixMediaProxyURL(smallUrl)})`);
 | 
			
		||||
              image_links.push({label: "Small Image", url: fixMediaProxyURL(smallUrl)});
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const largeImage = await fetch(largeUrl)
 | 
			
		||||
              .then((res) => res.arrayBuffer())
 | 
			
		||||
              .then((b) => Buffer.from(b));
 | 
			
		||||
            const presenceImage = sharp(largeImage).resize(60, 60);
 | 
			
		||||
            const presenceImage = sharp(largeImage).resize(100, 100);
 | 
			
		||||
            if (smallUrl) {
 | 
			
		||||
              const smallImage = await fetch(smallUrl)
 | 
			
		||||
                .then((res) => res.arrayBuffer())
 | 
			
		||||
                .then((b) => Buffer.from(b));
 | 
			
		||||
              const smallImageBuffer = await sharp(smallImage).resize(20, 20).toBuffer();
 | 
			
		||||
              const smallImageBuffer = await sharp(smallImage).resize(32, 32).toBuffer();
 | 
			
		||||
 | 
			
		||||
              presenceImage.composite([
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -279,13 +308,7 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
              contents: await presenceImage.toBuffer(),
 | 
			
		||||
              name: `${index}.png`,
 | 
			
		||||
            });
 | 
			
		||||
            embed.thumbnail = {
 | 
			
		||||
              url: `attachment://${index}.png`,
 | 
			
		||||
            };
 | 
			
		||||
            embed.fields.push({
 | 
			
		||||
              name: "\u200b",
 | 
			
		||||
              value: image_links.join("\u3000\u3000"),
 | 
			
		||||
            });
 | 
			
		||||
            thumbnail = `attachment://${index}.png`;
 | 
			
		||||
          } else if (!activity.assets.large_image && activity.assets.small_image != null) {
 | 
			
		||||
            let smallUrl;
 | 
			
		||||
            if (activity.assets.small_image.startsWith("mp:")) {
 | 
			
		||||
| 
						 | 
				
			
			@ -296,48 +319,64 @@ presence.callback = async function (msg, line) {
 | 
			
		|||
              smallUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.small_image);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const smallImage = await fetch(smallUrl)
 | 
			
		||||
              .then((res) => res.arrayBuffer())
 | 
			
		||||
              .then((b) => Buffer.from(b));
 | 
			
		||||
            const presenceImage = await sharp(smallImage).resize(40, 40).toBuffer();
 | 
			
		||||
 | 
			
		||||
            files.push({
 | 
			
		||||
              contents: presenceImage,
 | 
			
		||||
              name: `${index}.png`,
 | 
			
		||||
            });
 | 
			
		||||
            embed.thumbnail = {
 | 
			
		||||
              url: `attachment://${index}.png`,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            embed.fields.push({
 | 
			
		||||
              name: "\u200b",
 | 
			
		||||
              value: `[Small Image](${fixMediaProxyURL(smallUrl)})`,
 | 
			
		||||
            });
 | 
			
		||||
            thumbnail = fixMediaProxyURL(smallUrl);
 | 
			
		||||
            image_links.push({label: "Small Image", url: thumbnail});
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (activity.application_id && !activity.assets?.large_image && !activity.assets?.small_image) {
 | 
			
		||||
          const game = Games.find((game) => game.id == activity.application_id);
 | 
			
		||||
          if (game?.icon) {
 | 
			
		||||
            embed.thumbnail = {
 | 
			
		||||
              url: `${CDNEndpoints.APP_ICON(game.id, game.icon)}?size=40&keep_aspect_ratio=false`,
 | 
			
		||||
            };
 | 
			
		||||
            embed.fields.push({
 | 
			
		||||
              name: "\u200b",
 | 
			
		||||
              value: `[App Icon](${embed.thumbnail.url.replace("size=40&", "")})`,
 | 
			
		||||
            thumbnail = `${CDNEndpoints.APP_ICON(game.id, game.icon)}?keep_aspect_ratio=false`;
 | 
			
		||||
            image_links.push({label: "App Icon", url: thumbnail});
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (thumbnail != null) {
 | 
			
		||||
          comp.push({
 | 
			
		||||
            type: 9,
 | 
			
		||||
            components: [content],
 | 
			
		||||
            accessory: {type: 11, media: {url: thumbnail}},
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          comp.push(content);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (image_links.length > 0) {
 | 
			
		||||
          for (const link of image_links) {
 | 
			
		||||
            link.type = 2;
 | 
			
		||||
            link.style = 5;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          comp.push({type: 1, components: image_links});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        components.push(comp);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        embed.timestamp = new Date(activity.created_at).toISOString();
 | 
			
		||||
    const finalComponents = [{type: 10, content: `Presence for **${formatUsername(target)}**: ${icons.join(" ")}`}];
 | 
			
		||||
    if (components.length > 0) {
 | 
			
		||||
      const card = {type: 17, components: [], accent_color: getTopColor(msg, target)};
 | 
			
		||||
 | 
			
		||||
        embeds.push(embed);
 | 
			
		||||
      for (const [index, component] of components.entries()) {
 | 
			
		||||
        if (Array.isArray(component)) {
 | 
			
		||||
          card.components.push(...component);
 | 
			
		||||
        } else {
 | 
			
		||||
          card.components.push(component);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (index !== components.length - 1) {
 | 
			
		||||
          card.components.push({type: 14});
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      finalComponents.push(card);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      content: `Presence for **${formatUsername(target)}**: ${icons.join(" ")}`,
 | 
			
		||||
      embeds,
 | 
			
		||||
      flags: 1 << 15,
 | 
			
		||||
      components: finalComponents,
 | 
			
		||||
      files,
 | 
			
		||||
    };
 | 
			
		||||
  } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue