Add calendar overview to /linkcal

This commit is contained in:
NovaFox161
2021-11-20 00:15:37 -06:00
parent d8ba6ddbbf
commit ecb34fc13b
9 changed files with 117 additions and 18 deletions

View File

@@ -17,6 +17,11 @@ class LinkCalendarCommand : SlashCommand {
override val ephemeral = false
override fun handle(event: ChatInputInteractionEvent, settings: GuildSettings): Mono<Message> {
val showOverview = event.getOption("overview")
.flatMap(ApplicationCommandInteractionOption::getValue)
.map(ApplicationCommandInteractionOptionValue::asBoolean)
.orElse(true)
val calendarNumber = event.getOption("calendar")
.flatMap(ApplicationCommandInteractionOption::getValue)
.map(ApplicationCommandInteractionOptionValue::asLong)
@@ -24,7 +29,7 @@ class LinkCalendarCommand : SlashCommand {
.orElse(1)
return event.interaction.guild.flatMap { guild ->
CalendarEmbed.link(guild, settings, calendarNumber)
CalendarEmbed.link(guild, settings, calendarNumber, showOverview)
.flatMap(event::followup)
}.switchIfEmpty(event.followup(getCommonMsg("error.notFound.calendar", settings)))
}

View File

@@ -8,6 +8,7 @@ import org.dreamexposure.discal.core.`object`.announcement.Announcement
import org.dreamexposure.discal.core.entities.Event
import org.dreamexposure.discal.core.enums.announcement.AnnouncementStyle
import org.dreamexposure.discal.core.enums.announcement.AnnouncementType
import org.dreamexposure.discal.core.extensions.DiscordTimestampFormat.LONG_DATETIME
import org.dreamexposure.discal.core.extensions.asDiscordTimestamp
import org.dreamexposure.discal.core.extensions.discord4j.getSettings
import org.dreamexposure.discal.core.extensions.embedFieldSafe
@@ -40,12 +41,12 @@ object AnnouncementEmbed : EmbedMaker {
builder.addField(
getMessage("announcement", "full.field.start", settings),
event.start.asDiscordTimestamp(),
event.start.asDiscordTimestamp(LONG_DATETIME),
true
)
builder.addField(
getMessage("announcement", "full.field.end", settings),
event.end.asDiscordTimestamp(),
event.end.asDiscordTimestamp(LONG_DATETIME),
true
)
@@ -84,7 +85,7 @@ object AnnouncementEmbed : EmbedMaker {
builder.addField(
getMessage("announcement", "simple.field.start", settings),
event.start.asDiscordTimestamp(),
event.start.asDiscordTimestamp(LONG_DATETIME),
true
)
@@ -116,12 +117,12 @@ object AnnouncementEmbed : EmbedMaker {
builder.addField(
getMessage("announcement", "event.field.start", settings),
event.start.asDiscordTimestamp(),
event.start.asDiscordTimestamp(LONG_DATETIME),
true
)
builder.addField(
getMessage("announcement", "event.field.end", settings),
event.end.asDiscordTimestamp(),
event.end.asDiscordTimestamp(LONG_DATETIME),
true
)

View File

@@ -6,21 +6,20 @@ import org.dreamexposure.discal.core.`object`.GuildSettings
import org.dreamexposure.discal.core.`object`.calendar.PreCalendar
import org.dreamexposure.discal.core.entities.Calendar
import org.dreamexposure.discal.core.enums.time.TimeFormat
import org.dreamexposure.discal.core.extensions.*
import org.dreamexposure.discal.core.extensions.discord4j.getCalendar
import org.dreamexposure.discal.core.extensions.embedDescriptionSafe
import org.dreamexposure.discal.core.extensions.embedFieldSafe
import org.dreamexposure.discal.core.extensions.embedTitleSafe
import org.dreamexposure.discal.core.extensions.toMarkdown
import org.dreamexposure.discal.core.utils.GlobalVal.discalColor
import org.dreamexposure.discal.core.utils.getCommonMsg
import reactor.core.publisher.Mono
import java.time.Instant
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
object CalendarEmbed : EmbedMaker {
fun link(guild: Guild, settings: GuildSettings, calNumber: Int): Mono<EmbedCreateSpec> {
return guild.getCalendar(calNumber).map {
link(guild, settings, it)
fun link(guild: Guild, settings: GuildSettings, calNumber: Int, overview: Boolean): Mono<EmbedCreateSpec> {
return guild.getCalendar(calNumber).flatMap {
if (overview) overview(guild, settings, it, false)
else Mono.just(link(guild, settings, it))
}
}
@@ -42,6 +41,54 @@ object CalendarEmbed : EmbedMaker {
.build()
}
fun overview(guild: Guild, settings: GuildSettings, calendar: Calendar, showUpdate: Boolean): Mono<EmbedCreateSpec> {
return calendar.getUpcomingEvents(15).collectList().map { it.groupByDate() }.map { events ->
val builder = defaultBuilder(guild, settings)
//Handle optional fields
if (calendar.name.isNotBlank())
builder.title(calendar.name.toMarkdown().embedTitleSafe())
if (calendar.description.isNotBlank())
builder.description(calendar.description.toMarkdown().embedDescriptionSafe())
// Show events
events.forEach { date ->
val fieldTitle = getMessage(
"calendar", "link.field.date",
settings,
Instant.from(date.key).asDiscordTimestamp(DiscordTimestampFormat.LONG_DATE)
)
val content = StringBuilder().append("```\n")
date.value.forEach {
content.append(it.start.asDiscordTimestamp(DiscordTimestampFormat.SHORT_TIME))
.append(" - ")
.append(it.end.asDiscordTimestamp(DiscordTimestampFormat.SHORT_TIME))
.append(" | ")
if (it.name.isNotBlank()) content.append(it.name).append(" | ")
content.append(it.eventId).append("\n")
}
content.append("```")
builder.addField(fieldTitle, content.toString(), false)
}
// set footer
if (showUpdate) {
val lastUpdate = Instant.now().asDiscordTimestamp(DiscordTimestampFormat.RELATIVE_TIME)
builder.footer(getMessage("calendar", "link.footer.update", settings, lastUpdate), null)
} else builder.footer(getMessage("calendar", "link.footer.default", settings), null)
// finish and return
builder.addField(getMessage("calendar", "link.field.timezone", settings), calendar.zoneName, true)
.addField(getMessage("calendar", "link.field.number", settings), "${calendar.calendarNumber}", true)
.url(calendar.link)
.color(discalColor)
.build()
}
}
fun time(guild: Guild, settings: GuildSettings, calNumber: Int): Mono<EmbedCreateSpec> {
return guild.getCalendar(calNumber).map { cal ->

View File

@@ -6,6 +6,7 @@ import org.dreamexposure.discal.core.`object`.GuildSettings
import org.dreamexposure.discal.core.`object`.event.PreEvent
import org.dreamexposure.discal.core.entities.Event
import org.dreamexposure.discal.core.extensions.*
import org.dreamexposure.discal.core.extensions.DiscordTimestampFormat.LONG_DATETIME
import org.dreamexposure.discal.core.utils.getCommonMsg
object EventEmbed : EmbedMaker {
@@ -19,8 +20,15 @@ object EventEmbed : EmbedMaker {
if (event.description.isNotBlank())
builder.description(event.description.toMarkdown().embedDescriptionSafe())
builder.addField(getMessage("event", "full.field.start", settings), event.start.asDiscordTimestamp(), true)
builder.addField(getMessage("event", "full.field.end", settings), event.end.asDiscordTimestamp(), true)
builder.addField(
getMessage("event", "full.field.start", settings),
event.start.asDiscordTimestamp(LONG_DATETIME),
true)
builder.addField(
getMessage("event", "full.field.end", settings),
event.end.asDiscordTimestamp(LONG_DATETIME),
true
)
if (event.location.isNotBlank()) builder.addField(
getMessage("event", "full.field.location", settings),
@@ -44,7 +52,11 @@ object EventEmbed : EmbedMaker {
if (event.name.isNotBlank())
builder.title(event.name.toMarkdown().embedTitleSafe())
builder.addField(getMessage("event", "con.field.start", settings), event.start.asDiscordTimestamp(), true)
builder.addField(
getMessage("event", "con.field.start", settings),
event.start.asDiscordTimestamp(LONG_DATETIME),
true
)
if (event.location.isNotBlank()) builder.addField(
getMessage("event", "con.field.location", settings),

View File

@@ -0,0 +1,11 @@
package org.dreamexposure.discal.core.extensions
enum class DiscordTimestampFormat(val value: String) {
SHORT_TIME("t"),
LONG_TIME("T"),
SHORT_DATE("d"),
LONG_DATE("D"),
SHORT_DATETIME("f"),
LONG_DATETIME("F"),
RELATIVE_TIME("R"),
}

View File

@@ -5,7 +5,7 @@ import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
fun Instant.asDiscordTimestamp(): String = "<t:${this.toEpochMilli() / 1000}:F>"
fun Instant.asDiscordTimestamp(fmt: DiscordTimestampFormat) = "<t:${this.toEpochMilli() / 1000}:${fmt.value}>"
fun Instant.humanReadableFull(timezone: ZoneId, format: TimeFormat): String {
return DateTimeFormatter.ofPattern(format.full).withZone(timezone).format(this)

View File

@@ -1,5 +1,10 @@
package org.dreamexposure.discal.core.extensions
import org.dreamexposure.discal.core.entities.Event
import java.time.LocalDate
import java.time.temporal.TemporalAdjusters
import java.util.stream.Collectors
fun MutableList<String>.asStringList(): String {
val builder = StringBuilder()
@@ -13,3 +18,13 @@ fun MutableList<String>.asStringList(): String {
return builder.toString()
}
fun MutableList<Event>.groupByDate(): Map<LocalDate, List<Event>> {
return this.stream()
.collect(Collectors.groupingBy {
LocalDate.ofInstant(it.start, it.timezone)
.with(TemporalAdjusters.ofDateAdjuster { identity -> identity })
})
}

View File

@@ -2,6 +2,12 @@
"name": "linkcal",
"description": "Provides info and a link to the Guild's Calendar",
"options": [
{
"name": "overview",
"type": 5,
"description": "Whether to display the next 15 upcoming events in the response (default true).",
"required": false
},
{
"name": "calendar",
"type": 4,

View File

@@ -3,7 +3,9 @@ link.field.timezone=Time Zone
link.field.host=Host
link.field.number=Number
link.field.id=ID
link.footer=View the entire calendar with events by clicking the title
link.field.date=%s (Local)
link.footer.default=View the entire calendar with events by clicking the title
link.footer.update=Last Updated \u22C4 %s
wizard.title=Calendar Wizard
wizard.field.name=* Name