Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@

"rules": {
"no-console": "warn",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/consistent-type-definitions": ["error", "type"],
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-unused-vars": [
"error",
{ "ignoreRestSiblings": true }
],
"require-await": "warn"
},

Expand Down
26 changes: 17 additions & 9 deletions src/cache/tip-fact-cache.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import config from "adapters/config"
import { TEST } from "env"
import { logger } from "logger"
import NodeCache from "node-cache"
import { getChance } from "utils/common"
import retry from "retry"

const contentCache = new NodeCache({
stdTTL: 3600,
checkperiod: 3600,
useClones: false,
})

export async function getTipsAndFacts() {
const { ok, data } = await config.getContent("header")

if (ok) {
contentCache.set("content", data)
} else {
contentCache.set("content", { description: { fact: [], tip: [] } })
getTipsAndFacts()
}
export function getTipsAndFacts() {
const operation = retry.operation()
operation.attempt((currentAttempt) => {
logger.info(`Fetching tips and facts... (attempt ${currentAttempt})`)
config.getContent("header").then(({ ok, data }) => {
if (ok) {
logger.info("Fetch tips and facts OK")
contentCache.set("content", data)
} else {
logger.warn("Fetch tips and facts FAIL, retrying...")
contentCache.set("content", { description: { fact: [], tip: [] } })
operation.retry()
}
})
})
}

export function getRandomFact() {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/watchlist/view/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { heightOf, widthOf } from "ui/canvas/calculator"
import { renderChartImage } from "ui/canvas/chart"
import { drawCircleImage, drawRectangle } from "ui/canvas/draw"
import { loadAndCacheImage } from "ui/canvas/image"
import { EmojiKey, emojis, getEmojiURL } from "utils/common"
import { emojis, getEmojiURL } from "utils/common"

export async function renderChart(data: any[]) {
const container: RectangleStats = {
Expand Down Expand Up @@ -73,7 +73,7 @@ export async function renderChart(data: any[]) {
if (!imageUrl && is_pair) {
const [base, target] = symbol
.split("/")
.map((s: string) => emojis[s.toUpperCase() as EmojiKey])
.map((s: string) => emojis[s.toUpperCase() as keyof typeof emojis])
imageUrl =
base && target
? [getEmojiURL(base), getEmojiURL(target)].join("||")
Expand Down
3 changes: 1 addition & 2 deletions src/errors/command-argument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ export class CommandArgumentError extends BotBaseError {
if ((embeds?.length ?? 0) > 0) {
this.reply?.({
content: `> It may be incorrect command, here's a help reference for you ${getEmoji(
"ANIMATED_POINTING_DOWN",
true
"ANIMATED_POINTING_DOWN"
)}`,
embeds,
})
Expand Down
3 changes: 1 addition & 2 deletions src/errors/command-not-allowed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ export class CommandNotAllowedToRunError extends BotBaseError {
.join("\n")}`
: ""
}\n\n${getEmoji(
"ANIMATED_POINTING_RIGHT",
true
"ANIMATED_POINTING_RIGHT"
)} Contact this server's owner to use ${await getSlashCommand(
"bot-manager set"
)} to add your role as a bot manager role.`,
Expand Down
4 changes: 1 addition & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ const rest = new REST({ version: "9" }).setToken(DISCORD_TOKEN)
})
logger.info("Successfully reloaded application (/) commands.")

logger.info("Getting tips and facts.")
await getTipsAndFacts()
logger.info("Success getting tips and facts.")
getTipsAndFacts()

runHttpServer()
} catch (error) {
Expand Down
6 changes: 2 additions & 4 deletions src/ui/discord/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ import {
specificHelpCommand,
} from "utils/commands"
import {
TokenEmojiKey,
emojis,
getEmoji,
getEmojiToken,
getEmojiURL,
msgColors,
roundFloatNumber,
Expand Down Expand Up @@ -642,10 +640,10 @@ export function composeInsufficientBalanceEmbed({
}: {
current?: number
required?: number
symbol: TokenEmojiKey
symbol: string
author?: User
}) {
const tokenEmoji = getEmojiToken(symbol)
const tokenEmoji = getEmoji(symbol)
return composeEmbedMessage(null, {
author: ["Insufficient balance", getEmojiURL(emojis.REVOKE)],
description: `${author}, your balance is insufficient.\nYou can deposit more by using </deposit:1063362961198030868>`,
Expand Down
10 changes: 2 additions & 8 deletions src/ui/discord/select-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@ import {
} from "discord.js"
import { SetDefaultButtonHandler, SetDefaultRenderList } from "types/common"
import { InteractionHandler } from "handlers/discord/select-menu"
import {
EmojiKey,
getAuthor,
getDateStr,
getEmoji,
hasAdministrator,
} from "utils/common"
import { getAuthor, getDateStr, getEmoji, hasAdministrator } from "utils/common"
import { VERTICAL_BAR } from "utils/constants"
import { composeEmbedMessage } from "./embed"
import dayjs from "dayjs"
Expand Down Expand Up @@ -104,7 +98,7 @@ export function composeSimpleSelection(
.map((o, i) =>
customRender
? customRender(o, i)
: `${getEmoji(`NUM_${i + 1}` as EmojiKey)}${VERTICAL_BAR}${o}`
: `${getEmoji(`NUM_${i + 1}`)}${VERTICAL_BAR}${o}`
)
.join("\n")}`
}
Expand Down
96 changes: 63 additions & 33 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
} from "@bonfida/spl-name-service"
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js"

import { DOT, SPACE } from "./constants"
import { API_BASE_URL, DOT, SPACE } from "./constants"
import {
marketplaceEmojis,
rarityEmojis,
Expand All @@ -35,6 +35,68 @@ import {
} from "./nft"
import { swr } from "adapters/fetcher"

class EmojiCache {
private cache: Map<string, { emoji: string; url: string }>
public fallback: string

constructor() {
this.cache = new Map()
this.fallback = "<a:coin:1093923016691421205>"
this.fetch()
}

async fetch() {
try {
logger.info("Fetching emoji data...")
const res = await fetch(`${API_BASE_URL}/product-metadata/emoji`)
if (!res.ok) throw new Error("")
const json = await res.json().catch(() => null)
if (!json) throw new Error("")
const { data } = json
const emojis = data as any[]
for (const emoji of emojis) {
this.cache.set(emoji.code.toUpperCase(), {
emoji: emoji.emoji,
url: emoji.emoji_url,
})
}
logger.info("Fetch emoji data OK")
} catch (e: any) {
logger.error(e)
logger.error("Fetch emoji data FAIL")
process.exit(1)
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getEmoji(_code: string, ..._args: any[]) {
const code = _code.toUpperCase()
if (!this.cache.has(code)) return this.fallback

return this.cache.get(code)!.emoji
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getEmojiURL(_code: string, ..._args: any[]) {
const code = _code.toUpperCase()
if (!this.cache.has(code)) return this.fallback

return this.cache.get(code)!.url
}

getRawEmojiURL(id: string) {
return `https://cdn.discordapp.com/emojis/${id}.png?size=240&quality=lossless`
}
}

const Emoji = new EmojiCache()

export const getEmoji = Emoji.getEmoji.bind(Emoji)
export const getEmojiToken = Emoji.getEmoji.bind(Emoji)
export const getEmojiURL = Emoji.getRawEmojiURL.bind(Emoji)
export type EmojiKey = string
export type TokenEmojiKey = string

dayjs.extend(relativeTime)

const SOL_TLD_AUTHORITY = new PublicKey(
Expand Down Expand Up @@ -507,9 +569,6 @@ export const thumbnails = {
"https://cdn.discordapp.com/attachments/933195103273627719/1100350433295339541/rocket.webp",
}

export type EmojiKey = keyof typeof emojis
export type TokenEmojiKey = keyof typeof tokenEmojis

export function isInteraction(
msgOrInteraction: Message | MessageComponentInteraction
): msgOrInteraction is MessageComponentInteraction {
Expand Down Expand Up @@ -546,31 +605,6 @@ export function maskAddress(str: string, minLen?: number) {
return str
}

export function getEmoji(
key: EmojiKey | "",
animated?: boolean,
fallback = "<a:coin:1093923016691421205>"
) {
if (!key) return fallback

const emoji = emojis[key.toUpperCase() as EmojiKey]
if (!emoji) return fallback

if (isNaN(+emoji)) {
return emoji
}

return `<${
animated || key.toUpperCase().startsWith("ANIMATED_") ? "a" : ""
}:${key.toUpperCase().replace(/-/g, "_").toLowerCase()}:${
emojis[key.toUpperCase() as EmojiKey]
}>`
}

export function getEmojiToken(key: TokenEmojiKey, animated?: boolean) {
return getEmoji(key, animated, getEmoji("ANIMATED_COIN_1", true))
}

export function roundFloatNumber(n: number, fractionDigits = 1) {
return parseFloat(parseFloat(`${n}`).toFixed(fractionDigits))
}
Expand All @@ -579,10 +613,6 @@ export function capFirst(str = "") {
return `${str.charAt(0).toUpperCase()}${str.slice(1)}`
}

export function getEmojiURL(emojiId: string) {
return `https://cdn.discordapp.com/emojis/${emojiId}.png?size=240&quality=lossless`
}

export function getAnimatedEmojiURL(emojiId: string) {
return `https://cdn.discordapp.com/emojis/${emojiId}.gif?size=240&quality=lossless`
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/defi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CommandInteraction, Message } from "discord.js"
import { APIError } from "errors"
import { InsufficientBalanceError } from "errors/insufficient-balance"
import mochiPay from "../adapters/mochi-pay"
import { getAuthor, TokenEmojiKey } from "./common"
import { getAuthor } from "./common"
import { convertString } from "./convert"
import { getProfileIdByDiscord } from "./profile"
import { COMMA, EMPTY } from "./constants"
Expand Down Expand Up @@ -101,7 +101,7 @@ export async function validateBalance({
all,
}: {
msgOrInteraction: Message | CommandInteraction
token: TokenEmojiKey
token: string
amount: number
all?: boolean
}) {
Expand Down
3 changes: 1 addition & 2 deletions src/utils/emoji.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ export function throwOnInvalidEmoji(emoji: string, msg: OriginalMessage) {
msgOrInteraction: msg,
title: "Unsupported emojis",
description: `${getEmoji(
"ANIMATED_POINTING_RIGHT",
true
"ANIMATED_POINTING_RIGHT"
)} Please use an emoji from this server or in the Discord default list.`,
})
}
Expand Down