I have a channel that contains 10 embedded messages (1 embed per message). Each embed is a leaderboard for people's best lap times, by Track.
The layout of each embed is
const trackName = new MessageEmbed
.setTitle(trackName)
.addField(user1, lapTime)
.addField(user2, lapTime)
.addField(user3, lapTime)
Assume for example the 3rd embed looks something like this:
| Track 3 Name
| John 37 seconds
| Chris 39 seconds
| Jeff 40 seconds
Beyond simply editing the embed and sending all the information updated manually, how could I update just one particular slot? For example, say Clark comes in with a 38 second lap, how would I move Chris to 3rd, remove Jeff, and add Clark to 2nd so the embed looks as such
| Track 3 Name
| John 37 seconds
| Clark 38 seconds
| Chris 39 seconds
Without changing any other embeds in the channel
You don't necessarily need to create an entirely new embed and input all of the information into it. You could get the current embed from the message, and edit the specific fields you need to edit. Here is an example that you could adapt to work with your system:
function editTrack(msg, newUser, newTime) {
//Assume `msg` is the message in the channel containing the embed you want to edit
//currentEmbed is now the embed you want to edit
let currentEmbed = msg.embeds[0];
//Add `newUser` and its `newTime` to the embed as a new field, in the last position
currentEmbed.addField(newUser, newTime);
//Sorts the embed's fields by the lap times of each user, from lowest to highest
//This example numerically sorts the fields by the number in their value
//This does most of the work for you; the laps are now in the correct order
currentEmbed.fields.sort((a, b) => Number(a.value.split(" second")[0]) - Number(b.value.split(" second")[0]));
//If you want to display only the top 3, remove the 4th field of the embed (if any)
if (currentEmbed.fields.length == 4) currentEmbed.fields.splice(3, 1);
//Now, we need to edit the message with our updated embed (djs 13.x syntax)
return msg.edit({embeds: [currentEmbed]});
}
I tested this editTrack
method using one of my bots' eval commands:
The original embed is successfully edited with the new information. And it only required the Message
object containing the embed, the new lap's user, and the new lap's time.
Edit based on OP's comment:
For the answer to work when editing the track embed with an existing user, who has a new lap time, a slight modification needs to be made. Before removing the 4th field of the embed, you must do something like this:
const names = new Set();
currentEmbed.fields = currentEmbed.fields.filter(field =>
!names.has(field.name) && names.add(field.name)
);
Here's what that code is doing. First, we create a Set
. Sets are iterable structures similar to arrays, but they can only contain unique values. We can therefore use sets to ensure there are no repeats of a user's name. Next, we filter the fields; only the fields whose user is not already contained in names
will remain. If a user's name is not already in names
, it gets added to the set via .add()
. And because the fields are already sorted with the quickest lap time coming first, only the quickest lap of a given user will remain; any longer lap times by the same user will be filtered out.
Note that I only tested this edit briefly, let me know if there are any logical errors or further issues caused by it (or if it fails to work entirely).
Thanks to Cannicide's helpful answer, it led me down the right track.
To achieve the end result of sorting times and overwriting existing times, I ended up with the following function. I require all times be submitted in the format: MINUTES:SECONDS (0:35 = 35s | 4:24 = 4m24s | 62:08 = 1h2m8s).
function editLb(theMessage, newUser, newTime) {
//get the embed you want to edit
let currentEmbed = theMessage.embeds[0];
//Check all existing fields for the same newUser, if the same newUser
//is found, replace that entire field with the name: "Placeholder"
//and the value: "999:99". This will also remove any existing duplicates.
currentEmbed.fields.forEach(field => {
if (field.name == newUser) {
field.name = `Placeholder`;
field.value = `999:99`;
}
})
//add the newUser and the newTime to a new field
currentEmbed.addField(`${newUser}`, `${newTime}`);
//sort all available fields effectively by seconds, by taking
// (minutes*60) + (seconds)
currentEmbed.fields.sort((a, b) => Number((a.value.split(":")[0])*60 + (a.value.split(":")[1])) - Number((b.value.split(":")[0])*60 + (b.value.split(":")[1])));
//If there are now 4 fields, remove the slowest(last) one.
if (currentEmbed.fields.length == 4) currentEmbed.fields.splice(3, 1);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.