Skip to content

Commit

Permalink
feat: add user's personal best to level reply if linked
Browse files Browse the repository at this point in the history
  • Loading branch information
wopian committed Jan 19, 2023
1 parent fbbff1d commit 18f4541
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 60 deletions.
59 changes: 35 additions & 24 deletions src/commands/level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,38 @@ import { levelRecords } from '../components/levelRecords.js'
import { levelsList } from '../components/levelsList.js'
import { getLevels } from '../services/levels.js'

const getOptions = (interaction: CommandInteraction) => {
const id = interaction.options.data.find(option => option.name === 'id')
?.value as number
const workshopId = interaction.options.data.find(
option => option.name === 'workshopid'
)?.value as string
const author = interaction.options.data.find(
option => option.name === 'author'
)?.value as string
const name = interaction.options.data.find(option => option.name === 'name')
?.value as string

return { id, workshopId, author, name }
}

const replyNoLevels = async (
interaction: CommandInteraction,
invalidArguments = false
) => {
const embed = new EmbedBuilder()
.setColor(0xff_00_00)
.setTitle(invalidArguments ? 'Missing Arguments' : 'No level found')
.setDescription(
invalidArguments
? 'You must provide either a level ID, workshop ID, author or name of a level.'
: 'No level found with the provided arguments.'
)
.setTimestamp()

await interaction.reply({ embeds: [embed], ephemeral: true })
}

export const level: Command = {
name: 'level',
description: 'Get records for a level',
Expand Down Expand Up @@ -42,26 +74,12 @@ export const level: Command = {
}
],
run: async (interaction: CommandInteraction) => {
const id = interaction.options.data.find(option => option.name === 'id')
?.value as number
const workshopId = interaction.options.data.find(
option => option.name === 'workshopid'
)?.value as string
const author = interaction.options.data.find(
option => option.name === 'author'
)?.value as string
const name = interaction.options.data.find(option => option.name === 'name')
?.value as string

const { id, workshopId, author, name } = getOptions(interaction)
console.log('[level]:', id, workshopId, author, name)

if (!id && !workshopId && !author && !name) {
console.log('[level]:', 'No arguments provided')
await interaction.reply({
content:
'You must provide either a level ID, workshop ID, author or name of a level.',
ephemeral: true
})
await replyNoLevels(interaction, true)
return
}

Expand All @@ -76,13 +94,7 @@ export const level: Command = {

if (levels.totalAmount === 0) {
console.log('[level]:', 'No level found', levels)
const embed = new EmbedBuilder()
.setColor(0xff_00_00)
.setTitle('No level found')
.setDescription('No level found with the provided arguments.')
.setTimestamp()

await interaction.reply({ embeds: [embed], ephemeral: true })
await replyNoLevels(interaction)
return
}

Expand All @@ -93,7 +105,6 @@ export const level: Command = {
levels.levels,
levels.totalAmount
)

await interaction.reply({ embeds })
return
}
Expand Down
121 changes: 85 additions & 36 deletions src/components/levelRecords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
italic
} from 'discord.js'

import { LinkedAccount } from '../models/database/linkedAccounts.js'
import { Level } from '../models/level.js'
import { database } from '../services/database.js'
import { getRecords } from '../services/records.js'
import {
formatRelativeDate,
Expand All @@ -23,6 +25,13 @@ export const levelRecords = async (
page = 1,
limit = 10
) => {
const user = await database<LinkedAccount>('linked_accounts')
.select('steamId')
.where({
discordId: String(interaction.user.id)
})
console.log(user)

const records = await getRecords({
LevelId: level.id,
BestOnly: true,
Expand All @@ -31,22 +40,17 @@ export const levelRecords = async (
})

const totalPages = Math.ceil(records.totalAmount / limit)

let recordsList = records.records
.map((record, index) => {
const recordNumber = bold(`${index + 1}.`)
const recordTime = inlineCode(formatResultTime(record.time))
const recordUser = hyperlink(
record.user.steamName,
`https://zeepkist.wopian.me/user/${record.user.steamId}`
)
const recordDate = formatRelativeDate(record.dateCreated)
return `${recordNumber} ${recordTime} by ${recordUser} (${recordDate})`
const embed = new EmbedBuilder()
.setColor(0xff_92_00)
.setTitle(`${level.name}`)
.setFooter({
text: `Page ${page} of ${totalPages}. ${providedBy}`
})
.setTimestamp()
.setURL(`https://zeepkist.wopian.me/level/${level.id}`)
.setAuthor({
name: level.author
})
.join('\n')
if (records.totalAmount > limit) {
recordsList += `\n\n${italic('Only the first 10 levels are shown.')}`
}

const medalTimes = [
level.timeAuthor &&
Expand All @@ -67,29 +71,74 @@ export const levelRecords = async (
)}`
].join('\n')

const embed = new EmbedBuilder()
.setColor(0xff_92_00)
.setTitle(`${level.name}`)
.setFooter({
text: `Page ${page} of ${totalPages}. ${providedBy}`
embed.addFields({
name: 'Medal Times',
value: medalTimes,
inline: true
})

if (user && user.length > 0) {
const userRecord = await getRecords({
LevelId: level.id,
UserSteamId: user[0].steamId,
BestOnly: true
})
.setTimestamp()
.setURL(`https://zeepkist.wopian.me/level/${level.id}`)
.setAuthor({
name: level.author

console.log(userRecord)

if (userRecord && userRecord.records.length > 0) {
const record = userRecord.records[0]

let bestMedal
if (record.isWorldRecord) bestMedal = 'WR '
else if (record.time < level.timeAuthor)
bestMedal = '<:zeepkist_author:1008786679173234688> '
else if (record.time < level.timeGold)
bestMedal = '<:zeepkist_gold:1008786743706783826> '
else if (record.time < level.timeSilver)
bestMedal = '<:zeepkist_silver:1008786769380130959> '
else if (record.time < level.timeBronze)
bestMedal = '<:zeepkist_bronze:1008786713688166400> '

const personalBest = `${bestMedal}${inlineCode(
formatResultTime(record.time)
)}\n${formatRelativeDate(record.dateCreated)} with ${
userRecord.totalAmount
} total runs`

embed.addFields({
name: 'Your Personal Best',
value: personalBest,
inline: true
})
}
}

let recordsList = records.records
.map((record, index) => {
const recordNumber = bold(`${index + 1}.`)
const recordTime = inlineCode(formatResultTime(record.time))
const recordUser = hyperlink(
record.user.steamName,
`https://zeepkist.wopian.me/user/${record.user.steamId}`
)
const recordDate = formatRelativeDate(record.dateCreated)
return `${recordNumber} ${recordTime} by ${recordUser} (${recordDate})`
})
.addFields(
{
name: 'Medal Times',
value: medalTimes
},
{
name: 'Best Times',
value: recordsList ?? 'No records recorded.'
}
)

if (level.thumbnailUrl) embed.setThumbnail(level.thumbnailUrl)
.join('\n')

if (records.totalAmount > limit) {
recordsList += `\n\n${italic('Only the first 10 levels are shown.')}`
}

embed.addFields({
name: 'Best Times',
value: recordsList ?? 'No records recorded.'
})

if (level.thumbnailUrl) {
embed.setThumbnail(level.thumbnailUrl.replace(' ', '%20'))
}

// const pagination = paginationButtons(interaction, 'level', page, totalPages)

Expand Down
5 changes: 5 additions & 0 deletions src/models/database/linkedAccounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface LinkedAccount {
id: number
discordId: string
steamId: string
}

0 comments on commit 18f4541

Please sign in to comment.