mirror of
https://github.com/DreamExposure/DisCal-Discord-Bot.git
synced 2026-04-26 11:28:31 -05:00
Merge branch 'master' of https://github.com/DreamExposure/DisCal-Discord-Bot into feature/rsvp-role
This commit is contained in:
@@ -2,7 +2,8 @@ package org.dreamexposure.discal.client.calendar;
|
||||
|
||||
import com.google.api.services.calendar.model.AclRule;
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import org.dreamexposure.discal.client.message.CalendarMessageFormatter;
|
||||
import org.dreamexposure.discal.client.message.Messages;
|
||||
import org.dreamexposure.discal.core.calendar.CalendarAuth;
|
||||
@@ -13,15 +14,12 @@ import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.object.calendar.PreCalendar;
|
||||
import org.dreamexposure.discal.core.wrapper.google.AclRuleWrapper;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 1/4/2017.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
@@ -129,7 +127,7 @@ public class CalendarCreator {
|
||||
final int credId = new Random().nextInt(CalendarAuth.credentialsCount());
|
||||
|
||||
if (!pre.getEditing()) {
|
||||
return CalendarWrapper.createCalendar(calendar, credId)
|
||||
return CalendarWrapper.createCalendar(calendar, credId, settings.getGuildID())
|
||||
.flatMap(confirmed -> {
|
||||
final CalendarData data = new CalendarData(
|
||||
settings.getGuildID(),
|
||||
|
||||
@@ -47,7 +47,7 @@ public class EventCreator {
|
||||
if (!this.hasPreEvent(settings.getGuildID())) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), 1) //TODO: handle multiple calendars
|
||||
.flatMap(calData -> {
|
||||
final PreEvent event = new PreEvent(settings.getGuildID());
|
||||
final PreEvent event = new PreEvent(settings.getGuildID(), calData.getCalendarNumber());
|
||||
this.events.add(event);
|
||||
|
||||
return CalendarWrapper.getCalendar(calData)
|
||||
@@ -67,7 +67,7 @@ public class EventCreator {
|
||||
if (!this.hasPreEvent(settings.getGuildID())) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), 1) //TODO: handle multiple calendars
|
||||
.flatMap(calData -> {
|
||||
final PreEvent event = new PreEvent(settings.getGuildID());
|
||||
final PreEvent event = new PreEvent(settings.getGuildID(), calData.getCalendarNumber());
|
||||
event.setSummary(summary);
|
||||
|
||||
this.events.add(event);
|
||||
@@ -90,9 +90,8 @@ public class EventCreator {
|
||||
if (!this.hasPreEvent(settings.getGuildID())) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), 1) //TODO: handle multiple calendars
|
||||
.flatMap(calData -> EventWrapper.getEvent(calData, eventId)
|
||||
.flatMap(toCopy -> {
|
||||
final PreEvent event = new PreEvent(settings.getGuildID(), toCopy);
|
||||
|
||||
.flatMap(toCopy -> PreEvent.copy(settings.getGuildID(), toCopy, calData))
|
||||
.flatMap(event -> {
|
||||
this.events.add(event);
|
||||
|
||||
return CalendarWrapper.getCalendar(calData)
|
||||
@@ -112,8 +111,8 @@ public class EventCreator {
|
||||
if (!this.hasPreEvent(settings.getGuildID())) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), 1) //TODO: handle multiple calendars
|
||||
.flatMap(calData -> EventWrapper.getEvent(calData, eventId)
|
||||
.flatMap(toEdit -> {
|
||||
final PreEvent event = new PreEvent(settings.getGuildID(), toEdit);
|
||||
.flatMap(toEdit -> PreEvent.copy(settings.getGuildID(), toEdit, calData))
|
||||
.flatMap(event -> {
|
||||
event.setEditing(true);
|
||||
|
||||
this.events.add(event);
|
||||
|
||||
+105
-410
@@ -15,9 +15,9 @@ import org.dreamexposure.discal.core.utils.ImageUtils;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -35,21 +35,20 @@ import reactor.function.TupleUtils;
|
||||
*/
|
||||
@SuppressWarnings("MagicNumber")
|
||||
public class EventMessageFormatter {
|
||||
@Deprecated
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getEventEmbed(final Event event, final GuildSettings settings) {
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getEventEmbed(Event event, int calNum, GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<EventData> data = DatabaseManager
|
||||
.getEventData(settings.getGuildID(), event.getId())
|
||||
.defaultIfEmpty(new EventData()).cache();
|
||||
final Mono<String> sDate = getHumanReadableDate(event.getStart(), false, settings);
|
||||
final Mono<String> sTime = getHumanReadableTime(event.getStart(), false, settings);
|
||||
final Mono<String> eDate = getHumanReadableDate(event.getEnd(), false, settings);
|
||||
final Mono<String> eTime = getHumanReadableTime(event.getEnd(), false, settings);
|
||||
final Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
Mono<EventData> data = DatabaseManager.getEventData(settings.getGuildID(), event.getId())
|
||||
.defaultIfEmpty(new EventData())
|
||||
.cache();
|
||||
Mono<String> sDate = getHumanReadableDate(event.getStart(), calNum, false, settings);
|
||||
Mono<String> sTime = getHumanReadableTime(event.getStart(), calNum, false, settings);
|
||||
Mono<String> eDate = getHumanReadableDate(event.getEnd(), calNum, false, settings);
|
||||
Mono<String> eTime = getHumanReadableTime(event.getEnd(), calNum, false, settings);
|
||||
Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
final Mono<String> timezone = DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.flatMap(d -> CalendarWrapper.getCalendar(d))
|
||||
Mono<String> timezone = DatabaseManager.getCalendar(settings.getGuildID(), calNum)
|
||||
.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(com.google.api.services.calendar.model.Calendar::getTimeZone)
|
||||
.defaultIfEmpty("Error/Unknown");
|
||||
|
||||
@@ -80,12 +79,20 @@ public class EventMessageFormatter {
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.Description", settings), description, false);
|
||||
}
|
||||
|
||||
|
||||
//Start time
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.StartDate", settings), startDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.StartTime", settings), startTime, true);
|
||||
|
||||
//Timezone so that start/end times are split up cleanly on discord
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.TimeZone", settings), tz, false);
|
||||
|
||||
//End time
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.EndDate", settings), endDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.EndTime", settings), endTime, true);
|
||||
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.TimeZone", settings), tz, true);
|
||||
//Location handling
|
||||
if (event.getLocation() != null && !"".equalsIgnoreCase(event.getLocation())) {
|
||||
if (event.getLocation().length() > 300) {
|
||||
final String location = event.getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
@@ -99,7 +106,7 @@ public class EventMessageFormatter {
|
||||
spec.setFooter(Messages.getMessage("Embed.Event.Info.ID", "%id%", event.getId(), settings), null);
|
||||
|
||||
if (event.getColorId() != null) {
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.valueOf(event.getColorId()));
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.parseInt(event.getColorId()));
|
||||
spec.setColor(ec.asColor());
|
||||
} else {
|
||||
spec.setColor(GlobalConst.discalColor);
|
||||
@@ -107,145 +114,20 @@ public class EventMessageFormatter {
|
||||
}));
|
||||
}
|
||||
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getEventEmbed(final Event event, final int calNum, final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<EventData> data = DatabaseManager
|
||||
.getEventData(settings.getGuildID(), event.getId())
|
||||
.defaultIfEmpty(new EventData()).cache();
|
||||
final Mono<String> sDate = getHumanReadableDate(event.getStart(), calNum, false, settings);
|
||||
final Mono<String> sTime = getHumanReadableTime(event.getStart(), calNum, false, settings);
|
||||
final Mono<String> eDate = getHumanReadableDate(event.getEnd(), calNum, false, settings);
|
||||
final Mono<String> eTime = getHumanReadableTime(event.getEnd(), calNum, false, settings);
|
||||
final Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
final Mono<String> timezone = DatabaseManager.getCalendar(settings.getGuildID(), calNum)
|
||||
.flatMap(d -> CalendarWrapper.getCalendar(d))
|
||||
.map(com.google.api.services.calendar.model.Calendar::getTimeZone)
|
||||
.defaultIfEmpty("Error/Unknown");
|
||||
|
||||
return Mono.zip(guild, data, sDate, sTime, eDate, eTime, img, timezone)
|
||||
.map(TupleUtils.function((g, ed, startDate, startTime, endDate, endTime, hasImg, tz) -> spec -> {
|
||||
if (settings.getBranded())
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite, g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
else
|
||||
spec.setAuthor("DisCal", GlobalConst.discalSite, GlobalConst.iconUrl);
|
||||
|
||||
spec.setTitle(Messages.getMessage("Embed.Event.Info.Title", settings));
|
||||
if (hasImg) {
|
||||
spec.setImage(ed.getImageLink());
|
||||
}
|
||||
if (event.getSummary() != null) {
|
||||
String summary = event.getSummary();
|
||||
if (summary.length() > 250) {
|
||||
summary = summary.substring(0, 250);
|
||||
summary = summary + " (continues on Google Calendar View)";
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.Summary", settings), summary, false);
|
||||
}
|
||||
if (event.getDescription() != null) {
|
||||
String description = event.getDescription();
|
||||
if (description.length() > 500) {
|
||||
description = description.substring(0, 500);
|
||||
description = description + " (continues on Google Calendar View)";
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.Description", settings), description, false);
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.StartDate", settings), startDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.StartTime", settings), startTime, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.EndDate", settings), endDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.EndTime", settings), endTime, true);
|
||||
|
||||
spec.addField(Messages.getMessage("Embed.Event.Info.TimeZone", settings), tz, true);
|
||||
if (event.getLocation() != null && !"".equalsIgnoreCase(event.getLocation())) {
|
||||
if (event.getLocation().length() > 300) {
|
||||
final String location = event.getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), location, false);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), event.getLocation(), false);
|
||||
}
|
||||
}
|
||||
//TODO: Add info on recurrence here.
|
||||
spec.setUrl(event.getHtmlLink());
|
||||
spec.setFooter(Messages.getMessage("Embed.Event.Info.ID", "%id%", event.getId(), settings), null);
|
||||
|
||||
if (event.getColorId() != null) {
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.valueOf(event.getColorId()));
|
||||
spec.setColor(ec.asColor());
|
||||
} else {
|
||||
spec.setColor(GlobalConst.discalColor);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getCondensedEventEmbed(final Event event, final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<EventData> data = DatabaseManager
|
||||
.getEventData(settings.getGuildID(), event.getId())
|
||||
.defaultIfEmpty(new EventData()).cache();
|
||||
final Mono<String> date = getHumanReadableDate(event.getStart(), false, settings);
|
||||
final Mono<String> time = getHumanReadableTime(event.getStart(), false, settings);
|
||||
final Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
|
||||
return Mono.zip(guild, data, time, date, img)
|
||||
.map(TupleUtils.function((g, ed, startDate, startTime, hasImg) -> spec -> {
|
||||
|
||||
if (settings.getBranded())
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite, g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
else
|
||||
spec.setAuthor("DisCal", GlobalConst.discalSite, GlobalConst.iconUrl);
|
||||
|
||||
spec.setTitle(Messages.getMessage("Embed.Event.Condensed.Title", settings));
|
||||
if (hasImg)
|
||||
spec.setThumbnail(ed.getImageLink());
|
||||
|
||||
if (event.getSummary() != null) {
|
||||
String summary = event.getSummary();
|
||||
if (summary.length() > 250) {
|
||||
summary = summary.substring(0, 250);
|
||||
summary = summary + " (continues on Google Calendar View)";
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Condensed.Summary", settings), summary, false);
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Condensed.Date", settings), startDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Condensed.Time", settings), startTime, true);
|
||||
if (event.getLocation() != null && !"".equalsIgnoreCase(event.getLocation())) {
|
||||
if (event.getLocation().length() > 300) {
|
||||
final String location = event.getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), location, false);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), event.getLocation(), false);
|
||||
}
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Condensed.ID", settings), event.getId(), false);
|
||||
spec.setUrl(event.getHtmlLink());
|
||||
|
||||
if (event.getColorId() != null) {
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.valueOf(event.getColorId()));
|
||||
spec.setColor(ec.asColor());
|
||||
} else {
|
||||
spec.setColor(GlobalConst.discalColor);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getCondensedEventEmbed(final Event event, final int calNum, final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<EventData> data = DatabaseManager
|
||||
.getEventData(settings.getGuildID(), event.getId())
|
||||
.defaultIfEmpty(new EventData()).cache();
|
||||
final Mono<String> date = getHumanReadableDate(event.getStart(), calNum, false, settings);
|
||||
final Mono<String> time = getHumanReadableTime(event.getOriginalStartTime(), 1, false, settings);
|
||||
final Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getCondensedEventEmbed(Event event, int calNum,
|
||||
GuildSettings settings) {
|
||||
Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
Mono<EventData> data = DatabaseManager.getEventData(settings.getGuildID(), event.getId())
|
||||
.defaultIfEmpty(new EventData())
|
||||
.cache();
|
||||
Mono<String> date = getHumanReadableDate(event.getStart(), calNum, false, settings);
|
||||
Mono<String> time = getHumanReadableTime(event.getStart(), 1, false, settings);
|
||||
Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
|
||||
return Mono.zip(guild, data, date, time, img)
|
||||
.map(TupleUtils.function((g, ed, startData, startTime, hasImg) -> spec -> {
|
||||
|
||||
if (settings.getBranded())
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite, g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
else
|
||||
@@ -277,7 +159,7 @@ public class EventMessageFormatter {
|
||||
spec.setUrl(event.getHtmlLink());
|
||||
|
||||
if (event.getColorId() != null) {
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.valueOf(event.getColorId()));
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.parseInt(event.getColorId()));
|
||||
spec.setColor(ec.asColor());
|
||||
} else {
|
||||
spec.setColor(GlobalConst.discalColor);
|
||||
@@ -285,14 +167,13 @@ public class EventMessageFormatter {
|
||||
}));
|
||||
}
|
||||
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getPreEventEmbed(final PreEvent event, final int calNum,
|
||||
final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<String> sDate = getHumanReadableDate(event.getStartDateTime(), calNum, false, settings);
|
||||
final Mono<String> sTime = getHumanReadableTime(event.getStartDateTime(), calNum, false, settings);
|
||||
final Mono<String> eDate = getHumanReadableDate(event.getEndDateTime(), calNum, false, settings);
|
||||
final Mono<String> eTime = getHumanReadableTime(event.getEndDateTime(), calNum, false, settings);
|
||||
final Mono<Boolean> img = Mono.justOrEmpty(event.getEventData()).filter(EventData::shouldBeSaved)
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getPreEventEmbed(PreEvent event, GuildSettings settings) {
|
||||
Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
Mono<String> sDate = getHumanReadableDate(event.getStartDateTime(), event.getCalNumber(), false, settings);
|
||||
Mono<String> sTime = getHumanReadableTime(event.getStartDateTime(), event.getCalNumber(), false, settings);
|
||||
Mono<String> eDate = getHumanReadableDate(event.getEndDateTime(), event.getCalNumber(), false, settings);
|
||||
Mono<String> eTime = getHumanReadableTime(event.getEndDateTime(), event.getCalNumber(), false, settings);
|
||||
Mono<Boolean> img = Mono.justOrEmpty(event.getEventData()).filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
|
||||
@@ -335,9 +216,9 @@ public class EventMessageFormatter {
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.StartDate", settings), startDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.StartTime", settings), startTime, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.TimeZone", settings), event.getTimezone(), false);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.EndDate", settings), endDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.EndTime", settings), endTime, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.TimeZone", settings), event.getTimezone(), true);
|
||||
|
||||
if (event.getLocation() != null && !"".equalsIgnoreCase(event.getLocation())) {
|
||||
if (event.getLocation().length() > 300) {
|
||||
@@ -355,120 +236,48 @@ public class EventMessageFormatter {
|
||||
}));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getPreEventEmbed(final PreEvent event,
|
||||
final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<String> sDate = getHumanReadableDate(event.getStartDateTime(), false, settings);
|
||||
final Mono<String> sTime = getHumanReadableTime(event.getStartDateTime(), false, settings);
|
||||
final Mono<String> eDate = getHumanReadableDate(event.getEndDateTime(), false, settings);
|
||||
final Mono<String> eTime = getHumanReadableTime(event.getEndDateTime(), false, settings);
|
||||
final Mono<Boolean> img = Mono.justOrEmpty(event.getEventData()).filter(EventData::shouldBeSaved)
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getEventConfirmationEmbed(EventCreatorResponse ecr, int calNum,
|
||||
GuildSettings settings) {
|
||||
Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
Mono<EventData> data = DatabaseManager.getEventData(settings.getGuildID(), ecr.getEvent().getId())
|
||||
.defaultIfEmpty(new EventData())
|
||||
.cache();
|
||||
Mono<String> date = getHumanReadableDate(ecr.getEvent().getStart(), calNum, false, settings);
|
||||
Mono<String> time = getHumanReadableTime(ecr.getEvent().getStart(), calNum, false, settings);
|
||||
Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
|
||||
return Mono.zip(guild, sDate, sTime, eDate, eTime, img)
|
||||
.map(TupleUtils.function((g, startDate, startTime, endDate, endTime, hasImg) -> spec -> {
|
||||
return Mono.zip(guild, data, date, time, img)
|
||||
.map(TupleUtils.function((g, ed, d, t, hasImg) -> spec -> {
|
||||
if (settings.getBranded())
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite, g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite,
|
||||
g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
else
|
||||
spec.setAuthor("DisCal", GlobalConst.discalSite, GlobalConst.iconUrl);
|
||||
|
||||
if (hasImg)
|
||||
spec.setImage(event.getEventData().getImageLink());
|
||||
if (event.getEditing())
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Id", settings), event.getEventId(), false);
|
||||
spec.setTitle(Messages.getMessage("Embed.Event.Confirm.Title", settings));
|
||||
|
||||
if (event.getSummary() != null) {
|
||||
String summary = event.getSummary();
|
||||
if (summary.length() > 250) {
|
||||
summary = summary.substring(0, 250);
|
||||
summary = summary + " (continues on Google Calendar View)";
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Summary", settings), summary, false);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Summary", settings), "NOT SET", true);
|
||||
}
|
||||
if (event.getDescription() != null) {
|
||||
String description = event.getDescription();
|
||||
if (description.length() > 500) {
|
||||
description = description.substring(0, 500);
|
||||
description = description + " (continues on Google Calendar View)";
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Description", settings), description, false);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Description", settings), "NOT SET", true);
|
||||
}
|
||||
if (event.getRecur()) {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Recurrence", settings), event.getRecurrence().toHumanReadable(), false);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.Recurrence", settings), "N/a", true);
|
||||
}
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.StartDate", settings), startDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.StartTime", settings), startTime, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.EndDate", settings), endDate, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.EndTime", settings), endTime, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Pre.TimeZone", settings), event.getTimezone(), true);
|
||||
if (hasImg) spec.setImage(ed.getImageLink());
|
||||
|
||||
if (event.getLocation() != null && !"".equalsIgnoreCase(event.getLocation())) {
|
||||
if (event.getLocation().length() > 300) {
|
||||
final String location = event.getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.ID", settings), ecr.getEvent().getId(), false);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Condensed.Date", settings), d, true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Condensed.Time", settings), t, true);
|
||||
|
||||
if (ecr.getEvent().getLocation() != null && !"".equalsIgnoreCase(ecr.getEvent().getLocation())) {
|
||||
if (ecr.getEvent().getLocation().length() > 300) {
|
||||
final String location = ecr.getEvent().getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), location, false);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), event.getLocation(), false);
|
||||
}
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), "N/a", true);
|
||||
}
|
||||
|
||||
spec.setFooter(Messages.getMessage("Embed.Event.Pre.Key", settings), null);
|
||||
spec.setColor(event.getColor().asColor());
|
||||
}));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getEventConfirmationEmbed(final EventCreatorResponse ecr,
|
||||
final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<EventData> data = DatabaseManager
|
||||
.getEventData(settings.getGuildID(), ecr.getEvent().getId())
|
||||
.defaultIfEmpty(new EventData()).cache();
|
||||
final Mono<String> date = getHumanReadableDate(ecr.getEvent().getStart(), false, settings);
|
||||
final Mono<String> time = getHumanReadableTime(ecr.getEvent().getStart(), false, settings);
|
||||
final Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
|
||||
return Mono.zip(guild, data, date, time, img)
|
||||
.map(TupleUtils.function((g, ed, d, t, hasImg) -> spec -> {
|
||||
if (settings.getBranded())
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite,
|
||||
g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
else
|
||||
spec.setAuthor("DisCal", GlobalConst.discalSite, GlobalConst.iconUrl);
|
||||
|
||||
spec.setTitle(Messages.getMessage("Embed.Event.Confirm.Title", settings));
|
||||
|
||||
if (hasImg)
|
||||
spec.setImage(ed.getImageLink());
|
||||
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.ID", settings),
|
||||
ecr.getEvent().getId(), false);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Date", settings),
|
||||
d, false);
|
||||
if (ecr.getEvent().getLocation() != null && !"".equalsIgnoreCase(ecr.getEvent().getLocation())) {
|
||||
if (ecr.getEvent().getLocation().length() > 300) {
|
||||
final String location = ecr.getEvent().getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), location, true);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), ecr.getEvent().getLocation(), true);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings),
|
||||
ecr.getEvent().getLocation(), false);
|
||||
}
|
||||
}
|
||||
spec.setFooter(Messages.getMessage("Embed.Event.Confirm.Footer", settings), null);
|
||||
spec.setUrl(ecr.getEvent().getHtmlLink());
|
||||
|
||||
if (ecr.getEvent().getColorId() != null) {
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.valueOf(ecr.getEvent().getColorId()));
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.parseInt(ecr.getEvent().getColorId()));
|
||||
spec.setColor(ec.asColor());
|
||||
} else {
|
||||
spec.setColor(GlobalConst.discalColor);
|
||||
@@ -476,147 +285,8 @@ public class EventMessageFormatter {
|
||||
}));
|
||||
}
|
||||
|
||||
public static Mono<Consumer<EmbedCreateSpec>> getEventConfirmationEmbed(final EventCreatorResponse ecr,
|
||||
final int calNum,
|
||||
final GuildSettings settings) {
|
||||
final Mono<Guild> guild = DisCalClient.getClient().getGuildById(settings.getGuildID());
|
||||
final Mono<EventData> data = DatabaseManager
|
||||
.getEventData(settings.getGuildID(), ecr.getEvent().getId())
|
||||
.defaultIfEmpty(new EventData()).cache();
|
||||
final Mono<String> date = getHumanReadableDate(ecr.getEvent().getStart(), calNum, false, settings);
|
||||
final Mono<String> time = getHumanReadableTime(ecr.getEvent().getStart(), calNum, false, settings);
|
||||
final Mono<Boolean> img = data.filter(EventData::shouldBeSaved)
|
||||
.flatMap(d -> ImageUtils.validate(d.getImageLink(), settings.getPatronGuild()))
|
||||
.defaultIfEmpty(false);
|
||||
|
||||
return Mono.zip(guild, data, date, time, img)
|
||||
.map(TupleUtils.function((g, ed, d, t, hasImg) -> spec -> {
|
||||
if (settings.getBranded())
|
||||
spec.setAuthor(g.getName(), GlobalConst.discalSite,
|
||||
g.getIconUrl(Image.Format.PNG).orElse(GlobalConst.iconUrl));
|
||||
else
|
||||
spec.setAuthor("DisCal", GlobalConst.discalSite, GlobalConst.iconUrl);
|
||||
|
||||
spec.setTitle(Messages.getMessage("Embed.Event.Confirm.Title", settings));
|
||||
|
||||
if (hasImg) {
|
||||
spec.setImage(ed.getImageLink());
|
||||
}
|
||||
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.ID", settings),
|
||||
ecr.getEvent().getId(), false);
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Date", settings),
|
||||
d, false);
|
||||
if (ecr.getEvent().getLocation() != null && !"".equalsIgnoreCase(ecr.getEvent().getLocation())) {
|
||||
if (ecr.getEvent().getLocation().length() > 300) {
|
||||
final String location = ecr.getEvent().getLocation().substring(0, 300).trim() + "... (cont. on Google Cal)";
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), location, true);
|
||||
} else {
|
||||
spec.addField(Messages.getMessage("Embed.Event.Confirm.Location", settings), ecr.getEvent().getLocation(), true);
|
||||
}
|
||||
}
|
||||
spec.setFooter(Messages.getMessage("Embed.Event.Confirm.Footer", settings), null);
|
||||
spec.setUrl(ecr.getEvent().getHtmlLink());
|
||||
|
||||
if (ecr.getEvent().getColorId() != null) {
|
||||
final EventColor ec = EventColor.Companion.fromId(Integer.valueOf(ecr.getEvent().getColorId()));
|
||||
spec.setColor(ec.asColor());
|
||||
} else {
|
||||
spec.setColor(GlobalConst.discalColor);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Mono<String> getHumanReadableDate(@Nullable final EventDateTime eventDateTime,
|
||||
final boolean preEvent, final GuildSettings settings) {
|
||||
return Mono.justOrEmpty(eventDateTime).flatMap(dateTime -> {
|
||||
if (!preEvent) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.flatMap(data -> CalendarWrapper.getCalendar(data))
|
||||
.map(com.google.api.services.calendar.model.Calendar::getTimeZone);
|
||||
} else {
|
||||
return Mono.just("UTC");
|
||||
}
|
||||
}
|
||||
).map(ZoneId::of)
|
||||
.map(tz -> {
|
||||
final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd");
|
||||
if (eventDateTime.getDateTime() != null) {
|
||||
final long dateTime = eventDateTime.getDateTime().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
|
||||
return format.format(ldt);
|
||||
} else {
|
||||
final long dateTime = eventDateTime.getDate().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
return format.format(ldt);
|
||||
}
|
||||
}).defaultIfEmpty("NOT SET");
|
||||
}
|
||||
|
||||
public static Mono<String> getHumanReadableDate(@Nullable final EventDateTime eventDateTime,
|
||||
final int calNum, final boolean preEvent,
|
||||
final GuildSettings settings) {
|
||||
return Mono.justOrEmpty(eventDateTime).flatMap(dateTime -> {
|
||||
if (!preEvent) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), calNum)
|
||||
.flatMap(data -> CalendarWrapper.getCalendar(data))
|
||||
.map(com.google.api.services.calendar.model.Calendar::getTimeZone);
|
||||
} else {
|
||||
return Mono.just("UTC");
|
||||
}
|
||||
}
|
||||
).map(ZoneId::of)
|
||||
.map(tz -> {
|
||||
final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd");
|
||||
if (eventDateTime.getDateTime() != null) {
|
||||
final long dateTime = eventDateTime.getDateTime().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
|
||||
return format.format(ldt);
|
||||
} else {
|
||||
final long dateTime = eventDateTime.getDate().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
return format.format(ldt);
|
||||
}
|
||||
}).defaultIfEmpty("NOT SET");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Mono<String> getHumanReadableTime(@Nullable final EventDateTime eventDateTime,
|
||||
final boolean preEvent, final GuildSettings settings) {
|
||||
return Mono.justOrEmpty(eventDateTime).flatMap(dateTime -> {
|
||||
if (!preEvent) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(com.google.api.services.calendar.model.Calendar::getTimeZone);
|
||||
} else {
|
||||
return Mono.just("UTC");
|
||||
}
|
||||
}
|
||||
).map(ZoneId::of)
|
||||
.map(tz -> {
|
||||
DateTimeFormatter format;
|
||||
if (settings.getTwelveHour()) format = DateTimeFormatter.ofPattern("hh:mm:ss a");
|
||||
else format = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
|
||||
if (eventDateTime.getDateTime() != null) {
|
||||
final long dateTime = eventDateTime.getDateTime().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
|
||||
return format.format(ldt);
|
||||
} else {
|
||||
final long dateTime = eventDateTime.getDate().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
return format.format(ldt);
|
||||
}
|
||||
}).defaultIfEmpty("NOT SET");
|
||||
}
|
||||
|
||||
public static Mono<String> getHumanReadableTime(@Nullable final EventDateTime eventDateTime,
|
||||
final int calNum, final boolean preEvent,
|
||||
final GuildSettings settings) {
|
||||
public static Mono<String> getHumanReadableDate(@Nullable EventDateTime eventDateTime, int calNum,
|
||||
boolean preEvent, GuildSettings settings) {
|
||||
return Mono.justOrEmpty(eventDateTime).flatMap(dateTime -> {
|
||||
if (!preEvent) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), calNum)
|
||||
@@ -626,22 +296,47 @@ public class EventMessageFormatter {
|
||||
return Mono.just("UTC");
|
||||
}
|
||||
}
|
||||
).map(ZoneId::of)
|
||||
.map(tz -> {
|
||||
DateTimeFormatter format;
|
||||
if (settings.getTwelveHour()) format = DateTimeFormatter.ofPattern("hh:mm:ss a");
|
||||
else format = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
).map(ZoneId::of).map(tz -> {
|
||||
final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd")
|
||||
.withZone(tz);
|
||||
|
||||
if (eventDateTime.getDateTime() != null) {
|
||||
final long dateTime = eventDateTime.getDateTime().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
if (eventDateTime.getDateTime() != null) { //Date with time
|
||||
return format.format(Instant.ofEpochMilli(eventDateTime.getDateTime().getValue()));
|
||||
} else { //Date only
|
||||
Instant date = Instant.ofEpochMilli(eventDateTime.getDate().getValue())
|
||||
.plus(1, ChronoUnit.DAYS);
|
||||
|
||||
return format.format(ldt);
|
||||
return format.format(date);
|
||||
}
|
||||
}).defaultIfEmpty("NOT SET");
|
||||
}
|
||||
|
||||
public static Mono<String> getHumanReadableTime(@Nullable EventDateTime eventDateTime, int calNum,
|
||||
boolean preEvent, GuildSettings settings) {
|
||||
return Mono.justOrEmpty(eventDateTime).flatMap(dateTime -> {
|
||||
if (!preEvent) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), calNum)
|
||||
.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(com.google.api.services.calendar.model.Calendar::getTimeZone);
|
||||
} else {
|
||||
final long dateTime = eventDateTime.getDate().getValue();
|
||||
final LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTime), tz);
|
||||
return format.format(ldt);
|
||||
return Mono.just("UTC");
|
||||
}
|
||||
}).defaultIfEmpty("NOT SET");
|
||||
}
|
||||
).map(ZoneId::of).map(tz -> {
|
||||
DateTimeFormatter format;
|
||||
if (settings.getTwelveHour()) format = DateTimeFormatter.ofPattern("hh:mm:ss a").withZone(tz);
|
||||
else format = DateTimeFormatter.ofPattern("HH:mm:ss").withZone(tz);
|
||||
|
||||
if (eventDateTime.getDateTime() != null) { //Date with time
|
||||
return format.format(Instant.ofEpochMilli(eventDateTime.getDateTime().getValue()));
|
||||
} else { //Just date
|
||||
// I guess just return 0 essentially?
|
||||
Instant date = Instant.ofEpochMilli(eventDateTime.getDate().getValue())
|
||||
.plus(1, ChronoUnit.DAYS);
|
||||
|
||||
//Go to beginning of day
|
||||
return format.format(date.atZone(tz).truncatedTo(ChronoUnit.DAYS).toLocalDate().atStartOfDay());
|
||||
}
|
||||
}).defaultIfEmpty("NOT SET");
|
||||
}
|
||||
}
|
||||
|
||||
+57
-58
@@ -6,7 +6,6 @@ import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.object.command.CommandInfo;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
import org.dreamexposure.discal.core.utils.PermissionChecker;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
|
||||
@@ -71,64 +70,64 @@ public class AddCalendarCommand implements Command {
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> issueCommand(final String[] args, final MessageCreateEvent event, final GuildSettings settings) {
|
||||
return Mono.just(settings)
|
||||
.filter(s -> s.getDevGuild() || s.getPatronGuild())
|
||||
.flatMap(s -> PermissionChecker.hasManageServerRole(event)
|
||||
.filter(identity -> identity)
|
||||
.flatMap(ignore -> {
|
||||
if (args.length == 0) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.hasElement()
|
||||
.flatMap(hasCal -> {
|
||||
if (hasCal) {
|
||||
return Messages.sendMessage(
|
||||
Messages.getMessage("Creator.Calendar.HasCalendar", settings), event);
|
||||
} else {
|
||||
return GoogleExternalAuth.getAuth().requestCode(event, settings)
|
||||
.then(Messages.sendMessage(
|
||||
Messages.getMessage("AddCalendar.Start", settings), event));
|
||||
}
|
||||
});
|
||||
} else if (args.length == 1) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID()).flatMap(data -> {
|
||||
if ("primary".equalsIgnoreCase(data.getCalendarAddress())) {
|
||||
return Messages.sendMessage(Messages.getMessage("Creator.Calendar.HasCalendar", settings), event);
|
||||
} else if ("N/a".equalsIgnoreCase(data.getEncryptedAccessToken())
|
||||
&& "N/a".equalsIgnoreCase(data.getEncryptedRefreshToken())) {
|
||||
return Messages.sendMessage(Messages.getMessage("AddCalendar.Select.NotAuth", settings), event);
|
||||
} else {
|
||||
return CalendarWrapper.getUsersExternalCalendars(data)
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.any(c -> !c.isDeleted() && c.getId().equals(args[0]))
|
||||
.flatMap(valid -> {
|
||||
if (valid) {
|
||||
final CalendarData newData = new CalendarData(
|
||||
data.getGuildId(), 1, args[0], args[0], true, 0,
|
||||
data.getPrivateKey(), data.getEncryptedAccessToken(),
|
||||
data.getEncryptedRefreshToken());
|
||||
if (!(settings.getDevGuild() || settings.getPatronGuild())) {
|
||||
return Messages.sendMessage(Messages.getMessage("Notification.Patron", settings), event).then();
|
||||
}
|
||||
|
||||
//combine db calls and message send to be executed together async
|
||||
final Mono<Boolean> calInsert = DatabaseManager.updateCalendar(newData);
|
||||
final Mono<Message> sendMsg = Messages.sendMessage(
|
||||
Messages.getMessage("AddCalendar.Select.Success", settings), event);
|
||||
return PermissionChecker.hasManageServerRole(event).flatMap(hasManageRole -> {
|
||||
if (!hasManageRole) {
|
||||
return Messages.sendMessage(Messages.getMessage("Notification.Perm.MANAGE_SERVER", settings), event);
|
||||
}
|
||||
|
||||
return Mono.when(calInsert, sendMsg)
|
||||
.thenReturn(GlobalConst.NOT_EMPTY);
|
||||
} else {
|
||||
return Messages.sendMessage(Messages
|
||||
.getMessage("AddCalendar.Select.Failure.Invalid", settings), event);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//Invalid argument count...
|
||||
return Messages.sendMessage(Messages.getMessage("AddCalendar.Specify", settings), event);
|
||||
}
|
||||
})
|
||||
.switchIfEmpty(Messages.sendMessage(Messages.getMessage("Notification.Perm.MANAGE_SERVER", settings), event))
|
||||
)
|
||||
.switchIfEmpty(Messages.sendMessage(Messages.getMessage("Notification.Patron", settings), event))
|
||||
.then();
|
||||
if (args.length == 0) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.hasElement()
|
||||
.flatMap(hasCal -> {
|
||||
if (hasCal) {
|
||||
return Messages.sendMessage(
|
||||
Messages.getMessage("Creator.Calendar.HasCalendar", settings), event);
|
||||
} else {
|
||||
return GoogleExternalAuth.getAuth().requestCode(event, settings)
|
||||
.then(Messages.sendMessage(
|
||||
Messages.getMessage("AddCalendar.Start", settings), event));
|
||||
}
|
||||
});
|
||||
} else if (args.length == 1) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.flatMap(data -> {
|
||||
if (!"primary".equalsIgnoreCase(data.getCalendarAddress())) {
|
||||
return Messages.sendMessage(Messages.getMessage("Creator.Calendar.HasCalendar", settings), event);
|
||||
} else if ("N/a".equalsIgnoreCase(data.getEncryptedAccessToken())
|
||||
&& "N/a".equalsIgnoreCase(data.getEncryptedRefreshToken())) {
|
||||
return Messages.sendMessage(Messages.getMessage("AddCalendar.Select.NotAuth", settings), event);
|
||||
} else {
|
||||
return CalendarWrapper.getUsersExternalCalendars(data)
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.any(c -> !c.isDeleted() && c.getId().equals(args[0]))
|
||||
.flatMap(valid -> {
|
||||
if (valid) {
|
||||
final CalendarData newData = new CalendarData(
|
||||
data.getGuildId(), 1, args[0], args[0], true, 0,
|
||||
data.getPrivateKey(), data.getEncryptedAccessToken(),
|
||||
data.getEncryptedRefreshToken());
|
||||
|
||||
//combine db calls and message send to be executed together async
|
||||
final Mono<Boolean> calInsert = DatabaseManager.updateCalendar(newData);
|
||||
final Mono<Message> sendMsg = Messages.sendMessage(
|
||||
Messages.getMessage("AddCalendar.Select.Success", settings), event);
|
||||
|
||||
return Mono.when(calInsert, sendMsg);
|
||||
} else {
|
||||
return Messages.sendMessage(Messages
|
||||
.getMessage("AddCalendar.Select.Failure.Invalid", settings), event);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//Invalid argument count...
|
||||
return Messages.sendMessage(Messages.getMessage("AddCalendar.Specify", settings), event);
|
||||
}
|
||||
}).then();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -233,7 +233,7 @@ public class EventCommand implements Command {
|
||||
final Mono<Void> deleteCreatorMessage = Messages.deleteMessage(pre.getCreatorMessage());
|
||||
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(), settings))
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, settings))
|
||||
.flatMap(em -> Messages.sendMessage(Messages.getMessage("Creator.Event.AlreadyInit", settings), em, event))
|
||||
.doOnNext(pre::setCreatorMessage);
|
||||
} else if (!"primary".equalsIgnoreCase(calendarData.getCalendarAddress())) {
|
||||
@@ -257,7 +257,7 @@ public class EventCommand implements Command {
|
||||
final Mono<Void> deleteCreatorMessage = Messages.deleteMessage(pre.getCreatorMessage());
|
||||
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(), settings))
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, settings))
|
||||
.flatMap(em -> Messages.sendMessage(Messages.getMessage("Creator.Event.AlreadyInit", settings), em, event))
|
||||
.doOnNext(pre::setCreatorMessage);
|
||||
} else if (!"primary".equalsIgnoreCase(calendarData.getCalendarAddress())) {
|
||||
@@ -291,7 +291,7 @@ public class EventCommand implements Command {
|
||||
final Mono<Void> deleteCreatorMessage = Messages.deleteMessage(pre.getCreatorMessage());
|
||||
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(), settings))
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, settings))
|
||||
.flatMap(em -> Messages.sendMessage(Messages.getMessage("Creator.Event.AlreadyInit", settings), em, event))
|
||||
.doOnNext(pre::setCreatorMessage);
|
||||
} else if ("primary".equalsIgnoreCase(calendarData.getCalendarAddress())) {
|
||||
@@ -345,7 +345,7 @@ public class EventCommand implements Command {
|
||||
final Mono<Void> deleteCreatorMessage = Messages.deleteMessage(pre.getCreatorMessage());
|
||||
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(), settings))
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, settings))
|
||||
.flatMap(em -> Messages.sendMessage(Messages
|
||||
.getMessage("Creator.Event.Delete.Failure.Creator", settings), em, event))
|
||||
.doOnNext(pre::setCreatorMessage);
|
||||
@@ -379,7 +379,7 @@ public class EventCommand implements Command {
|
||||
final Mono<Void> deleteCreatorMessage = Messages.deleteMessage(pre.getCreatorMessage());
|
||||
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(), settings))
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, settings))
|
||||
.flatMap(em -> Messages.sendMessage(Messages.getMessage("Event.View.Creator.Confirm", settings), em, event))
|
||||
.doOnNext(pre::setCreatorMessage);
|
||||
} else if ("primary".equalsIgnoreCase(calendarData.getCalendarAddress())) {
|
||||
@@ -421,7 +421,7 @@ public class EventCommand implements Command {
|
||||
.flatMap(em -> Messages.sendMessage(msg, em, event));
|
||||
} else {
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(),
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre,
|
||||
settings))
|
||||
.flatMap(em -> Messages.sendMessage(
|
||||
Messages.getMessage("Creator.Event.Confirm.Failure", settings), em, event))
|
||||
@@ -431,7 +431,7 @@ public class EventCommand implements Command {
|
||||
} else {
|
||||
//Some values are unset, tell user.
|
||||
return Mono.when(deleteUserMessage, deleteCreatorMessage)
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, calendarData.getCalendarNumber(), settings))
|
||||
.then(EventMessageFormatter.getPreEventEmbed(pre, settings))
|
||||
.flatMap(em -> Messages.sendMessage(Messages.getMessage("Creator.Event.NoRequired", settings), em, event))
|
||||
.doOnNext(pre::setCreatorMessage);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package org.dreamexposure.discal.core.database;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import io.r2dbc.pool.ConnectionPool;
|
||||
import io.r2dbc.pool.ConnectionPoolConfiguration;
|
||||
import io.r2dbc.spi.*;
|
||||
import org.dreamexposure.discal.core.enums.announcement.AnnouncementModifier;
|
||||
import org.dreamexposure.discal.core.enums.announcement.AnnouncementType;
|
||||
import org.dreamexposure.discal.core.enums.event.EventColor;
|
||||
@@ -13,6 +17,8 @@ import org.dreamexposure.discal.core.object.event.EventData;
|
||||
import org.dreamexposure.discal.core.object.event.RsvpData;
|
||||
import org.dreamexposure.discal.core.object.web.UserAPIAccount;
|
||||
import org.dreamexposure.novautils.database.DatabaseSettings;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.retry.Retry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -21,26 +27,7 @@ import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import io.r2dbc.pool.ConnectionPool;
|
||||
import io.r2dbc.pool.ConnectionPoolConfiguration;
|
||||
import io.r2dbc.spi.Connection;
|
||||
import io.r2dbc.spi.ConnectionFactories;
|
||||
import io.r2dbc.spi.ConnectionFactory;
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import io.r2dbc.spi.Result;
|
||||
import io.r2dbc.spi.ValidationDepth;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.retry.Retry;
|
||||
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.DATABASE;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.DRIVER;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.HOST;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.PASSWORD;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.PORT;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.PROTOCOL;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.SSL;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.USER;
|
||||
import static io.r2dbc.spi.ConnectionFactoryOptions.*;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 11/10/17.
|
||||
@@ -241,7 +228,7 @@ public class DatabaseManager {
|
||||
final String update = "UPDATE " + table
|
||||
+ " SET CALENDAR_NUMBER = ?, CALENDAR_ID = ?,"
|
||||
+ " CALENDAR_ADDRESS = ?, EXTERNAL = ?, CREDENTIAL_ID = ?,"
|
||||
+ " PRIVATE_KEY = ?, ACCESS_TOKEN = ?, REFRESH TOKEN = ?"
|
||||
+ " PRIVATE_KEY = ?, ACCESS_TOKEN = ?, REFRESH_TOKEN = ?"
|
||||
+ " WHERE GUILD_ID = ?";
|
||||
|
||||
return connect(master, c -> Mono.from(c.createStatement(update)
|
||||
@@ -261,7 +248,8 @@ public class DatabaseManager {
|
||||
} else {
|
||||
final String insertCommand = "INSERT INTO " + table
|
||||
+ "(GUILD_ID, CALENDAR_NUMBER, CALENDAR_ID, " +
|
||||
"CALENDAR_ADDRESS, EXTERNAL, CREDENTIAL_ID)" + " VALUES (?, ?, ?, ?, ?, ?)";
|
||||
"CALENDAR_ADDRESS, EXTERNAL, CREDENTIAL_ID, " +
|
||||
"PRIVATE_KEY, ACCESS_TOKEN, REFRESH_TOKEN)" + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
return connect(master, c -> Mono.from(c.createStatement(insertCommand)
|
||||
.bind(0, calData.getGuildId().asString())
|
||||
@@ -270,6 +258,9 @@ public class DatabaseManager {
|
||||
.bind(3, calData.getCalendarAddress())
|
||||
.bind(4, calData.getExternal())
|
||||
.bind(5, calData.getCredentialId())
|
||||
.bind(6, calData.getPrivateKey())
|
||||
.bind(7, calData.getEncryptedAccessToken())
|
||||
.bind(8, calData.getEncryptedRefreshToken())
|
||||
.execute())
|
||||
).flatMap(res -> Mono.from(res.getRowsUpdated()))
|
||||
.hasElement()
|
||||
@@ -1061,12 +1052,11 @@ public class DatabaseManager {
|
||||
return connect(master, c -> {
|
||||
final String announcementTableName = String.format("%sannouncements", settings.getPrefix());
|
||||
final String query = "DELETE FROM " + announcementTableName + " WHERE EVENT_ID = ? AND " +
|
||||
"GUILD_ID = ? AND ANNOUNCEMENT_TYPE = ?";
|
||||
"GUILD_ID = ?";
|
||||
|
||||
return Mono.from(c.createStatement(query)
|
||||
.bind(0, eventId)
|
||||
.bind(1, guildId.asString())
|
||||
.bind(2, AnnouncementType.SPECIFIC.name())
|
||||
.execute());
|
||||
}).flatMapMany(Result::getRowsUpdated)
|
||||
.then(Mono.just(true))
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package org.dreamexposure.discal.core.utils;
|
||||
|
||||
import com.google.api.services.calendar.model.Event;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.enums.event.EventColor;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.event.EventData;
|
||||
import org.dreamexposure.discal.core.object.event.PreEvent;
|
||||
import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
@@ -18,27 +16,20 @@ import reactor.core.publisher.Mono;
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
public class EventUtils {
|
||||
|
||||
@Deprecated
|
||||
public static Mono<Boolean> deleteEvent(final GuildSettings settings, final String eventId) {
|
||||
return DatabaseManager.getMainCalendar(settings.getGuildID())
|
||||
.flatMap(data ->
|
||||
EventWrapper.deleteEvent(data, eventId)
|
||||
.then(Mono.when(
|
||||
DatabaseManager.deleteAnnouncementsForEvent(settings.getGuildID(), eventId),
|
||||
DatabaseManager.deleteEventData(eventId))
|
||||
).thenReturn(true)
|
||||
).defaultIfEmpty(false);
|
||||
}
|
||||
|
||||
public static Mono<Boolean> deleteEvent(final GuildSettings settings, final int calNumber, final String eventId) {
|
||||
return DatabaseManager.getCalendar(settings.getGuildID(), calNumber)
|
||||
.flatMap(data ->
|
||||
EventWrapper.deleteEvent(data, eventId)
|
||||
.then(Mono.when(
|
||||
DatabaseManager.deleteAnnouncementsForEvent(settings.getGuildID(), eventId),
|
||||
DatabaseManager.deleteEventData(eventId))
|
||||
).thenReturn(true)
|
||||
.flatMap(success -> {
|
||||
if (success) {
|
||||
return Mono.when(
|
||||
DatabaseManager.deleteAnnouncementsForEvent(settings.getGuildID(), eventId),
|
||||
DatabaseManager.deleteEventData(eventId)
|
||||
).thenReturn(true);
|
||||
} else {
|
||||
return Mono.just(false);
|
||||
}
|
||||
})
|
||||
).defaultIfEmpty(false);
|
||||
}
|
||||
|
||||
@@ -59,9 +50,9 @@ public class EventUtils {
|
||||
).switchIfEmpty(Mono.just(false));
|
||||
}
|
||||
|
||||
public static Mono<PreEvent> copyEvent(final Snowflake guildId, final Event event) {
|
||||
public static Mono<PreEvent> copyEvent(final Snowflake guildId, final Event event, int calNum) {
|
||||
return DatabaseManager.getEventData(guildId, event.getId())
|
||||
.flatMap(data -> Mono.just(new PreEvent(guildId))
|
||||
.flatMap(data -> Mono.just(new PreEvent(guildId, calNum))
|
||||
.doOnNext(p -> p.setEventData(data))
|
||||
.doOnNext(p -> p.setSummary(event.getSummary()))
|
||||
.doOnNext(p -> p.setDescription(event.getDescription()))
|
||||
@@ -72,7 +63,7 @@ public class EventUtils {
|
||||
else
|
||||
p.setColor(EventColor.NONE);
|
||||
})
|
||||
).switchIfEmpty(Mono.just(new PreEvent(guildId))
|
||||
).switchIfEmpty(Mono.just(new PreEvent(guildId, calNum))
|
||||
.doOnNext(p -> p.setEventData(new EventData()))
|
||||
.doOnNext(p -> p.setSummary(event.getSummary()))
|
||||
.doOnNext(p -> p.setDescription(event.getDescription()))
|
||||
|
||||
@@ -5,54 +5,85 @@ import com.google.api.services.calendar.model.Event;
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.enums.event.EventColor;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.event.EventData;
|
||||
import org.dreamexposure.discal.core.object.event.Recurrence;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class JsonUtils {
|
||||
public static String getJsonResponseMessage(final String msg) {
|
||||
return "{\"message\": \"" + msg + "\"}";
|
||||
}
|
||||
|
||||
//TODO: rewrite to non-blocking
|
||||
public static JSONObject convertEventToJson(final Event event, final GuildSettings settings) {
|
||||
final JSONObject json = new JSONObject();
|
||||
public static Mono<JSONObject> convertEventToJson(Event event, ZoneId tz, GuildSettings settings) {
|
||||
return Mono.just(new JSONObject()).flatMap(json -> {
|
||||
json.put("event_id", event.getId());
|
||||
if (event.getStart().getDateTime() != null)
|
||||
json.put("epoch_start", event.getStart().getDateTime().getValue());
|
||||
else {
|
||||
Long start = Instant.ofEpochMilli(event.getStart().getDate().getValue())
|
||||
.plus(1, ChronoUnit.DAYS)
|
||||
.atZone(tz)
|
||||
.truncatedTo(ChronoUnit.DAYS)
|
||||
.toLocalDate()
|
||||
.atStartOfDay()
|
||||
.atZone(tz)
|
||||
.toInstant()
|
||||
.toEpochMilli();
|
||||
|
||||
json.put("event_id", event.getId());
|
||||
json.put("epoch_start", event.getStart().getDateTime().getValue());
|
||||
json.put("epoch_end", event.getEnd().getDateTime().getValue());
|
||||
json.put("epoch_start", start);
|
||||
}
|
||||
|
||||
//These 3 are optional values
|
||||
if (event.getSummary() != null)
|
||||
json.put("summary", event.getSummary());
|
||||
if (event.getDescription() != null)
|
||||
json.put("description", event.getDescription());
|
||||
if (event.getLocation() != null)
|
||||
json.put("location", event.getLocation());
|
||||
if (event.getEnd().getDateTime() != null)
|
||||
json.put("epoch_end", event.getEnd().getDateTime().getValue());
|
||||
else {
|
||||
Long end = Instant.ofEpochMilli(event.getEnd().getDate().getValue())
|
||||
.plus(1, ChronoUnit.DAYS)
|
||||
.atZone(tz)
|
||||
.truncatedTo(ChronoUnit.DAYS)
|
||||
.toLocalDate()
|
||||
.atStartOfDay()
|
||||
.atZone(tz)
|
||||
.toInstant()
|
||||
.toEpochMilli();
|
||||
|
||||
json.put("is_parent", !(event.getId().contains("_")));
|
||||
json.put("epoch_end", end);
|
||||
}
|
||||
|
||||
json.put("color", EventColor.Companion.fromNameOrHexOrId(event.getColorId()).name());
|
||||
//These 3 are optional values
|
||||
if (event.getSummary() != null)
|
||||
json.put("summary", event.getSummary());
|
||||
if (event.getDescription() != null)
|
||||
json.put("description", event.getDescription());
|
||||
if (event.getLocation() != null)
|
||||
json.put("location", event.getLocation());
|
||||
|
||||
if (event.getRecurrence() != null && !event.getRecurrence().isEmpty()) {
|
||||
json.put("recur", true);
|
||||
final Recurrence r = Recurrence.Companion.fromRRule(event.getRecurrence().get(0));
|
||||
json.put("is_parent", !(event.getId().contains("_")));
|
||||
|
||||
final JSONObject recurrence = new JSONObject();
|
||||
recurrence.put("frequency", r.getFrequency().name());
|
||||
recurrence.put("count", r.getCount());
|
||||
recurrence.put("interval", r.getInterval());
|
||||
if (event.getColorId() != null)
|
||||
json.put("color", EventColor.Companion.fromNameOrHexOrId(event.getColorId()).name());
|
||||
else
|
||||
json.put("color", EventColor.NONE.name());
|
||||
|
||||
json.put("recurrence", recurrence); //Optional
|
||||
} else
|
||||
json.put("recur", false);
|
||||
if (event.getRecurrence() != null && !event.getRecurrence().isEmpty()) {
|
||||
json.put("recur", true);
|
||||
final Recurrence r = Recurrence.Companion.fromRRule(event.getRecurrence().get(0));
|
||||
|
||||
final EventData ed = DatabaseManager.getEventData(settings.getGuildID(), event.getId()).block();
|
||||
json.put("recurrence", JsonUtil.INSTANCE.encodeToJSON(Recurrence.class, r)); //Optional
|
||||
json.put("rrule", r.toRRule());
|
||||
} else
|
||||
json.put("recur", false);
|
||||
|
||||
//Event image is also optional
|
||||
if (ed != null && ed.getImageLink() != null)
|
||||
json.put("image", ed.getImageLink());
|
||||
|
||||
return json;
|
||||
return DatabaseManager.getEventData(settings.getGuildID(), event.getId())
|
||||
.filter(ed -> !ed.getImageLink().isEmpty())
|
||||
.doOnNext(ed -> json.put("image", ed.getImageLink()))
|
||||
.thenReturn(json)
|
||||
.defaultIfEmpty(json);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.dreamexposure.discal.core.utils;
|
||||
|
||||
import com.google.api.client.util.DateTime;
|
||||
import com.google.api.services.calendar.model.Event;
|
||||
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
@@ -10,6 +11,9 @@ import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@@ -67,7 +71,12 @@ public class TimeUtils {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss");
|
||||
sdf.setTimeZone(timezone);
|
||||
final Date endDate = sdf.parse(endRaw);
|
||||
final Date startDate = new Date(event.getStartDateTime().getDateTime().getValue());
|
||||
|
||||
final Date startDate;
|
||||
if (event.getStartDateTime().getDateTime() != null)
|
||||
startDate = new Date(event.getStartDateTime().getDateTime().getValue());
|
||||
else
|
||||
startDate = new Date(event.getStartDateTime().getDate().getValue());
|
||||
|
||||
return endDate.before(startDate);
|
||||
} catch (final ParseException e) {
|
||||
@@ -83,7 +92,13 @@ public class TimeUtils {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss");
|
||||
sdf.setTimeZone(timezone);
|
||||
final Date startDate = sdf.parse(startRaw);
|
||||
final Date endDate = new Date(event.getEndDateTime().getDateTime().getValue());
|
||||
|
||||
Date endDate;
|
||||
if (event.getEndDateTime().getDateTime() != null)
|
||||
endDate = new Date(event.getEndDateTime().getDateTime().getValue());
|
||||
else
|
||||
endDate = new Date(event.getEndDateTime().getDate().getValue());
|
||||
|
||||
|
||||
return startDate.after(endDate);
|
||||
} catch (final ParseException e) {
|
||||
@@ -92,4 +107,17 @@ public class TimeUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static DateTime doTimeShiftBullshit(DateTime original, ZoneId tz) {
|
||||
return new DateTime(Instant.ofEpochMilli(original.getValue())
|
||||
.plus(1, ChronoUnit.DAYS)
|
||||
.atZone(tz)
|
||||
.truncatedTo(ChronoUnit.DAYS)
|
||||
.toLocalDate()
|
||||
.atStartOfDay()
|
||||
.atZone(tz)
|
||||
.toInstant()
|
||||
.toEpochMilli()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package org.dreamexposure.discal.core.wrapper.google;
|
||||
|
||||
import com.google.api.services.calendar.model.AclRule;
|
||||
|
||||
import org.dreamexposure.discal.core.calendar.CalendarAuth;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
public class AclRuleWrapper {
|
||||
public static Mono<AclRule> insertRule(final AclRule rule, final CalendarData data) {
|
||||
public static Mono<AclRule> insertRule(AclRule rule, CalendarData data) {
|
||||
return CalendarAuth.getCalendarService(data)
|
||||
.flatMap(service -> Mono.fromCallable(() ->
|
||||
service.acl()
|
||||
.insert(data.getCalendarId(), rule)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic()))
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
|
||||
+12
-8
@@ -2,51 +2,53 @@ package org.dreamexposure.discal.core.wrapper.google;
|
||||
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
import com.google.api.services.calendar.model.CalendarListEntry;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import org.dreamexposure.discal.core.calendar.CalendarAuth;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
public class CalendarWrapper {
|
||||
public static Mono<Calendar> createCalendar(final Calendar calendar, final int credId) {
|
||||
public static Mono<Calendar> createCalendar(Calendar calendar, int credId, Snowflake guildId) {
|
||||
return CalendarAuth.getCalendarService(credId)
|
||||
.flatMap(service -> Mono.fromCallable(() ->
|
||||
service.calendars()
|
||||
.insert(calendar)
|
||||
.setQuotaUser(guildId.asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic()))
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<Calendar> updateCalendar(final Calendar calendar, final CalendarData calData) {
|
||||
public static Mono<Calendar> updateCalendar(Calendar calendar, CalendarData calData) {
|
||||
return CalendarAuth.getCalendarService(calData)
|
||||
.flatMap(service -> Mono.fromCallable(() ->
|
||||
service.calendars()
|
||||
.update(calendar.getId(), calendar)
|
||||
.setQuotaUser(calData.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic()))
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<Calendar> getCalendar(final CalendarData data) {
|
||||
public static Mono<Calendar> getCalendar(CalendarData data) {
|
||||
return CalendarAuth.getCalendarService(data)
|
||||
.flatMap(service -> Mono.fromCallable(() ->
|
||||
service.calendars()
|
||||
.get(data.getCalendarAddress())
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic()))
|
||||
.doOnError(e -> LogFeed.log(LogObject.forException("Get Cal Failure", e, CalendarWrapper.class)))
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<Void> deleteCalendar(final CalendarData data) {
|
||||
public static Mono<Void> deleteCalendar(CalendarData data) {
|
||||
return Mono.just(data)
|
||||
.filter(cd -> !cd.getExternal())
|
||||
.filter(cd -> !"primary".equalsIgnoreCase(cd.getCalendarAddress()))
|
||||
@@ -54,6 +56,7 @@ public class CalendarWrapper {
|
||||
CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() -> service.calendars()
|
||||
.delete(cd.getCalendarAddress())
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
)
|
||||
@@ -68,6 +71,7 @@ public class CalendarWrapper {
|
||||
service.calendarList()
|
||||
.list()
|
||||
.setMinAccessRole("writer")
|
||||
.setQuotaUser(calData.getGuildId().asString())
|
||||
.execute()
|
||||
.getItems()
|
||||
).subscribeOn(Schedulers.boundedElastic()))
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
package org.dreamexposure.discal.core.wrapper.google;
|
||||
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
||||
import com.google.api.client.http.HttpResponse;
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.api.client.util.DateTime;
|
||||
import com.google.api.services.calendar.Calendar;
|
||||
import com.google.api.services.calendar.model.Event;
|
||||
|
||||
import org.dreamexposure.discal.core.calendar.CalendarAuth;
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class EventWrapper {
|
||||
public static Mono<Event> createEvent(final CalendarData data, final Event event) {
|
||||
public static Mono<Event> createEvent(CalendarData data, Event event) {
|
||||
return CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() ->
|
||||
service.events()
|
||||
.insert(data.getCalendarId(), event)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(GoogleJsonResponseException.class, e -> {
|
||||
@@ -52,11 +53,12 @@ public class EventWrapper {
|
||||
).onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<Event> updateEvent(final CalendarData data, final Event event) {
|
||||
public static Mono<Event> updateEvent(CalendarData data, Event event) {
|
||||
return CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() ->
|
||||
service.events()
|
||||
.update(data.getCalendarId(), event.getId(), event)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(GoogleJsonResponseException.class, e -> {
|
||||
@@ -83,18 +85,18 @@ public class EventWrapper {
|
||||
).onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<Event> getEvent(final CalendarData data, final String id) {
|
||||
public static Mono<Event> getEvent(CalendarData data, String id) {
|
||||
return CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() ->
|
||||
service.events()
|
||||
.get(data.getCalendarAddress(), id)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(e -> Mono.empty()); //Can ignore this, the event just doesn't exist.
|
||||
}
|
||||
|
||||
public static Mono<List<Event>> getEvents(final CalendarData data, final int amount,
|
||||
final long start) {
|
||||
public static Mono<List<Event>> getEvents(CalendarData data, int amount, long start) {
|
||||
return CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() ->
|
||||
service.events().list(data.getCalendarId())
|
||||
@@ -103,13 +105,13 @@ public class EventWrapper {
|
||||
.setOrderBy("startTime")
|
||||
.setSingleEvents(true)
|
||||
.setShowDeleted(false)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute().getItems()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<List<Event>> getEvents(final CalendarData data, final Calendar service, final int amount,
|
||||
final long start) {
|
||||
public static Mono<List<Event>> getEvents(CalendarData data, Calendar service, int amount, long start) {
|
||||
return Mono.fromCallable(() ->
|
||||
service.events().list(data.getCalendarId())
|
||||
.setMaxResults(amount)
|
||||
@@ -117,6 +119,7 @@ public class EventWrapper {
|
||||
.setOrderBy("startTime")
|
||||
.setSingleEvents(true)
|
||||
.setShowDeleted(false)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute().getItems()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
@@ -132,13 +135,13 @@ public class EventWrapper {
|
||||
.setOrderBy("startTime")
|
||||
.setSingleEvents(true)
|
||||
.setShowDeleted(false)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute().getItems()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<List<Event>> getEvents(final CalendarData data, final long start,
|
||||
final long end) {
|
||||
public static Mono<List<Event>> getEvents(CalendarData data, long start, long end) {
|
||||
return CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() ->
|
||||
service.events().list(data.getCalendarId())
|
||||
@@ -147,17 +150,29 @@ public class EventWrapper {
|
||||
.setOrderBy("startTime")
|
||||
.setSingleEvents(true)
|
||||
.setShowDeleted(false)
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute().getItems()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public static Mono<Void> deleteEvent(final CalendarData data, final String id) {
|
||||
public static Mono<Boolean> deleteEvent(CalendarData data, String id) {
|
||||
return CalendarAuth.getCalendarService(data).flatMap(service ->
|
||||
Mono.fromCallable(() ->
|
||||
service.events()
|
||||
Mono.fromCallable(() -> {
|
||||
HttpResponse response = service.events()
|
||||
.delete(data.getCalendarAddress(), id)
|
||||
.execute()
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.executeUnparsed();
|
||||
|
||||
//Log error code if one happened
|
||||
if (response.getStatusCode() != HttpStatusCodes.STATUS_CODE_OK) {
|
||||
LogFeed.log(LogObject.forDebug(
|
||||
"Event Delete Error | " + response.getStatusCode() + " | " + response.getStatusMessage()
|
||||
));
|
||||
}
|
||||
|
||||
return response.getStatusCode() == HttpStatusCodes.STATUS_CODE_OK;
|
||||
}
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
).onErrorResume(GoogleJsonResponseException.class, e -> {
|
||||
if ("requiredAccessLevel".equalsIgnoreCase(e.getDetails().getErrors().get(0).getReason())) {
|
||||
@@ -169,34 +184,37 @@ public class EventWrapper {
|
||||
return DatabaseManager.getCalendar(data.getGuildId(), data.getCalendarNumber())
|
||||
.flatMap(cd -> deleteEvent(cd, id));
|
||||
} else {
|
||||
return Mono.empty();
|
||||
return Mono.just(false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//This is some other issue I am not currently aware of, logging for handling
|
||||
LogFeed.log(LogObject.forException("GJRE: Event delete Failure", e, EventWrapper.class));
|
||||
return Mono.just(false);
|
||||
}
|
||||
return Mono.empty();
|
||||
}).doOnError(e -> LogFeed.log(LogObject.forException("Event Delete Failure", e, EventWrapper.class))
|
||||
).onErrorResume(e -> Mono.empty());
|
||||
).onErrorReturn(false);
|
||||
}
|
||||
|
||||
|
||||
private static Mono<Boolean> correctAssignedCredentialId(CalendarData data) {
|
||||
return Flux.range(0, CalendarAuth.credentialsCount()).flatMap(i ->
|
||||
CalendarAuth.getCalendarService(i).flatMap(service -> Mono.fromCallable(() ->
|
||||
service.calendarList().get(data.getCalendarId()).execute()
|
||||
service.calendarList()
|
||||
.get(data.getCalendarId())
|
||||
.setQuotaUser(data.getGuildId().asString())
|
||||
.execute()
|
||||
).subscribeOn(Schedulers.boundedElastic())
|
||||
.onErrorResume(GoogleJsonResponseException.class, e -> {
|
||||
if (e.getStatusCode() == GlobalConst.STATUS_NOT_FOUND ||
|
||||
"requiredAccessLevel".equalsIgnoreCase(e.getDetails().getErrors().get(0).getReason())) {
|
||||
return Mono.empty();
|
||||
}
|
||||
.onErrorResume(GoogleJsonResponseException.class, e -> {
|
||||
if (e.getStatusCode() == GlobalConst.STATUS_NOT_FOUND ||
|
||||
"requiredAccessLevel".equalsIgnoreCase(e.getDetails().getErrors().get(0).getReason())) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
return Mono.empty();
|
||||
})
|
||||
return Mono.empty();
|
||||
})
|
||||
).map(cal -> "owner".equalsIgnoreCase(cal.getAccessRole()) ? i : -1)
|
||||
).filter(i -> i > -1)
|
||||
).filter(i -> i > -1)
|
||||
.flatMap(correctCredential -> {
|
||||
//Ayyyyy we found the correct one!! Lets go ahead and save that and bump this back to the calling method
|
||||
CalendarData corrected = new CalendarData(
|
||||
|
||||
@@ -13,7 +13,7 @@ data class CalendarData(
|
||||
@SerialName("guild_id")
|
||||
val guildId: Snowflake = Snowflake.of(0),
|
||||
@SerialName("calendar_number")
|
||||
val calendarNumber: Int = 0,
|
||||
val calendarNumber: Int = 1,
|
||||
@SerialName("calendar_id")
|
||||
val calendarId: String = "primary",
|
||||
@SerialName("calendar_address")
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
package org.dreamexposure.discal.core.`object`.event
|
||||
|
||||
import com.google.api.services.calendar.model.Calendar
|
||||
import com.google.api.services.calendar.model.Event
|
||||
import com.google.api.services.calendar.model.EventDateTime
|
||||
import discord4j.common.util.Snowflake
|
||||
import discord4j.core.`object`.entity.Message
|
||||
import org.dreamexposure.discal.core.`object`.calendar.CalendarData
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager
|
||||
import org.dreamexposure.discal.core.enums.event.EventColor
|
||||
import org.dreamexposure.discal.core.logger.LogFeed
|
||||
import org.dreamexposure.discal.core.logger.`object`.LogObject
|
||||
import org.dreamexposure.discal.core.utils.TimeUtils
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper
|
||||
import reactor.core.publisher.Mono
|
||||
import java.time.ZoneId
|
||||
|
||||
@Suppress("DataClassPrivateConstructor")
|
||||
data class PreEvent private constructor(
|
||||
val guildId: Snowflake,
|
||||
val eventId: String,
|
||||
val calNumber: Int,
|
||||
) {
|
||||
//fields
|
||||
var summary: String? = null
|
||||
@@ -39,10 +41,15 @@ data class PreEvent private constructor(
|
||||
var lastEdit = System.currentTimeMillis()
|
||||
|
||||
//Constructors
|
||||
constructor(guildId: Snowflake) : this(guildId, "N/a")
|
||||
constructor(guildId: Snowflake, calNumber: Int) : this(guildId, "N/a", calNumber)
|
||||
|
||||
constructor(guildId: Snowflake, e: Event) : this(guildId, e.id) {
|
||||
this.color = EventColor.fromNameOrHexOrId(e.colorId)
|
||||
private constructor(guildId: Snowflake, e: Event, calData: CalendarData) : this(guildId, e.id, calData
|
||||
.calendarNumber) {
|
||||
try {
|
||||
this.color = EventColor.fromNameOrHexOrId(e.colorId)
|
||||
} catch (ignore: NullPointerException) {
|
||||
this.color = EventColor.NONE
|
||||
}
|
||||
|
||||
if (e.recurrence != null && e.recurrence.isNotEmpty()) {
|
||||
this.recur = true
|
||||
@@ -53,25 +60,44 @@ data class PreEvent private constructor(
|
||||
if (e.description != null) this.description = e.description
|
||||
if (e.location != null) this.location = e.location
|
||||
|
||||
this.startDateTime = e.start
|
||||
this.endDateTime = e.end
|
||||
if (e.start.date == null)
|
||||
this.startDateTime = e.start
|
||||
|
||||
//Here is where I need to fix the display times
|
||||
//TODO: Get rid of the blocking
|
||||
//TODO: Support multi-cal
|
||||
val data = DatabaseManager.getMainCalendar(this.guildId).block()!!
|
||||
if (e.end.date == null)
|
||||
this.endDateTime = e.end
|
||||
|
||||
var cal: Calendar? = null
|
||||
try {
|
||||
cal = CalendarWrapper.getCalendar(data).block()
|
||||
} catch (ex: Exception) {
|
||||
LogFeed.log(LogObject.forException("Failed to get proper date/time for event!", ex, this.javaClass))
|
||||
if (e.start.timeZone != null) this.timezone = e.start.timeZone
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun copy(guildId: Snowflake, e: Event, calData: CalendarData): Mono<PreEvent> {
|
||||
return CalendarWrapper.getCalendar(calData)
|
||||
.map { ZoneId.of(it.timeZone) }
|
||||
.map { tz ->
|
||||
val event = PreEvent(guildId, e, calData)
|
||||
event.timezone = tz.id
|
||||
|
||||
if (e.start.date != null) {
|
||||
event.startDateTime = EventDateTime()
|
||||
event.startDateTime!!.dateTime = TimeUtils.doTimeShiftBullshit(e.start.date, tz)
|
||||
}
|
||||
if (e.end.date != null) {
|
||||
event.endDateTime = EventDateTime()
|
||||
event.endDateTime!!.dateTime = TimeUtils.doTimeShiftBullshit(e.end.date, tz)
|
||||
}
|
||||
|
||||
return@map event
|
||||
}
|
||||
.flatMap { event ->
|
||||
DatabaseManager.getEventData(guildId, event.eventId)
|
||||
.switchIfEmpty(Mono.just(EventData(guildId, event.eventId)))
|
||||
.doOnNext {
|
||||
event.eventData = it
|
||||
}
|
||||
.thenReturn(event)
|
||||
}
|
||||
}
|
||||
|
||||
if (cal != null) this.timezone = cal.timeZone
|
||||
else this.timezone = "ERROR/Unknown"
|
||||
|
||||
this.eventData = DatabaseManager.getEventData(this.guildId, e.id).block()!!
|
||||
}
|
||||
|
||||
//Functions
|
||||
|
||||
+31
-22
@@ -10,40 +10,49 @@ let browserSync = require('browser-sync').create();
|
||||
|
||||
// Set the banner content
|
||||
let banner = ['/*!\n',
|
||||
' */\n',
|
||||
'\n'
|
||||
' */\n',
|
||||
'\n'
|
||||
].join('');
|
||||
|
||||
// Copy third party libraries from /node_modules into /vendor
|
||||
gulp.task('vendor', gulp.series(function(done) {
|
||||
// Bootstrap
|
||||
gulp.src([
|
||||
gulp.task('vendor', gulp.series(function (done) {
|
||||
// Bootstrap
|
||||
gulp.src([
|
||||
'./node_modules/bootstrap/dist/**/*',
|
||||
'!./node_modules/bootstrap/dist/css/bootstrap-grid*',
|
||||
'!./node_modules/bootstrap/dist/css/bootstrap-reboot*'
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/bootstrap'));
|
||||
|
||||
// jQuery
|
||||
// jQuery
|
||||
gulp.src([
|
||||
'./node_modules/jquery/dist/*',
|
||||
'!./node_modules/jquery/dist/core.js'
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/jquery'));
|
||||
|
||||
// jQuery Easing
|
||||
// jQuery Easing
|
||||
gulp.src([
|
||||
'./node_modules/jquery.easing/*.js'
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/jquery-easing'));
|
||||
|
||||
//ChartJS
|
||||
// FullCalendar
|
||||
/*
|
||||
gulp.src([
|
||||
'./node_modules/fullcalendar/main.min.js',
|
||||
'./node_modules/fullcalendar/main.min.css'
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/fullcalendar'))
|
||||
*/
|
||||
|
||||
// ChartJS
|
||||
gulp.src([
|
||||
'./node_modules/chart.js/dist/*.js'
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/chart.js'));
|
||||
|
||||
//DataTables
|
||||
// DataTables
|
||||
gulp.src([
|
||||
'./node_modules/datatables.net/js/*.js',
|
||||
'./node_modules/datatables.net-bs4/js/*.js',
|
||||
@@ -51,13 +60,13 @@ gulp.task('vendor', gulp.series(function(done) {
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/datatables'));
|
||||
|
||||
// Font Awesome 5
|
||||
// Font Awesome 5
|
||||
gulp.src([
|
||||
'./node_modules/@fortawesome/**/*'
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor'));
|
||||
|
||||
// Simple Line Icons
|
||||
// Simple Line Icons
|
||||
gulp.src([
|
||||
'./node_modules/simple-line-icons/fonts/**'
|
||||
])
|
||||
@@ -68,11 +77,11 @@ gulp.task('vendor', gulp.series(function(done) {
|
||||
])
|
||||
.pipe(gulp.dest('./web/src/main/html/static/vendor/simple-line-icons/css'));
|
||||
|
||||
done();
|
||||
done();
|
||||
}));
|
||||
|
||||
gulp.task('clean:all', gulp.series(function () {
|
||||
return del([
|
||||
return del([
|
||||
"./web/build",
|
||||
"./web/src/main/html/static/assets/js/**",
|
||||
"./web/src/main/html/static/assets/css/**",
|
||||
@@ -81,14 +90,14 @@ gulp.task('clean:all', gulp.series(function () {
|
||||
}));
|
||||
|
||||
gulp.task('clean:build', gulp.series(function () {
|
||||
return del([
|
||||
"./web/build"
|
||||
])
|
||||
return del([
|
||||
"./web/build"
|
||||
])
|
||||
}));
|
||||
|
||||
// Compile SCSS
|
||||
gulp.task('css:compile', gulp.series(function () {
|
||||
return gulp.src('./web/src/main/less/**/*.scss')
|
||||
return gulp.src('./web/src/main/less/**/*.scss')
|
||||
.pipe(sass.sync({
|
||||
outputStyle: 'expanded'
|
||||
}).on('error', sass.logError))
|
||||
@@ -124,12 +133,12 @@ gulp.task('default', gulp.series(['clean:all', 'css', 'vendor', 'clean:build']))
|
||||
gulp.task('build', gulp.series(['clean:all', 'css', 'vendor', 'clean:build']));
|
||||
|
||||
// Configure the browserSync task
|
||||
gulp.task('browserSync', gulp.series(function() {
|
||||
browserSync.init({
|
||||
server: {
|
||||
gulp.task('browserSync', gulp.series(function () {
|
||||
browserSync.init({
|
||||
server: {
|
||||
baseDir: "./web/src/main/html/"
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
// Dev task
|
||||
@@ -141,4 +150,4 @@ gulp.task('dev', gulp.series(['css', 'browserSync'], function () {
|
||||
gulp.watch('/web/src/main/html/static/assets/js/*.js').on('change', function () {
|
||||
browserSync.reload();
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
||||
Generated
+950
-18
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jquery": "3.5.5",
|
||||
"browser-sync": "2.26.13",
|
||||
"css-loader": "5.0.2",
|
||||
"del": "6.0.0",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-autoprefixer": "7.0.1",
|
||||
@@ -25,6 +26,7 @@
|
||||
"gulp-header": "2.0.9",
|
||||
"gulp-rename": "2.0.0",
|
||||
"gulp-sass": "4.1.0",
|
||||
"mini-css-extract-plugin": "1.3.6",
|
||||
"node-sass": "5.0.0",
|
||||
"ts-loader": "8.0.11",
|
||||
"webpack": "5.10.0",
|
||||
@@ -32,12 +34,24 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "5.15.1",
|
||||
"@fullcalendar/bootstrap": "5.5.0",
|
||||
"@fullcalendar/core": "5.5.0",
|
||||
"@fullcalendar/daygrid": "5.5.0",
|
||||
"@fullcalendar/interaction": "5.5.0",
|
||||
"@fullcalendar/list": "5.5.0",
|
||||
"@fullcalendar/moment-timezone": "5.5.0",
|
||||
"@fullcalendar/rrule": "5.5.1",
|
||||
"@fullcalendar/timegrid": "5.5.0",
|
||||
"@popperjs/core": "2.7.0",
|
||||
"bootstrap": "4.5.3",
|
||||
"chart.js": "2.9.4",
|
||||
"datatables.net-bs4": "1.10.22",
|
||||
"jquery": "3.5.1",
|
||||
"jquery.easing": "1.4.1",
|
||||
"moment-timezone": "0.5.33",
|
||||
"rrule": "2.6.8",
|
||||
"sass": "^1.32.8",
|
||||
"tippy.js": "6.2.7",
|
||||
"typescript": "4.1.2",
|
||||
"what-input": "5.2.10"
|
||||
}
|
||||
|
||||
+16
-8
@@ -1,9 +1,8 @@
|
||||
package org.dreamexposure.discal.server.api.endpoints.v2.event;
|
||||
|
||||
import com.google.api.services.calendar.Calendar;
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
import com.google.api.services.calendar.model.Event;
|
||||
|
||||
import org.dreamexposure.discal.core.calendar.CalendarAuth;
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
@@ -13,6 +12,8 @@ import org.dreamexposure.discal.core.object.web.AuthenticationState;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtil;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtils;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
import org.dreamexposure.discal.server.utils.Authentication;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -21,10 +22,13 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.ZoneId;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v2/events")
|
||||
@@ -46,18 +50,22 @@ public class GetEventEndpoint {
|
||||
final String guildId = requestBody.getString("guild_id");
|
||||
final int calNumber = requestBody.getInt("calendar_number");
|
||||
final String eventId = requestBody.getString("event_id");
|
||||
|
||||
final GuildSettings settings = DatabaseManager.getSettings(Snowflake.of(guildId)).block();
|
||||
final CalendarData calendarData = DatabaseManager.getCalendar(settings.getGuildID(), calNumber).block();
|
||||
Mono<CalendarData> calDataMono = DatabaseManager.getCalendar(settings.getGuildID(), calNumber)
|
||||
.cache();
|
||||
final Event event = calDataMono.flatMap(calData -> EventWrapper.getEvent(calData, eventId))
|
||||
.block();
|
||||
final ZoneId tz = calDataMono.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(Calendar::getTimeZone)
|
||||
.map(ZoneId::of)
|
||||
.block();
|
||||
|
||||
//okay, get the calendar service and then the event
|
||||
final Calendar service = CalendarAuth.getCalendarService(calendarData).block();
|
||||
|
||||
final Event event = service.events().get(calendarData.getCalendarAddress(), eventId).execute();
|
||||
|
||||
response.setContentType("application/json");
|
||||
if (event != null) {
|
||||
response.setStatus(GlobalConst.STATUS_SUCCESS);
|
||||
return JsonUtils.convertEventToJson(event, settings).toString();
|
||||
return JsonUtils.convertEventToJson(event, tz, settings).block().toString();
|
||||
} else {
|
||||
response.setStatus(GlobalConst.STATUS_NOT_FOUND);
|
||||
return JsonUtils.getJsonResponseMessage("Event not Found");
|
||||
|
||||
+15
-2
@@ -1,13 +1,17 @@
|
||||
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
|
||||
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.object.web.AuthenticationState;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtil;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtils;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
import org.dreamexposure.discal.server.utils.Authentication;
|
||||
import org.json.JSONException;
|
||||
@@ -17,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -24,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v2/events/list")
|
||||
@@ -46,13 +52,20 @@ public class ListEventDateEndpoint {
|
||||
final int calNumber = requestBody.getInt("calendar_number");
|
||||
final long startEpoch = requestBody.getLong("epoch_start");
|
||||
final long endEpoch = startEpoch + GlobalConst.oneDayMs;
|
||||
|
||||
final GuildSettings settings = DatabaseManager.getSettings(guildId).block();
|
||||
Mono<CalendarData> calDataMono = DatabaseManager.getCalendar(guildId, calNumber)
|
||||
.cache();
|
||||
final ZoneId tz = calDataMono.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(Calendar::getTimeZone)
|
||||
.map(ZoneId::of)
|
||||
.block();
|
||||
|
||||
//okay, lets actually get the date's events.
|
||||
final List<JSONObject> events = DatabaseManager.getCalendar(settings.getGuildID(), calNumber)
|
||||
final List<JSONObject> events = calDataMono
|
||||
.flatMap(calData -> EventWrapper.getEvents(calData, startEpoch, endEpoch))
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.map(e -> JsonUtils.convertEventToJson(e, settings))
|
||||
.flatMap(e -> JsonUtils.convertEventToJson(e, tz, settings))
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
|
||||
+15
-2
@@ -1,13 +1,17 @@
|
||||
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
|
||||
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.object.web.AuthenticationState;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtil;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtils;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
import org.dreamexposure.discal.server.utils.Authentication;
|
||||
import org.json.JSONException;
|
||||
@@ -17,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -24,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v2/events/list")
|
||||
@@ -47,13 +53,20 @@ public class ListEventMonthEndpoint {
|
||||
final int daysInMonth = requestBody.getInt("days_in_month");
|
||||
final long startEpoch = requestBody.getLong("epoch_start");
|
||||
final long endEpoch = startEpoch + (GlobalConst.oneDayMs * daysInMonth);
|
||||
|
||||
final GuildSettings settings = DatabaseManager.getSettings(guildId).block();
|
||||
Mono<CalendarData> calDataMono = DatabaseManager.getCalendar(guildId, calNumber)
|
||||
.cache();
|
||||
final ZoneId tz = calDataMono.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(Calendar::getTimeZone)
|
||||
.map(ZoneId::of)
|
||||
.block();
|
||||
|
||||
//okay, lets actually get the month's events.
|
||||
final List<JSONObject> events = DatabaseManager.getCalendar(settings.getGuildID(), calNumber)
|
||||
final List<JSONObject> events = calDataMono
|
||||
.flatMap(calData -> EventWrapper.getEvents(calData, startEpoch, endEpoch))
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.map(e -> JsonUtils.convertEventToJson(e, settings))
|
||||
.flatMap(e -> JsonUtils.convertEventToJson(e, tz, settings))
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
|
||||
+16
-2
@@ -1,13 +1,17 @@
|
||||
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
|
||||
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.object.web.AuthenticationState;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtil;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtils;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
import org.dreamexposure.discal.server.utils.Authentication;
|
||||
import org.json.JSONException;
|
||||
@@ -17,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -24,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v2/events/list")
|
||||
@@ -48,13 +54,21 @@ public class ListEventOngoingEndpoint {
|
||||
final long end = System.currentTimeMillis() + GlobalConst.oneDayMs; // one day from now
|
||||
final GuildSettings settings = DatabaseManager.getSettings(guildId).block();
|
||||
|
||||
Mono<CalendarData> calDataMono = DatabaseManager.getCalendar(guildId, calNumber)
|
||||
.cache();
|
||||
final ZoneId tz = calDataMono.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(Calendar::getTimeZone)
|
||||
.map(ZoneId::of)
|
||||
.block();
|
||||
|
||||
|
||||
//okay, lets actually get the date's events.
|
||||
final List<JSONObject> events = DatabaseManager.getCalendar(settings.getGuildID(), calNumber)
|
||||
final List<JSONObject> events = calDataMono
|
||||
.flatMap(calData -> EventWrapper.getEvents(calData, start, end))
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.filter(e -> e.getStart().getDateTime().getValue() < System.currentTimeMillis())
|
||||
.filter(e -> e.getEnd().getDateTime().getValue() > System.currentTimeMillis())
|
||||
.map(e -> JsonUtils.convertEventToJson(e, settings))
|
||||
.flatMap(e -> JsonUtils.convertEventToJson(e, tz, settings))
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
|
||||
+17
-2
@@ -1,13 +1,17 @@
|
||||
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
|
||||
|
||||
import com.google.api.services.calendar.model.Calendar;
|
||||
|
||||
import org.dreamexposure.discal.core.database.DatabaseManager;
|
||||
import org.dreamexposure.discal.core.logger.LogFeed;
|
||||
import org.dreamexposure.discal.core.logger.object.LogObject;
|
||||
import org.dreamexposure.discal.core.object.GuildSettings;
|
||||
import org.dreamexposure.discal.core.object.calendar.CalendarData;
|
||||
import org.dreamexposure.discal.core.object.web.AuthenticationState;
|
||||
import org.dreamexposure.discal.core.utils.GlobalConst;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtil;
|
||||
import org.dreamexposure.discal.core.utils.JsonUtils;
|
||||
import org.dreamexposure.discal.core.wrapper.google.CalendarWrapper;
|
||||
import org.dreamexposure.discal.core.wrapper.google.EventWrapper;
|
||||
import org.dreamexposure.discal.server.utils.Authentication;
|
||||
import org.json.JSONException;
|
||||
@@ -17,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -24,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v2/events/list")
|
||||
@@ -46,13 +52,22 @@ public class ListEventRangeEndpoint {
|
||||
final int calNumber = requestBody.getInt("calendar_number");
|
||||
final long startEpoch = requestBody.getLong("epoch_start");
|
||||
final long endEpoch = requestBody.getLong("epoch_end");
|
||||
|
||||
final GuildSettings settings = DatabaseManager.getSettings(guildId).block();
|
||||
|
||||
Mono<CalendarData> calDataMono = DatabaseManager.getCalendar(guildId, calNumber)
|
||||
.cache();
|
||||
final ZoneId tz = calDataMono.flatMap(CalendarWrapper::getCalendar)
|
||||
.map(Calendar::getTimeZone)
|
||||
.map(ZoneId::of)
|
||||
.block();
|
||||
|
||||
|
||||
//okay, lets actually get the range's events.
|
||||
final List<JSONObject> events = DatabaseManager.getCalendar(settings.getGuildID(), calNumber)
|
||||
final List<JSONObject> events = calDataMono
|
||||
.flatMap(calData -> EventWrapper.getEvents(calData, startEpoch, endEpoch))
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.map(e -> JsonUtils.convertEventToJson(e, settings))
|
||||
.flatMap(e -> JsonUtils.convertEventToJson(e, tz, settings))
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
|
||||
+24
-24
@@ -1,31 +1,31 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES5",
|
||||
"module": "ES6",
|
||||
"strict": true,
|
||||
"noImplicitThis": false,
|
||||
"removeComments": true,
|
||||
"importHelpers": true,
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"jquery"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"web/src/main/javascript/*"
|
||||
]
|
||||
}
|
||||
"target": "ES5",
|
||||
"module": "ES6",
|
||||
"strict": true,
|
||||
"noImplicitThis": false,
|
||||
"removeComments": true,
|
||||
"importHelpers": true,
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"jquery"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"web/src/main/javascript/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"web/src/main/javascript/**/*.ts",
|
||||
"web/src/main/javascript/**/*.js"
|
||||
"web/src/main/javascript/**/*.ts",
|
||||
"web/src/main/javascript/**/*.js"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="/assets/css/sb-admin-2.min.css" rel="stylesheet">
|
||||
<link href="/assets/js/main.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
@@ -53,22 +54,22 @@
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-gradient-discal-dark-gray sidebar sidebar-dark accordion"
|
||||
id="accordionSidebar">
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-gradient-discal-dark-gray sidebar sidebar-dark accordion"
|
||||
id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="/">
|
||||
<div class="sidebar-brand-icon rotate-n-15">
|
||||
<i class="fas fa-calendar"></i>
|
||||
</div>
|
||||
<div class="sidebar-brand-text mx-3">DISCAL</div>
|
||||
</a>
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="/">
|
||||
<div class="sidebar-brand-icon rotate-n-15">
|
||||
<i class="fas fa-calendar"></i>
|
||||
</div>
|
||||
<div class="sidebar-brand-text mx-3">DISCAL</div>
|
||||
</a>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider my-0">
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider my-0">
|
||||
|
||||
<!-- Nav Item - About -->
|
||||
<!-- Nav Item - About -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/about">
|
||||
<i class="fas fa-fw fa-info-circle"></i>
|
||||
@@ -192,23 +193,23 @@
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li th:if="${logged_in}" class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="mr-2 d-lg-inline small" th:text="${username}"></span>
|
||||
<img class="img-profile rounded-circle" th:src="${pfp}"
|
||||
alt="pfp">
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="mr-2 d-lg-inline small" th:text="${username}"></span>
|
||||
<img class="img-profile rounded-circle" th:src="${pfp}"
|
||||
alt="pfp">
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow
|
||||
animated--grow-in bg-discal-not-black"
|
||||
aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item text-discord-full-white" href="#"
|
||||
data-toggle="modal" data-target="#logoutModal">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item text-discord-full-white" href="#"
|
||||
data-toggle="modal" data-target="#logoutModal">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li th:unless="${logged_in}" class="nav-item">
|
||||
<a class="nav-link text-discord-full-white" href="/login">
|
||||
<i class="fas fa-sign-in-alt fa-sm fa-fw mr-2"></i>
|
||||
@@ -225,111 +226,27 @@
|
||||
<div class="container-fluid">
|
||||
<div class="loader"></div>
|
||||
|
||||
<div>
|
||||
<label class="text-discord-full-white form-select" for="time-zone-selector">Timezone:</label>
|
||||
<select id="time-zone-selector">
|
||||
<option value="local">local</option>
|
||||
<option value="UTC">UTC</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!--Start calendar -->
|
||||
<div id="calendar-container" hidden="hidden">
|
||||
<table id="calendar" style="border-color: #bcbcbc"
|
||||
border="#bcbcbc" cellpadding="4" cellspacing="0">
|
||||
<tbody>
|
||||
<tr style="height: 50px;">
|
||||
<th id="previous-month" class="cal-nav">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th id="month-display" class="text-center"></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th id="next-month" class="cal-nav">
|
||||
<i class="fa fa-arrow-right"></i>
|
||||
</th>
|
||||
</tr>
|
||||
<tr style="height: 40px;">
|
||||
<th>Sunday</th>
|
||||
<th>Monday</th>
|
||||
<th>Tuesday</th>
|
||||
<th>Wednesday</th>
|
||||
<th>Thursday</th>
|
||||
<th>Friday</th>
|
||||
<th>Saturday</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cal-date" id="r1c1"></td>
|
||||
<td class="cal-date" id="r1c2"></td>
|
||||
<td class="cal-date" id="r1c3"></td>
|
||||
<td class="cal-date" id="r1c4"></td>
|
||||
<td class="cal-date" id="r1c5"></td>
|
||||
<td class="cal-date" id="r1c6"></td>
|
||||
<td class="cal-date" id="r1c7"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cal-date" id="r2c1"></td>
|
||||
<td class="cal-date" id="r2c2"></td>
|
||||
<td class="cal-date" id="r2c3"></td>
|
||||
<td class="cal-date" id="r2c4"></td>
|
||||
<td class="cal-date" id="r2c5"></td>
|
||||
<td class="cal-date" id="r2c6"></td>
|
||||
<td class="cal-date" id="r2c7"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cal-date" id="r3c1"></td>
|
||||
<td class="cal-date" id="r3c2"></td>
|
||||
<td class="cal-date" id="r3c3"></td>
|
||||
<td class="cal-date" id="r3c4"></td>
|
||||
<td class="cal-date" id="r3c5"></td>
|
||||
<td class="cal-date" id="r3c6"></td>
|
||||
<td class="cal-date" id="r3c7"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cal-date" id="r4c1"></td>
|
||||
<td class="cal-date" id="r4c2"></td>
|
||||
<td class="cal-date" id="r4c3"></td>
|
||||
<td class="cal-date" id="r4c4"></td>
|
||||
<td class="cal-date" id="r4c5"></td>
|
||||
<td class="cal-date" id="r4c6"></td>
|
||||
<td class="cal-date" id="r4c7"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cal-date" id="r5c1"></td>
|
||||
<td class="cal-date" id="r5c2"></td>
|
||||
<td class="cal-date" id="r5c3"></td>
|
||||
<td class="cal-date" id="r5c4"></td>
|
||||
<td class="cal-date" id="r5c5"></td>
|
||||
<td class="cal-date" id="r5c6"></td>
|
||||
<td class="cal-date" id="r5c7"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cal-date" id="r6c1"></td>
|
||||
<td class="cal-date" id="r6c2"></td>
|
||||
<td class="cal-date" id="r6c3"></td>
|
||||
<td class="cal-date" id="r6c4"></td>
|
||||
<td class="cal-date" id="r6c5"></td>
|
||||
<td class="cal-date" id="r6c6"></td>
|
||||
<td class="cal-date" id="r6c7"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<p class="text-discord-full-white text-center" id="local-time-display">All Dates
|
||||
and Times are displayed in the calendar's timezone!</p>
|
||||
<br>
|
||||
<br>
|
||||
<a id="view-on-google-button"
|
||||
class="bg-discord-blurple btn btn-discord btn-user btn-block text-discord-full-white"
|
||||
style="margin: 0 auto; max-width: 200px"
|
||||
target="_blank">
|
||||
View on Google Calendar
|
||||
</a>
|
||||
<div id="calendar-container">
|
||||
<div id="calendar"></div>
|
||||
</div>
|
||||
<!--End calendar -->
|
||||
|
||||
<hr>
|
||||
|
||||
<!--Start Event Container-->
|
||||
<div id="events-container" hidden="hidden">
|
||||
<h6>Events for Selected Date</h6>
|
||||
<!--Add events for selected date via JS and JQuery-->
|
||||
</div>
|
||||
<div id="events-container" hidden="hidden">
|
||||
<h6>Events for Selected Date</h6>
|
||||
<!--Add events for selected date via JS and JQuery-->
|
||||
</div>
|
||||
<!--End Event Container-->
|
||||
</div>
|
||||
<!--End container fluid-->
|
||||
@@ -376,25 +293,25 @@
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content bg-discal-not-black">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title text-discal-blue" id="exampleModalLabel">Ready to Leave?</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span class="text-discal-red" aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-left text-discord-full-white">
|
||||
Select "Logout" below if you are ready to end your current session.
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-discal-dark-gray text-discord-full-white"
|
||||
type="button" data-dismiss="modal">Cancel
|
||||
</button>
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title text-discal-blue" id="exampleModalLabel">Ready to Leave?</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span class="text-discal-red" aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-left text-discord-full-white">
|
||||
Select "Logout" below if you are ready to end your current session.
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-discal-dark-gray text-discord-full-white"
|
||||
type="button" data-dismiss="modal">Cancel
|
||||
</button>
|
||||
|
||||
<a class="btn btn-discal-red text-discord-full-white" href="/logout">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-discal-red text-discord-full-white" href="/logout">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -443,6 +443,12 @@
|
||||
<td>!event color GREEN</td>
|
||||
<td>Set's the event's <a href="/docs/events/event-colors">Color</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>!event colour</td>
|
||||
<td>Alias of 'color' See above</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<!-- Start event location command-->
|
||||
<tr>
|
||||
<td>!event location</td>
|
||||
@@ -730,6 +736,12 @@
|
||||
<strong>ONLY needed when using COLOR</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>!a colour</td>
|
||||
<td>Alias of 'color' see above</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<!-- Start announcement channel command-->
|
||||
<tr>
|
||||
<td>!a channel</td>
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
</p>
|
||||
|
||||
<p class="text-left text-discord-full-white"
|
||||
th:text="'Discord4J Version: ' + ${client.d4JVersion}">
|
||||
th:text="'Discord4J Version: ' + ${client.d4jVersion}">
|
||||
</p>
|
||||
|
||||
<p class="text-left text-discord-full-white"
|
||||
|
||||
@@ -1,67 +1,437 @@
|
||||
import {EmbedCalendar} from "@/objects/calendar/EmbedCalendar";
|
||||
import {Calendar} from "@fullcalendar/core";
|
||||
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||
import boostrapPlugin from "@fullcalendar/bootstrap";
|
||||
import interactionPlugin from "@fullcalendar/interaction";
|
||||
import rrulePlugin from "@fullcalendar/rrule";
|
||||
import momentTimezonePlugin from "@fullcalendar/moment-timezone";
|
||||
import {ElementUtil} from "@/utils/ElementUtil";
|
||||
import {CalendarGetRequest} from "@/network/calendar/CalendarGetRequest";
|
||||
import {TaskCallback} from "@/objects/task/TaskCallback";
|
||||
import {NetworkCallStatus} from "@/objects/network/NetworkCallStatus";
|
||||
import {Snackbar} from "@/utils/snackbar";
|
||||
import {TaskType} from "@/enums/TaskType";
|
||||
import {WebCalendar} from "@/objects/calendar/WebCalendar";
|
||||
import {Event} from "@/objects/event/Event";
|
||||
import moment from "moment-timezone";
|
||||
import {EventColor, eventColorClass} from "@/enums/EventColor";
|
||||
import {EventFrequency} from "@/enums/EventFrequency";
|
||||
|
||||
export class EmbedCalendarRunner {
|
||||
private embedCalendar: EmbedCalendar;
|
||||
export class EmbedCalendarRunner implements TaskCallback {
|
||||
private initialTimezone: string = 'local';
|
||||
private timezoneSelectorEl = document
|
||||
.getElementById('time-zone-selector')! as HTMLSelectElement;
|
||||
private calendar?: Calendar;
|
||||
|
||||
private readonly guildId;
|
||||
private readonly calNumber;
|
||||
|
||||
private readonly apiKey;
|
||||
private readonly apiUrl;
|
||||
|
||||
private calendarData: WebCalendar = new WebCalendar();
|
||||
|
||||
constructor(key: string, url: string) {
|
||||
this.guildId = window.location.pathname.split("/")[2];
|
||||
this.calNumber = parseInt(window.location.pathname.split("/")[4]);
|
||||
this.apiKey = key;
|
||||
this.apiUrl = url;
|
||||
|
||||
//Create calendar and its needed components
|
||||
let calendarEl = document.getElementById('calendar')!;
|
||||
this.calendar = new Calendar(calendarEl, {
|
||||
plugins: [
|
||||
dayGridPlugin, timeGridPlugin,
|
||||
boostrapPlugin, interactionPlugin,
|
||||
rrulePlugin, momentTimezonePlugin
|
||||
],
|
||||
themeSystem: 'bootstrap',
|
||||
initialView: 'dayGridMonth',
|
||||
customButtons: {
|
||||
viewGoogle: {
|
||||
text: 'View on Google',
|
||||
click: () => {
|
||||
window.open("https://calendar.google.com/calendar/embed?src=" + this.calendarData.id, "_blank");
|
||||
},
|
||||
}
|
||||
},
|
||||
headerToolbar: {
|
||||
start: 'prev,next,today',
|
||||
center: 'title',
|
||||
end: 'dayGridMonth,timeGridWeek,timeGridDay viewGoogle'
|
||||
},
|
||||
navLinks: true,
|
||||
nowIndicator: true,
|
||||
slotEventOverlap: true,
|
||||
dayMaxEvents: true,
|
||||
timeZone: this.initialTimezone,
|
||||
displayEventEnd: true,
|
||||
eventColor: '#5566c2',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
omitZeroMinute: true,
|
||||
hour12: true, //TODO: Support guild setting for this...
|
||||
timeZoneName: 'short'
|
||||
},
|
||||
eventDidMount: (info) => {
|
||||
// So here we will call the method to build the event modal and have that method add to dom
|
||||
document.body.appendChild(this.buildModal(info.event.extendedProps.rawEvent));
|
||||
},
|
||||
eventWillUnmount: (info) => {
|
||||
//Remove the event modal from the dom
|
||||
document.body.removeChild(document.getElementById("modal-" + info.event.id)!);
|
||||
},
|
||||
eventClick: (info) => {
|
||||
//Open modal to show all the event details instead of just the short info...
|
||||
info.jsEvent.preventDefault();
|
||||
// @ts-ignore
|
||||
$("#modal-" + info.event.id).modal("show");
|
||||
},
|
||||
events: (fetchInfo, successCallback, failureCallback) => {
|
||||
let bodyRaw = {
|
||||
'guild_id': this.guildId,
|
||||
'calendar_number': this.calNumber,
|
||||
'epoch_start': fetchInfo.start.valueOf(),
|
||||
'epoch_end': fetchInfo.end.valueOf(),
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: this.apiUrl + "/v2/events/list/range",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": this.apiKey,
|
||||
},
|
||||
method: "POST",
|
||||
dataType: "json",
|
||||
data: JSON.stringify(bodyRaw),
|
||||
success: (json: any) => {
|
||||
let events = [];
|
||||
|
||||
for (let i = 0; i < json.events.length; i++) {
|
||||
|
||||
events.push(new Event().fromJson(json.events[i]).toFullCalEvent(false));
|
||||
}
|
||||
successCallback(events);
|
||||
},
|
||||
error: (jqXHR) => {
|
||||
Snackbar.showSnackbar("[ERROR] " + jqXHR.responseJSON.message);
|
||||
failureCallback(jqXHR.responseJSON.message);
|
||||
},
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
//Add listener for user changing timezone selector
|
||||
this.timezoneSelectorEl.addEventListener('change', function () {
|
||||
this.calendar.setOption('timeZone', this.timezoneSelectorEl.value)
|
||||
}.bind(this))
|
||||
|
||||
//Get timezones for selector
|
||||
$.ajax({
|
||||
url: "https://fullcalendar.io/demo-timezones.json",
|
||||
method: "GET",
|
||||
success: function (json: any) {
|
||||
for (let timezone in json) {
|
||||
if (json.hasOwnProperty(timezone) && json[timezone] !== 'UTC') {
|
||||
let optionEl = document.createElement('option');
|
||||
optionEl.value = json[timezone];
|
||||
optionEl.innerText = json[timezone];
|
||||
this.timezoneSelectorEl.appendChild(optionEl);
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
error: function (ignore: JQueryXHR) {
|
||||
//failure
|
||||
}
|
||||
});
|
||||
|
||||
//Run init to start other API requests...
|
||||
this.init();
|
||||
}
|
||||
|
||||
private init() {
|
||||
if (this.apiKey === "internal_error") {
|
||||
alert("Failed to get a read-only API key to display your calendar.\nIf you keep receiving this error," +
|
||||
" please contact the developers.");
|
||||
} else {
|
||||
//Request calendar information
|
||||
let calReq = new CalendarGetRequest(this.guildId, this.calNumber, this);
|
||||
calReq.provideApiDetails(this.apiKey, this.apiUrl);
|
||||
|
||||
//Execute the calls
|
||||
calReq.execute();
|
||||
}
|
||||
}
|
||||
|
||||
onCallback(status: NetworkCallStatus) {
|
||||
if (status.isSuccess) {
|
||||
switch (status.type) {
|
||||
case TaskType.CALENDAR_GET: {
|
||||
this.calendarData = new WebCalendar().fromJson(status.body);
|
||||
|
||||
//Hide loading UI and show calendar...
|
||||
ElementUtil.hideLoader();
|
||||
this.calendar?.render();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Snackbar.showSnackbar("[ERROR] " + status.message);
|
||||
}
|
||||
}
|
||||
|
||||
//Ugh, this actually sucks having to make this stuff...
|
||||
buildModal(event: Event): HTMLElement {
|
||||
//Create modal container
|
||||
let modalContainer = document.createElement("div");
|
||||
modalContainer.className = "modal fade";
|
||||
modalContainer.id = "modal-" + event.eventId;
|
||||
// @ts-ignore
|
||||
modalContainer.role = "dialog";
|
||||
|
||||
//Create modal-dialog
|
||||
let modalDia = document.createElement("div");
|
||||
modalDia.className = "modal-dialog modal-dialog-scrollable";
|
||||
modalContainer.appendChild(modalDia);
|
||||
|
||||
//Create modal content
|
||||
let modalCon = document.createElement("div");
|
||||
modalCon.className = "modal-content bg-discal-not-black";
|
||||
modalDia.appendChild(modalCon);
|
||||
|
||||
//Create modal header and title
|
||||
let modalHeader = document.createElement("div");
|
||||
modalHeader.className = "modal-header bg-discal-not-black";
|
||||
modalCon.appendChild(modalHeader);
|
||||
let modalTitle = document.createElement("h4");
|
||||
modalTitle.className = "modal-title text-discord-blurple text-center";
|
||||
modalTitle.innerText = "Viewing Event";
|
||||
modalHeader.appendChild(modalTitle);
|
||||
|
||||
//Create modal body
|
||||
let modalBody = document.createElement("div");
|
||||
modalBody.className = "modal-body";
|
||||
modalCon.appendChild(modalBody);
|
||||
|
||||
//summary/name
|
||||
let summaryLabel = document.createElement("label");
|
||||
summaryLabel.className = "text-discord-full-white form-label";
|
||||
summaryLabel.htmlFor = "event-summary-" + event.eventId;
|
||||
summaryLabel.innerText = "Summary/Name";
|
||||
summaryLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(summaryLabel);
|
||||
let summary = document.createElement("textarea");
|
||||
summary.className = "form-control";
|
||||
summary.id = "event-summary-" + event.eventId;
|
||||
summary.name = "summary";
|
||||
summary.readOnly = true;
|
||||
summary.value = event.summary;
|
||||
modalBody.appendChild(summary);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
|
||||
//Description
|
||||
if (event.description.trim().length > 0) {
|
||||
let descLabel = document.createElement("label");
|
||||
descLabel.className = "text-discord-full-white form-label";
|
||||
descLabel.htmlFor = "event-description-" + event.eventId;
|
||||
descLabel.innerText = "Description";
|
||||
descLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(descLabel);
|
||||
let desc = document.createElement("textarea");
|
||||
desc.className = "form-control";
|
||||
desc.id = "event-description-" + event.eventId;
|
||||
desc.name = "description";
|
||||
desc.readOnly = true;
|
||||
desc.value = event.description;
|
||||
modalBody.appendChild(desc);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
}
|
||||
|
||||
//Create correctly formatted start/end date/times
|
||||
//TODO: Support 24-hour format guild setting
|
||||
const format = "dddd, MMMM, Do YYYY, h:mm a z" //Friday, February 26th 2021, 1:20 AM CST
|
||||
|
||||
let startString;
|
||||
let endString;
|
||||
if (this.timezoneSelectorEl.value == "local") {
|
||||
startString = moment(new Date(event.epochStart)).format(format);
|
||||
endString = moment(new Date(event.epochEnd)).format(format);
|
||||
} else {
|
||||
startString = moment.tz(new Date(event.epochStart), this.timezoneSelectorEl.value).format(format);
|
||||
endString = moment.tz(new Date(event.epochEnd), this.timezoneSelectorEl.value).format(format);
|
||||
}
|
||||
|
||||
//Start date and time
|
||||
let startLabel = document.createElement("label");
|
||||
startLabel.className = "text-discord-full-white form-label";
|
||||
startLabel.htmlFor = "event-start-" + event.eventId;
|
||||
startLabel.innerText = "Event Start";
|
||||
startLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(startLabel);
|
||||
let start = document.createElement("input");
|
||||
start.type = "text";
|
||||
start.className = "form-control";
|
||||
start.id = "event-start-" + event.eventId;
|
||||
start.name = "label";
|
||||
start.readOnly = true;
|
||||
start.value = startString;
|
||||
modalBody.appendChild(start);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
|
||||
//End date and time
|
||||
let endLabel = document.createElement("label");
|
||||
endLabel.className = "text-discord-full-white form-label";
|
||||
endLabel.htmlFor = "event-end-" + event.eventId;
|
||||
endLabel.innerText = "Event End";
|
||||
endLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(endLabel);
|
||||
let end = document.createElement("input");
|
||||
end.type = "text";
|
||||
end.className = "form-control";
|
||||
end.id = "event-start-" + event.eventId;
|
||||
end.name = "label";
|
||||
end.readOnly = true;
|
||||
end.value = endString;
|
||||
modalBody.appendChild(end);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
|
||||
//Location
|
||||
if (event.location.trim().length > 0) {
|
||||
let locationLabel = document.createElement("label");
|
||||
locationLabel.className = "text-discord-full-white form-label";
|
||||
locationLabel.htmlFor = "event-location-" + event.eventId;
|
||||
locationLabel.innerText = "Location";
|
||||
locationLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(locationLabel);
|
||||
let location = document.createElement("textarea");
|
||||
location.className = "form-control";
|
||||
location.id = "event-location-" + event.eventId;
|
||||
location.name = "location";
|
||||
location.readOnly = true;
|
||||
location.value = event.location;
|
||||
modalBody.appendChild(location);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
}
|
||||
|
||||
//Color
|
||||
let eventColor = document.createElement("h1");
|
||||
eventColor.className = "text-discal-not-black bg-" + eventColorClass(event.color);
|
||||
eventColor.id = "event-color-" + event.eventId;
|
||||
eventColor.innerText = "Event Color: " + EventColor[event.color];
|
||||
modalBody.appendChild(eventColor);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
|
||||
//Recurrence
|
||||
if (event.doesRecur) {
|
||||
//Label
|
||||
let recurLabel = document.createElement("label");
|
||||
recurLabel.className = "text-discord-full-white form-label"
|
||||
recurLabel.innerText = "Recurrence Settings";
|
||||
recurLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(recurLabel);
|
||||
|
||||
//Group
|
||||
let recurGroup = document.createElement("div");
|
||||
recurGroup.className = "input-group";
|
||||
modalBody.appendChild(recurGroup);
|
||||
|
||||
//Frequency
|
||||
let freqLabel = document.createElement("span");
|
||||
freqLabel.className = "input-group-text";
|
||||
freqLabel.id = "event-freq-label-" + event.eventId;
|
||||
freqLabel.innerText = "Frequency";
|
||||
recurGroup.appendChild(freqLabel);
|
||||
let freq = document.createElement("input");
|
||||
freq.className = "form-control";
|
||||
freq.type = "text";
|
||||
freq.setAttribute("aria-describedby", "event-freq-label-" + event.eventId);
|
||||
freq.readOnly = true;
|
||||
freq.innerText = EventFrequency[event.recurrence.frequency];
|
||||
recurGroup.appendChild(freq);
|
||||
|
||||
//Count
|
||||
let countLabel = document.createElement("span");
|
||||
countLabel.className = "input-group-text";
|
||||
countLabel.id = "event-count-label-" + event.eventId;
|
||||
countLabel.innerText = "Count";
|
||||
recurGroup.appendChild(countLabel);
|
||||
let count = document.createElement("input");
|
||||
count.className = "form-control";
|
||||
count.type = "number";
|
||||
count.setAttribute("aria-describedby", "event-count-label-" + event.eventId);
|
||||
count.readOnly = true;
|
||||
count.innerText = event.recurrence.count.toString();
|
||||
recurGroup.appendChild(count);
|
||||
|
||||
//Interval
|
||||
let intervalLabel = document.createElement("span");
|
||||
intervalLabel.className = "input-group-text";
|
||||
intervalLabel.id = "event-interval-label-" + event.eventId;
|
||||
intervalLabel.innerText = "Interval";
|
||||
recurGroup.appendChild(intervalLabel);
|
||||
let interval = document.createElement("input");
|
||||
interval.className = "form-control";
|
||||
interval.type = "number";
|
||||
interval.setAttribute("aria-describedby", "event-interval-label-" + event.eventId);
|
||||
interval.readOnly = true;
|
||||
interval.innerText = event.recurrence.interval.toString();
|
||||
recurGroup.appendChild(interval);
|
||||
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
}
|
||||
|
||||
//Image
|
||||
if (event.image.trim().length > 0) {
|
||||
let img = document.createElement("img");
|
||||
img.className = "img-fluid round";
|
||||
img.id = "event-img-" + event.eventId;
|
||||
img.alt = "Event Image";
|
||||
img.src = event.image;
|
||||
modalBody.appendChild(img);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
}
|
||||
|
||||
//ID
|
||||
let idLabel = document.createElement("label");
|
||||
idLabel.className = "text-discord-full-white form-label";
|
||||
idLabel.htmlFor = "event-id-" + event.eventId;
|
||||
idLabel.innerText = "Event ID";
|
||||
idLabel.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(idLabel);
|
||||
let id = document.createElement("input");
|
||||
id.className = "form-control";
|
||||
id.id = "event-id-" + event.eventId;
|
||||
id.type = "text";
|
||||
id.name = "id";
|
||||
id.readOnly = true;
|
||||
id.value = event.eventId;
|
||||
modalBody.appendChild(id);
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
modalBody.appendChild(document.createElement("br"));
|
||||
|
||||
|
||||
constructor() {
|
||||
this.embedCalendar = new EmbedCalendar();
|
||||
}
|
||||
//Create modal footer
|
||||
let modalFooter = document.createElement("div");
|
||||
modalFooter.className = "modal-footer";
|
||||
modalCon.appendChild(modalFooter);
|
||||
|
||||
init(key: string, url: string) {
|
||||
this.embedCalendar.init(key, url);
|
||||
let closeButton = document.createElement("button");
|
||||
closeButton.type = "button";
|
||||
closeButton.className = "btn bg-discord-blurple btn-discord btn-block text-discord-full-white";
|
||||
closeButton.setAttribute("data-dismiss", "modal");
|
||||
closeButton.innerText = "Close";
|
||||
modalFooter.appendChild(closeButton);
|
||||
|
||||
/**loop through stuff and assign onclick to the functions here since we can't do it in html
|
||||
*due to how the code is compiled and minified, making it impossible to call these functions
|
||||
**/
|
||||
document.getElementById("previous-month")!.onclick = function () {
|
||||
this.previousMonth();
|
||||
}.bind(this);
|
||||
document.getElementById("next-month")!.onclick = function () {
|
||||
this.nextMonth();
|
||||
}.bind(this);
|
||||
|
||||
let dateDisplays = document.getElementsByClassName("cal-date");
|
||||
for (let i = 0; i < dateDisplays.length; i++) {
|
||||
let e = (<HTMLElement>dateDisplays[i]);
|
||||
e.onclick = function () {
|
||||
this.selectDate(e.id);
|
||||
}.bind(this);
|
||||
}
|
||||
}
|
||||
|
||||
//Handle user input for the calendar....
|
||||
previousMonth() {
|
||||
this.embedCalendar.selectedDate.setMonth(this.embedCalendar.selectedDate.getMonth() - 1);
|
||||
this.embedCalendar.selectedDate.setDate(1);
|
||||
|
||||
this.embedCalendar.setMonth(this.embedCalendar.selectedDate);
|
||||
|
||||
this.embedCalendar.getEventsForMonth();
|
||||
this.embedCalendar.getEventsForSelectedDate();
|
||||
}
|
||||
|
||||
nextMonth() {
|
||||
this.embedCalendar.selectedDate.setMonth(this.embedCalendar.selectedDate.getMonth() + 1);
|
||||
this.embedCalendar.selectedDate.setDate(1);
|
||||
|
||||
this.embedCalendar.setMonth(this.embedCalendar.selectedDate);
|
||||
|
||||
this.embedCalendar.getEventsForMonth();
|
||||
this.embedCalendar.getEventsForSelectedDate();
|
||||
}
|
||||
|
||||
selectDate(clickedId: string) {
|
||||
let e = document.getElementById(clickedId)!;
|
||||
let dateString = e.innerHTML.split("[")[0];
|
||||
if (dateString !== "") {
|
||||
let dateNum = parseInt(dateString);
|
||||
|
||||
this.embedCalendar.selectedDate.setDate(dateNum);
|
||||
this.embedCalendar.getEventsForSelectedDate();
|
||||
|
||||
document.getElementsByClassName("selected")[0].classList.remove("selected");
|
||||
e.classList.add("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
return modalContainer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,4 +11,84 @@ export enum EventColor {
|
||||
GREEN,
|
||||
RED,
|
||||
NONE
|
||||
}
|
||||
}
|
||||
|
||||
export function eventColorRGB(color: EventColor) {
|
||||
switch (color) {
|
||||
case EventColor.MELROSE: {
|
||||
return '#A4BDFC';
|
||||
}
|
||||
case EventColor.RIPTIDE: {
|
||||
return '#7AE7BF';
|
||||
}
|
||||
case EventColor.MAUVE: {
|
||||
return '#DBADFF';
|
||||
}
|
||||
case EventColor.TANGERINE: {
|
||||
return '#FF887C';
|
||||
}
|
||||
case EventColor.DANDELION: {
|
||||
return '#FBD75B';
|
||||
}
|
||||
case EventColor.MAC_AND_CHEESE: {
|
||||
return '#FFB878';
|
||||
}
|
||||
case EventColor.TURQUOISE: {
|
||||
return '#46D6DB';
|
||||
}
|
||||
case EventColor.MERCURY: {
|
||||
return '#E1E1E1';
|
||||
}
|
||||
case EventColor.BLUE: {
|
||||
return '#5484ED';
|
||||
}
|
||||
case EventColor.GREEN: {
|
||||
return '#51B749';
|
||||
}
|
||||
case EventColor.RED: {
|
||||
return '#DC2127';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function eventColorClass(color: EventColor) {
|
||||
switch (color) {
|
||||
case EventColor.MELROSE: {
|
||||
return 'google-melrose';
|
||||
}
|
||||
case EventColor.RIPTIDE: {
|
||||
return 'google-riptide';
|
||||
}
|
||||
case EventColor.MAUVE: {
|
||||
return 'google-mauve';
|
||||
}
|
||||
case EventColor.TANGERINE: {
|
||||
return 'google-tangerine';
|
||||
}
|
||||
case EventColor.DANDELION: {
|
||||
return 'google-dandelion';
|
||||
}
|
||||
case EventColor.MAC_AND_CHEESE: {
|
||||
return 'google-mac_and_cheese';
|
||||
}
|
||||
case EventColor.TURQUOISE: {
|
||||
return 'google-turquoise';
|
||||
}
|
||||
case EventColor.MERCURY: {
|
||||
return 'google-mercury';
|
||||
}
|
||||
case EventColor.BLUE: {
|
||||
return 'google-blue';
|
||||
}
|
||||
case EventColor.GREEN: {
|
||||
return 'google-green';
|
||||
}
|
||||
case EventColor.RED: {
|
||||
return 'google-red';
|
||||
}
|
||||
default: {
|
||||
return "discord-blurple";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ function loadDashboardCalendarPage(apiKey: string, apiUrl: string, userId: strin
|
||||
}
|
||||
|
||||
function loadEmbedCalendar(embedKey: string, apiUrl: string) {
|
||||
let embedRunner = new EmbedCalendarRunner();
|
||||
embedRunner.init(embedKey, apiUrl);
|
||||
new EmbedCalendarRunner(embedKey, apiUrl);
|
||||
}
|
||||
|
||||
const body = document.getElementById("page-top")!;
|
||||
@@ -94,4 +93,4 @@ if (body.dataset.embedKey != null) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
})(jQuery);
|
||||
|
||||
@@ -1,559 +0,0 @@
|
||||
import {Snackbar} from "@/utils/snackbar";
|
||||
import {EventColor} from "@/enums/EventColor";
|
||||
import {EventFrequency} from "@/enums/EventFrequency";
|
||||
import {TaskCallback} from "@/objects/task/TaskCallback";
|
||||
import {NetworkCallStatus} from "@/objects/network/NetworkCallStatus";
|
||||
import {TaskType} from "@/enums/TaskType";
|
||||
import {WebCalendar} from "@/objects/calendar/WebCalendar";
|
||||
import {CalendarGetRequest} from "@/network/calendar/CalendarGetRequest";
|
||||
import {EventListMonthRequest} from "@/network/event/list/EventListMonthRequest";
|
||||
import {EventListDateRequest} from "@/network/event/list/EventListDateRequest";
|
||||
import {Event} from "@/objects/event/Event";
|
||||
import {ElementUtil} from "@/utils/ElementUtil";
|
||||
|
||||
|
||||
//The calendar class. This just handles all the stuff inside of the calendar, and keeps it isolated.
|
||||
export class EmbedCalendar implements TaskCallback {
|
||||
private readonly guildId: string;
|
||||
private readonly calNumber: number;
|
||||
private todaysDate: Date;
|
||||
private displays: string[];
|
||||
private apiKey: string;
|
||||
private apiUrl: string;
|
||||
|
||||
public selectedDate: Date;
|
||||
|
||||
private calendarData: WebCalendar = new WebCalendar();
|
||||
|
||||
constructor() {
|
||||
this.guildId = window.location.pathname.split("/")[2];
|
||||
this.calNumber = parseInt(window.location.pathname.split("/")[4]);
|
||||
this.todaysDate = new Date();
|
||||
this.selectedDate = new Date();
|
||||
this.displays = [];
|
||||
this.apiKey = "";
|
||||
this.apiUrl = "";
|
||||
}
|
||||
|
||||
init(key: string, url: string) {
|
||||
this.apiKey = key;
|
||||
this.apiUrl = url;
|
||||
|
||||
if (this.apiKey === "internal_error") {
|
||||
ElementUtil.hideLoader();
|
||||
alert("Failed to get a read-only API key to display your calendar. \n" +
|
||||
"If you keep receiving this error, please contact the developers");
|
||||
|
||||
} else {
|
||||
//Request calendar information
|
||||
let calReq = new CalendarGetRequest(this.guildId, this.calNumber, this);
|
||||
calReq.provideApiDetails(this.apiKey, this.apiUrl);
|
||||
|
||||
//Execute the calls
|
||||
this.setMonth(this.selectedDate);
|
||||
|
||||
calReq.execute();
|
||||
this.getEventsForMonth();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//Utility methods for data to human readable conversions
|
||||
getMonthName(index: number) {
|
||||
return ["January", "February", "March",
|
||||
"April", "May", "June",
|
||||
"July", "August", "September",
|
||||
"October", "November", "December"][index];
|
||||
}
|
||||
|
||||
getDayName(index: number) {
|
||||
return ["Sunday", "Monday",
|
||||
"Tuesday", "Wednesday",
|
||||
"Thursday", "Friday",
|
||||
"Saturday"][index];
|
||||
}
|
||||
|
||||
dateDisplays() {
|
||||
//This is all of the IDs for the date displays, in row N, column X shorthand.
|
||||
return ["r1c1", "r1c2", "r1c3", "r1c4", "r1c5", "r1c6", "r1c7",
|
||||
"r2c1", "r2c2", "r2c3", "r2c4", "r2c5", "r2c6", "r2c7",
|
||||
"r3c1", "r3c2", "r3c3", "r3c4", "r3c5", "r3c6", "r3c7",
|
||||
"r4c1", "r4c2", "r4c3", "r4c4", "r4c5", "r4c6", "r4c7",
|
||||
"r5c1", "r5c2", "r5c3", "r5c4", "r5c5", "r5c6", "r5c7",
|
||||
"r6c1", "r6c2", "r6c3", "r6c4", "r6c5", "r6c6", "r6c7"];
|
||||
}
|
||||
|
||||
daysInMonth() {
|
||||
return new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth() + 1, 0).getDate();
|
||||
}
|
||||
|
||||
//Handling some display nonsense
|
||||
dateDisplaysToChange(str: string) {
|
||||
return this.dateDisplays().slice(this.dateDisplays().indexOf(str), this.dateDisplays().length - 1);
|
||||
}
|
||||
|
||||
findFirstDayOfMonthPosition() {
|
||||
let firstDay = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), 1);
|
||||
|
||||
let firstDayName = this.getDayName(firstDay.getDay());
|
||||
|
||||
switch (firstDayName) {
|
||||
case "Sunday":
|
||||
return "r1c1";
|
||||
case "Monday":
|
||||
return "r1c2";
|
||||
case "Tuesday":
|
||||
return "r1c3";
|
||||
case "Wednesday":
|
||||
return "r1c4";
|
||||
case "Thursday":
|
||||
return "r1c5";
|
||||
case "Friday":
|
||||
return "r1c6";
|
||||
case "Saturday":
|
||||
return "r1c7";
|
||||
}
|
||||
|
||||
return "r1c1";
|
||||
}
|
||||
|
||||
changeRecurrenceEditDisplays(checkbox: HTMLInputElement) {
|
||||
let eventId = checkbox.id.split("-")[1];
|
||||
if (checkbox.checked) {
|
||||
//Enable recur input
|
||||
(<HTMLInputElement>document.getElementById("editFrequency-" + eventId)).disabled = false;
|
||||
(<HTMLInputElement>document.getElementById("editCount-" + eventId)).disabled = false;
|
||||
(<HTMLInputElement>document.getElementById("editInterval-" + eventId)).disabled = false;
|
||||
|
||||
} else {
|
||||
//Disable recur input
|
||||
(<HTMLInputElement>document.getElementById("editFrequency-" + eventId)).disabled = true;
|
||||
(<HTMLInputElement>document.getElementById("editCount-" + eventId)).disabled = true;
|
||||
(<HTMLInputElement>document.getElementById("editInterval-" + eventId)).disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Actually handling calendar activities
|
||||
setMonth(date: Date) {
|
||||
|
||||
document.getElementById("month-display")!.innerHTML = this.getMonthName(date.getMonth()) + " " + date.getFullYear();
|
||||
|
||||
this.displays = [];
|
||||
|
||||
let tcc = this.dateDisplays();
|
||||
for (let ii = 0; ii < tcc.length; ii++) {
|
||||
let e = document.getElementById(tcc[ii])!;
|
||||
e.innerHTML = "";
|
||||
e.className = "cal-date";
|
||||
}
|
||||
|
||||
let tc = this.dateDisplaysToChange(this.findFirstDayOfMonthPosition());
|
||||
let count = this.daysInMonth();
|
||||
for (let i = 0; i < tc.length; i++) {
|
||||
let d = i + 1;
|
||||
if (d <= count) {
|
||||
let el = document.getElementById(tc[i])!;
|
||||
el.innerHTML = d + "";
|
||||
this.displays[d] = tc[i];
|
||||
|
||||
let thisDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), d);
|
||||
if (d === this.selectedDate.getDate()) {
|
||||
el.className = "selected cal-date";
|
||||
}
|
||||
if (thisDate.getMonth() === this.todaysDate.getMonth()
|
||||
&& thisDate.getFullYear() === this.todaysDate.getFullYear()
|
||||
&& thisDate.getDate() === this.todaysDate.getDate()) {
|
||||
if (el.classList.contains("selected")) {
|
||||
el.className = "today selected cal-date";
|
||||
//get events for it
|
||||
this.getEventsForSelectedDate();
|
||||
} else {
|
||||
el.className = "today cal-date";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getEventsForMonth() {
|
||||
let ds = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), 1);
|
||||
ds.setHours(0, 0, 0, 0);
|
||||
|
||||
let eventReq = new EventListMonthRequest(this.guildId, this.calNumber,
|
||||
this.daysInMonth(), ds.getTime(), this);
|
||||
|
||||
eventReq.provideApiDetails(this.apiKey, this.apiUrl);
|
||||
|
||||
eventReq.execute();
|
||||
}
|
||||
|
||||
getEventsForSelectedDate() {
|
||||
let ds = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate());
|
||||
ds.setHours(0, 0, 0, 0);
|
||||
|
||||
ElementUtil.hideEventsContainer();
|
||||
|
||||
let eventReq = new EventListDateRequest(this.guildId, this.calNumber, ds.getTime(), this);
|
||||
eventReq.provideApiDetails(this.apiKey, this.apiUrl);
|
||||
|
||||
eventReq.execute();
|
||||
}
|
||||
|
||||
onCallback(status: NetworkCallStatus): void {
|
||||
if (status.isSuccess) {
|
||||
switch (status.type) {
|
||||
case TaskType.CALENDAR_GET:
|
||||
this.calendarData = new WebCalendar().fromJson(status.body);
|
||||
|
||||
(<HTMLLinkElement>document.getElementById("view-on-google-button"))
|
||||
.href = "https://calendar.google.com/calendar/embed?src="
|
||||
+ this.calendarData.address;
|
||||
break;
|
||||
case TaskType.EVENT_LIST_MONTH:
|
||||
//Display the event counts on the calendar...
|
||||
for (let i = 0; i < status.body.events.length; i++) {
|
||||
let d = new Date(status.body.events[i].epoch_start);
|
||||
|
||||
let e = document.getElementById(this.displays[d.getDate()])!;
|
||||
|
||||
if (e.innerHTML.indexOf("[") === -1) {
|
||||
e.innerHTML = d.getDate() + "[1]";
|
||||
} else {
|
||||
e.innerHTML = d.getDate().toString()
|
||||
+ "[" + (parseInt(e.innerHTML.split("[")[1][0]) + 1).toString() + "]";
|
||||
}
|
||||
}
|
||||
ElementUtil.hideLoader();
|
||||
ElementUtil.showCalendarContainer();
|
||||
break;
|
||||
case TaskType.EVENT_LIST_DATE:
|
||||
EmbedCalendar.loadEventDisplay(status);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Snackbar.showSnackbar("ERROR] " + status.message);
|
||||
}
|
||||
}
|
||||
|
||||
private static loadEventDisplay(status: NetworkCallStatus) {
|
||||
//Display the selected day's event details for editing and such.
|
||||
let container = document.getElementById("events-container")!;
|
||||
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
for (let i = 0; i < status.body.events.length; i++) {
|
||||
let event = new Event().fromJson(status.body.events[i]);
|
||||
|
||||
//Create View Button
|
||||
let viewButton = document.createElement("button");
|
||||
viewButton.type = "button";
|
||||
viewButton.className =
|
||||
"btn bg-discord-blurple btn-discord btn-block " +
|
||||
"text-discord-full-white event-view-btn";
|
||||
viewButton.setAttribute("data-toggle", "modal");
|
||||
viewButton.setAttribute("data-target", "#modal-" + event.eventId);
|
||||
viewButton.innerHTML = "View " + event.summary;
|
||||
container.appendChild(viewButton);
|
||||
|
||||
container.appendChild(document.createElement("br"));
|
||||
container.appendChild(document.createElement("br"));
|
||||
|
||||
//Create modal container
|
||||
let modalContainer = document.createElement("div");
|
||||
modalContainer.className = "modal fade";
|
||||
modalContainer.id = "modal-" + event.eventId;
|
||||
// @ts-ignore
|
||||
modalContainer.role = "dialog";
|
||||
container.appendChild(modalContainer);
|
||||
|
||||
//Create modal-dialog
|
||||
let modalDia = document.createElement("div");
|
||||
modalDia.className = "modal-dialog";
|
||||
modalContainer.appendChild(modalDia);
|
||||
|
||||
//Create Modal Content
|
||||
let modalCon = document.createElement("div");
|
||||
modalCon.className = "modal-content bg-discal-not-black";
|
||||
modalDia.appendChild(modalCon);
|
||||
|
||||
//Create modal header and title
|
||||
let modalHeader = document.createElement("div");
|
||||
modalHeader.className = "modal-header bg-discal-not-black";
|
||||
modalCon.appendChild(modalHeader);
|
||||
let modalTitle = document.createElement("h4");
|
||||
modalTitle.className = "modal-title text-discord-blurple text-center";
|
||||
modalTitle.innerHTML = "Viewing Event";
|
||||
modalHeader.appendChild(modalTitle);
|
||||
|
||||
//Create Modal Body
|
||||
let modalBody = document.createElement("div");
|
||||
modalBody.className = "modal-body";
|
||||
modalCon.appendChild(modalBody);
|
||||
|
||||
let form = document.createElement("form");
|
||||
modalBody.appendChild(form);
|
||||
|
||||
//Summary
|
||||
let summaryLabel = document.createElement("label");
|
||||
summaryLabel.innerHTML = "Summary";
|
||||
summaryLabel.className = "text-discord-full-white";
|
||||
summaryLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(summaryLabel);
|
||||
let summary = document.createElement("input");
|
||||
summary.name = "summary";
|
||||
summary.type = "text";
|
||||
// noinspection JSDeprecatedSymbols
|
||||
summary.value = event.summary;
|
||||
summary.id = "editSummary-" + event.eventId;
|
||||
summary.readOnly = true;
|
||||
summaryLabel.appendChild(summary);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Description
|
||||
let descriptionLabel = document.createElement("label");
|
||||
descriptionLabel.innerHTML = "Description";
|
||||
descriptionLabel.className = "text-discord-full-white";
|
||||
descriptionLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(descriptionLabel);
|
||||
let description = document.createElement("input");
|
||||
description.name = "edit-description";
|
||||
description.type = "text";
|
||||
description.value = event.description;
|
||||
description.id = "editDescription-" + event.eventId;
|
||||
description.readOnly = true;
|
||||
descriptionLabel.appendChild(description);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Start date and time
|
||||
let sd = new Date(event.epochStart);
|
||||
let startLabel = document.createElement("label");
|
||||
startLabel.innerHTML = "Start Date and Time";
|
||||
startLabel.className = "text-discord-full-white";
|
||||
startLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(startLabel);
|
||||
let startDate = document.createElement("input");
|
||||
startDate.name = "start-date";
|
||||
startDate.type = "date";
|
||||
startDate.valueAsDate = sd;
|
||||
startDate.id = "editStartDate-" + event.eventId;
|
||||
startDate.readOnly = true;
|
||||
startLabel.appendChild(startDate);
|
||||
let startTime = document.createElement("input");
|
||||
startTime.name = "start-time";
|
||||
startTime.type = "time";
|
||||
startTime.value = (sd.getHours() < 10 ? "0" : "") + sd.getHours() + ":" + (sd.getMinutes() < 10 ? "0" : "") + sd.getMinutes();
|
||||
startTime.id = "editStartTime-" + event.eventId;
|
||||
startTime.readOnly = true;
|
||||
startLabel.appendChild(startTime);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//End date and time
|
||||
let ed = new Date(event.epochEnd);
|
||||
let endLabel = document.createElement("label");
|
||||
endLabel.innerHTML = "End Date and Time";
|
||||
endLabel.className = "text-discord-full-white";
|
||||
endLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(endLabel);
|
||||
let endDate = document.createElement("input");
|
||||
endDate.name = "end-date";
|
||||
endDate.type = "date";
|
||||
endDate.valueAsDate = ed;
|
||||
endDate.id = "editEndDate-" + event.eventId;
|
||||
endDate.readOnly = true;
|
||||
endLabel.appendChild(endDate);
|
||||
let endTime = document.createElement("input");
|
||||
endTime.name = "end-time";
|
||||
endTime.type = "time";
|
||||
endTime.value = (ed.getHours() < 10 ? "0" : "") + ed.getHours() + ":" + (ed.getMinutes() < 10 ? "0" : "") + ed.getMinutes();
|
||||
endTime.id = "editEndTime-" + event.eventId;
|
||||
endTime.readOnly = true;
|
||||
endLabel.appendChild(endTime);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Location
|
||||
let locationLabel = document.createElement("label");
|
||||
locationLabel.innerHTML = "Location";
|
||||
locationLabel.className = "text-discord-full-white";
|
||||
locationLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(locationLabel);
|
||||
let location = document.createElement("input");
|
||||
location.name = "location";
|
||||
location.type = "text";
|
||||
location.value = event.location;
|
||||
location.id = "editLocation-" + event.eventId;
|
||||
location.readOnly = true;
|
||||
locationLabel.appendChild(location);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Color
|
||||
let colorLabel = document.createElement("label");
|
||||
colorLabel.innerHTML = "Color";
|
||||
colorLabel.className = "text-discord-full-white";
|
||||
colorLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(colorLabel);
|
||||
let colorSelect = document.createElement("select");
|
||||
colorSelect.name = "color";
|
||||
colorSelect.id = "editColor-" + event.eventId;
|
||||
colorSelect.disabled = true;
|
||||
colorLabel.appendChild(colorSelect);
|
||||
|
||||
for (let ec in EventColor) {
|
||||
let option = document.createElement("option");
|
||||
option.value = EventColor[ec];
|
||||
option.text = EventColor[ec];
|
||||
option.selected = (EventColor[event.color] === EventColor[ec]);
|
||||
colorSelect.appendChild(option);
|
||||
}
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
if (event.doesRecur) {
|
||||
//Recurrence
|
||||
let recurrenceLabel = document.createElement("label");
|
||||
recurrenceLabel.innerHTML = "Recurrence";
|
||||
recurrenceLabel.className = "text-discord-full-white";
|
||||
recurrenceLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(recurrenceLabel);
|
||||
|
||||
if (event.isParent) {
|
||||
let enableRecurrence = document.createElement("input");
|
||||
enableRecurrence.name = "enable-recurrence";
|
||||
enableRecurrence.type = "checkbox";
|
||||
enableRecurrence.checked = false;
|
||||
enableRecurrence.readOnly = true;
|
||||
enableRecurrence.id = "editEnableRecur-" + event.eventId;
|
||||
recurrenceLabel.appendChild(enableRecurrence);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Frequency
|
||||
let frequencyLabel = document.createElement("label");
|
||||
frequencyLabel.innerHTML = "Recurrence - Frequency";
|
||||
frequencyLabel.className = "text-discord-full-white";
|
||||
frequencyLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(frequencyLabel);
|
||||
let freqSelect = document.createElement("select");
|
||||
freqSelect.name = "frequency";
|
||||
freqSelect.id = "editFrequency-" + event.eventId;
|
||||
frequencyLabel.appendChild(freqSelect);
|
||||
|
||||
for (let f in EventFrequency) {
|
||||
let op = document.createElement("option");
|
||||
op.value = EventFrequency[f];
|
||||
op.text = EventFrequency[f];
|
||||
op.selected = (EventFrequency[event.recurrence.frequency] === EventFrequency[f]);
|
||||
freqSelect.appendChild(op);
|
||||
}
|
||||
|
||||
freqSelect.disabled = true;
|
||||
frequencyLabel.appendChild(freqSelect);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Count
|
||||
let countLabel = document.createElement("label");
|
||||
countLabel.innerHTML = "Recurrence - Count";
|
||||
countLabel.className = "text-discord-full-white";
|
||||
countLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(countLabel);
|
||||
let count = document.createElement("input");
|
||||
count.name = "count";
|
||||
count.type = "number";
|
||||
count.valueAsNumber = event.recurrence.count;
|
||||
count.min = "-1";
|
||||
count.id = "editCount-" + event.eventId;
|
||||
count.readOnly = true;
|
||||
countLabel.appendChild(count);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Interval
|
||||
let intervalLabel = document.createElement("label");
|
||||
intervalLabel.innerHTML = "Recurrence - Interval";
|
||||
intervalLabel.className = "text-discord-full-white";
|
||||
intervalLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(intervalLabel);
|
||||
let interval = document.createElement("input");
|
||||
interval.name = "interval";
|
||||
interval.type = "number";
|
||||
interval.valueAsNumber = event.recurrence.interval;
|
||||
interval.min = "1";
|
||||
interval.id = "editInterval-" + event.eventId;
|
||||
interval.readOnly = true;
|
||||
intervalLabel.appendChild(interval);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
} else {
|
||||
//Cannot edit recurrence
|
||||
let cannotEditRecur = document.createElement("input");
|
||||
cannotEditRecur.name = "ignore-cer";
|
||||
cannotEditRecur.type = "text";
|
||||
cannotEditRecur.readOnly = true;
|
||||
cannotEditRecur.value = "Cannot edit child";
|
||||
recurrenceLabel.appendChild(cannotEditRecur);
|
||||
}
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
}
|
||||
|
||||
//Image
|
||||
let imageLabel = document.createElement("label");
|
||||
imageLabel.innerHTML = "Image";
|
||||
imageLabel.className = "text-discord-full-white";
|
||||
imageLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(imageLabel);
|
||||
let image = document.createElement("input");
|
||||
image.name = "image";
|
||||
image.type = "text";
|
||||
image.value = event.image;
|
||||
image.id = "editImage-" + event.eventId;
|
||||
image.readOnly = true;
|
||||
imageLabel.appendChild(image);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//ID (readonly) for API
|
||||
let idLabel = document.createElement("label");
|
||||
idLabel.innerHTML = "Event ID";
|
||||
idLabel.className = "text-discord-full-white";
|
||||
idLabel.appendChild(document.createElement("br"));
|
||||
form.appendChild(idLabel);
|
||||
let hiddenId = document.createElement("input");
|
||||
hiddenId.type = "text";
|
||||
hiddenId.name = "id";
|
||||
hiddenId.value = event.eventId;
|
||||
hiddenId.id = "editId-" + event.eventId;
|
||||
hiddenId.readOnly = true;
|
||||
idLabel.appendChild(hiddenId);
|
||||
form.appendChild(document.createElement("br"));
|
||||
form.appendChild(document.createElement("br"));
|
||||
|
||||
//Create modal footer
|
||||
let modalFooter = document.createElement("div");
|
||||
modalFooter.className = "modal-footer";
|
||||
modalCon.appendChild(modalFooter);
|
||||
|
||||
let closeButton = document.createElement("button");
|
||||
closeButton.type = "button";
|
||||
closeButton.className = "btn bg-discord-blurple btn-discord btn-block " +
|
||||
"text-discord-full-white";
|
||||
closeButton.setAttribute("data-dismiss", "modal");
|
||||
closeButton.innerHTML = "Close";
|
||||
modalFooter.appendChild(closeButton);
|
||||
//Oh my god finally done!!!
|
||||
}
|
||||
ElementUtil.showEventsContainer();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,31 @@
|
||||
import {EventColor} from "@/enums/EventColor";
|
||||
import {EventColor, eventColorRGB} from "@/enums/EventColor";
|
||||
import {Recurrence} from "@/objects/event/Recurrence";
|
||||
|
||||
export class Event {
|
||||
private _eventId: string = "";
|
||||
private _epochStart: number = 0;
|
||||
private _epochEnd: number = 0;
|
||||
private _eventId: string = "";
|
||||
private _epochStart: number = 0;
|
||||
private _epochEnd: number = 0;
|
||||
|
||||
private _summary: string = "";
|
||||
private _description: string = "";
|
||||
private _location: string = "";
|
||||
private _summary: string = "";
|
||||
private _description: string = "";
|
||||
private _location: string = "";
|
||||
|
||||
private _isParent: boolean = false;
|
||||
private _color: EventColor = EventColor.NONE;
|
||||
private _isParent: boolean = false;
|
||||
private _color: EventColor = EventColor.NONE;
|
||||
|
||||
private _recur: boolean = false;
|
||||
private _recurrence: Recurrence = new Recurrence();
|
||||
private _recur: boolean = false;
|
||||
private _recurrence: Recurrence = new Recurrence();
|
||||
private _rrule: String = "";
|
||||
|
||||
private _image: string = "";
|
||||
private _image: string = "";
|
||||
|
||||
constructor() {
|
||||
}
|
||||
constructor() {
|
||||
}
|
||||
|
||||
//Setter/getter pairs
|
||||
get eventId() {
|
||||
return this._eventId;
|
||||
}
|
||||
//Setter/getter pairs
|
||||
get eventId() {
|
||||
return this._eventId;
|
||||
}
|
||||
|
||||
set eventId(id) {
|
||||
this._eventId = id;
|
||||
@@ -102,6 +103,14 @@ export class Event {
|
||||
this._recurrence = rec;
|
||||
}
|
||||
|
||||
get rrule() {
|
||||
return this._rrule;
|
||||
}
|
||||
|
||||
set rrule(rr) {
|
||||
this._rrule = rr;
|
||||
}
|
||||
|
||||
get image() {
|
||||
return this._image;
|
||||
}
|
||||
@@ -112,6 +121,36 @@ export class Event {
|
||||
|
||||
|
||||
//Json conversion
|
||||
toFullCalEvent(editable: boolean) {
|
||||
let event: any = {
|
||||
id: this.eventId,
|
||||
groupId: this.eventId.split("_")[0],
|
||||
title: this.summary,
|
||||
description: this.description,
|
||||
location: this.location,
|
||||
image: this.image,
|
||||
eventColor: this.color,
|
||||
|
||||
start: this.epochStart,
|
||||
end: this.epochEnd,
|
||||
|
||||
overlap: true,
|
||||
editable: editable,
|
||||
|
||||
rawEvent: this,
|
||||
};
|
||||
|
||||
if (this.color != EventColor.NONE) {
|
||||
event.borderColor = eventColorRGB(this.color);
|
||||
}
|
||||
if (this.doesRecur) {
|
||||
event.rrule = this.rrule;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
toJson() {
|
||||
let json: any = {
|
||||
"event_id": this.eventId,
|
||||
@@ -132,6 +171,7 @@ export class Event {
|
||||
}
|
||||
if (this.doesRecur) {
|
||||
json.recurrence = this.recurrence.toJson();
|
||||
json.rrule = this.rrule
|
||||
}
|
||||
if (this.image.length > 0) {
|
||||
json.image = this.image;
|
||||
@@ -161,6 +201,7 @@ export class Event {
|
||||
this.doesRecur = json.recur;
|
||||
if (this.doesRecur) {
|
||||
this.recurrence = new Recurrence().fromJson(json.recurrence);
|
||||
this.rrule = json.rrule;
|
||||
}
|
||||
|
||||
if (json.hasOwnProperty("image")) {
|
||||
@@ -169,4 +210,4 @@ export class Event {
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
@import "variables";
|
||||
|
||||
.cal-date {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
.fc-toolbar-title {
|
||||
color: $discal-light-gray;
|
||||
}
|
||||
|
||||
.cal-date:hover {
|
||||
background-color: $discal-red;
|
||||
.fc-prev-button, .fc-today-button, .fc-next-button, .fc-viewGoogle-button, .fc-dayGridMonth-button,
|
||||
.fc-timeGridDay-button, .fc-timeGridWeek-button {
|
||||
background-color: $discal-blue !important;
|
||||
border-color: $discal-blue !important;
|
||||
|
||||
:active {
|
||||
background-color: $discal-red !important;
|
||||
border-color: $discal-red !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cal-date.today {
|
||||
background-color: $discord-blurple;
|
||||
.tippy-box[data-theme~='discal'] {
|
||||
background-color: $discal-light-gray;
|
||||
color: $discal-dark-gray;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.cal-date.selected {
|
||||
background-color: $discord-greyple;
|
||||
}
|
||||
|
||||
.cal-nav {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.event-view-btn {
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -51,25 +51,47 @@ $brand-google: #ea4335 !default;
|
||||
$brand-facebook: #3b5998 !default;
|
||||
$brand-discord: #7289da !default;
|
||||
|
||||
// Google colors
|
||||
$google-melrose: #A4BDFC !default;
|
||||
$google-riptide: #7AE7BF !default;
|
||||
$google-mauve: #DBADFF !default;
|
||||
$google-tangerine: #FF887C !default;
|
||||
$google-dandelion: #FBD75B !default;
|
||||
$google-mac_and_cheese: #FFB878 !default;
|
||||
$google-turquoise: #46D6DB !default;
|
||||
$google-mercury: #E1E1E1 !default;
|
||||
$google-blue: #5484ED !default;
|
||||
$google-green: #51B749 !default;
|
||||
$google-red: #DC2127 !default;
|
||||
|
||||
|
||||
$theme-colors: (
|
||||
// Discord Colors
|
||||
discord-blurple: #7289DA,
|
||||
discord-full-white: #FFFFFF,
|
||||
discord-greyple: #99AAB5,
|
||||
discord-dark-but-not-black: #2C2F33,
|
||||
discord-not-quite-black: #23272A,
|
||||
|
||||
// DisCal colors
|
||||
discal-blue: #5566c2,
|
||||
discal-red: #ef0813,
|
||||
discal-light-gray: #bcbcbc,
|
||||
discal-dark-gray: #3c3d41,
|
||||
discal-not-black: #242428,
|
||||
|
||||
// Brand colors
|
||||
brand-google: #ea4335,
|
||||
brand-facebook: #3b5998,
|
||||
brand-discord: #7289da,
|
||||
// Discord Colors
|
||||
discord-blurple: #7289DA,
|
||||
discord-full-white: #FFFFFF,
|
||||
discord-greyple: #99AAB5,
|
||||
discord-dark-but-not-black: #2C2F33,
|
||||
discord-not-quite-black: #23272A,
|
||||
// DisCal colors
|
||||
discal-blue: #5566c2,
|
||||
discal-red: #ef0813,
|
||||
discal-light-gray: #bcbcbc,
|
||||
discal-dark-gray: #3c3d41,
|
||||
discal-not-black: #242428,
|
||||
// Brand colors
|
||||
brand-google: #ea4335,
|
||||
brand-facebook: #3b5998,
|
||||
brand-discord: #7289da,
|
||||
// Google colors
|
||||
google-mauve: #DBADFF,
|
||||
google-tangerine: #FF887C,
|
||||
google-dandelion: #FBD75B,
|
||||
google-mac_and_cheese: #FFB878,
|
||||
google-turquoise: #46D6DB,
|
||||
google-mercury: #E1E1E1,
|
||||
google-blue: #5484ED,
|
||||
google-green: #51B749,
|
||||
google-red: #DC2127,
|
||||
);
|
||||
|
||||
// Set Contrast Threshold
|
||||
|
||||
+39
-18
@@ -1,24 +1,45 @@
|
||||
const path = require('path');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
|
||||
module.exports = {
|
||||
mode: "production",
|
||||
entry: './web/src/main/javascript/index.ts',
|
||||
devtool: "inline-source-map",
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
}],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.tsx', '.js'],
|
||||
alias: {
|
||||
'@': path.resolve('web/src/main/javascript')
|
||||
}
|
||||
},
|
||||
output: {
|
||||
mode: "production",
|
||||
entry: './web/src/main/javascript/index.ts',
|
||||
devtool: "inline-source-map",
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader
|
||||
},
|
||||
{
|
||||
loader: 'css-loader', options: {
|
||||
importLoaders: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.tsx', '.js'],
|
||||
alias: {
|
||||
'@': path.resolve('web/src/main/javascript')
|
||||
}
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, "web/src/main/html/static/assets/js"),
|
||||
filename: 'bundle.js'
|
||||
},
|
||||
};
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'main.css'
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user