diff --git a/app/http/endpoints/api/autoclose/autocloseget.go b/app/http/endpoints/api/autoclose/autocloseget.go index 16752e4..66a97e4 100644 --- a/app/http/endpoints/api/autoclose/autocloseget.go +++ b/app/http/endpoints/api/autoclose/autocloseget.go @@ -1,20 +1,67 @@ package api import ( - "github.com/TicketsBot/GoPanel/database" + dbclient "github.com/TicketsBot/GoPanel/database" + "github.com/TicketsBot/database" "github.com/gin-gonic/gin" + "time" ) +// time.Duration marshals to nanoseconds, custom impl to marshal to seconds +type autoCloseBody struct { + Enabled bool `json:"enabled"` + SinceOpenWithNoResponse int64 `json:"since_open_with_no_response"` + SinceLastMessage int64 `json:"since_last_message"` + OnUserLeave bool `json:"on_user_leave"` +} + func GetAutoClose(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) - settings, err := database.Client.AutoClose.Get(guildId); if err != nil { + settings, err := dbclient.Client.AutoClose.Get(guildId) + if err != nil { ctx.AbortWithStatusJSON(500, gin.H{ "success": false, - "error": err.Error(), + "error": err.Error(), }) return } - ctx.JSON(200, settings) + ctx.JSON(200, convertToAutoCloseBody(settings)) +} + +func convertToAutoCloseBody(settings database.AutoCloseSettings) (body autoCloseBody) { + body.Enabled = settings.Enabled + + if settings.SinceOpenWithNoResponse != nil { + body.SinceOpenWithNoResponse = int64(*settings.SinceOpenWithNoResponse / time.Second) + } + + if settings.SinceLastMessage != nil { + body.SinceLastMessage = int64(*settings.SinceLastMessage / time.Second) + } + + if settings.OnUserLeave != nil { + body.OnUserLeave = *settings.OnUserLeave + } + + return +} + +func convertFromAutoCloseBody(body autoCloseBody) (settings database.AutoCloseSettings) { + settings.Enabled = body.Enabled + + if body.SinceOpenWithNoResponse > 0 { + duration := time.Second * time.Duration(body.SinceOpenWithNoResponse) + settings.SinceOpenWithNoResponse = &duration + } + + if body.SinceLastMessage > 0 { + duration := time.Second * time.Duration(body.SinceLastMessage) + settings.SinceLastMessage = &duration + } + + settings.OnUserLeave = &body.OnUserLeave + + return } diff --git a/app/http/endpoints/api/autoclose/autoclosepost.go b/app/http/endpoints/api/autoclose/autoclosepost.go index c44c6db..ecd555b 100644 --- a/app/http/endpoints/api/autoclose/autoclosepost.go +++ b/app/http/endpoints/api/autoclose/autoclosepost.go @@ -1,36 +1,48 @@ package api import ( + "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" - "github.com/TicketsBot/database" + "github.com/TicketsBot/GoPanel/rpc" + "github.com/TicketsBot/GoPanel/utils" + "github.com/TicketsBot/common/premium" "github.com/gin-gonic/gin" + "time" ) +var maxDays = 90 +var maxLength = time.Hour * 24 * time.Duration(maxDays) + func PostAutoClose(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) - var settings database.AutoCloseSettings - if err := ctx.BindJSON(&settings); err != nil { - ctx.AbortWithStatusJSON(400, gin.H{ - "success": false, - "error": err.Error(), - }) + var body autoCloseBody + if err := ctx.BindJSON(&body); err != nil { + ctx.JSON(400, utils.ErrorJson(err)) return } - if settings.Enabled && (settings.SinceLastMessage == nil || settings.SinceOpenWithNoResponse == nil || settings.OnUserLeave == nil) { - ctx.AbortWithStatusJSON(400, gin.H{ - "success": false, - "error": "No time period provided", - }) + settings := convertFromAutoCloseBody(body) + + // get premium + botContext, err := botcontext.ContextForGuild(guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) return } - if (settings.SinceOpenWithNoResponse != nil && *settings.SinceOpenWithNoResponse < 0) || (settings.SinceLastMessage != nil && *settings.SinceLastMessage < 0) { - ctx.AbortWithStatusJSON(400, gin.H{ - "success": false, - "error": "Negative time period provided", - }) + premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, botContext.Token, botContext.RateLimiter) + + if premiumTier < premium.Premium { + settings.SinceOpenWithNoResponse = nil + settings.SinceLastMessage = nil + } + + // Time period cannot be negative, convertFromAutoCloseBody will not allow + + if (settings.SinceOpenWithNoResponse != nil && *settings.SinceOpenWithNoResponse > maxLength) || + (settings.SinceLastMessage != nil && *settings.SinceLastMessage > maxLength) { + ctx.JSON(400, utils.ErrorStr("Time period cannot be longer than %d days", maxDays)) return } @@ -41,14 +53,9 @@ func PostAutoClose(ctx *gin.Context) { } if err := dbclient.Client.AutoClose.Set(guildId, settings); err != nil { - ctx.AbortWithStatusJSON(500, gin.H{ - "success": false, - "error": err.Error(), - }) + ctx.JSON(500, utils.ErrorJson(err)) return } - ctx.JSON(200, gin.H{ - "success": true, - }) + ctx.JSON(200, utils.SuccessResponse) } diff --git a/frontend/src/components/form/Duration.svelte b/frontend/src/components/form/Duration.svelte new file mode 100644 index 0000000..c80e41d --- /dev/null +++ b/frontend/src/components/form/Duration.svelte @@ -0,0 +1,117 @@ +
+
+
+ + {#if badge !== undefined} +
{badge}
+ {/if} +
+
+ +
+
+ +
D
+
+ +
+ +
H
+
+ +
+ +
M
+
+
+
+ + + + \ No newline at end of file diff --git a/frontend/src/components/form/EmojiInput.svelte b/frontend/src/components/form/EmojiInput.svelte index 376bf7f..c272890 100644 --- a/frontend/src/components/form/EmojiInput.svelte +++ b/frontend/src/components/form/EmojiInput.svelte @@ -46,6 +46,7 @@ border-color: #2e3136 !important; border-left: none; color: white; + z-index: 2; } :global(.svelte-emoji-picker__trigger:active) { diff --git a/frontend/src/components/manage/AutoCloseCard.svelte b/frontend/src/components/manage/AutoCloseCard.svelte index fcf305a..42f265d 100644 --- a/frontend/src/components/manage/AutoCloseCard.svelte +++ b/frontend/src/components/manage/AutoCloseCard.svelte @@ -4,39 +4,117 @@
-
- - - This feature is currently disabled. Discord will soon be releasing message threads, - which will incorporate their own auto-close behaviour. Thank you for your patience. - - -
+
+
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
diff --git a/frontend/src/js/timeutil.js b/frontend/src/js/timeutil.js new file mode 100644 index 0000000..d1222ab --- /dev/null +++ b/frontend/src/js/timeutil.js @@ -0,0 +1,11 @@ +export function toDays(value) { + return Math.floor(value / 86400); +} + +export function toHours(value) { + return Math.floor((value % 86400) / 3600); +} + +export function toMinutes(value) { + return Math.floor((value % 86400 % 3600) / 60); +} \ No newline at end of file diff --git a/frontend/src/views/Panels.svelte b/frontend/src/views/Panels.svelte index 38d8fce..9432483 100644 --- a/frontend/src/views/Panels.svelte +++ b/frontend/src/views/Panels.svelte @@ -258,7 +258,8 @@ return; } - panels = res.data; + // convert button_style to string + panels = res.data.map((p) => Object.assign({}, p, {button_style: p.button_style.toString()})); } async function loadMultiPanels() { diff --git a/frontend/src/views/Settings.svelte b/frontend/src/views/Settings.svelte index 3167112..90abcdb 100644 --- a/frontend/src/views/Settings.svelte +++ b/frontend/src/views/Settings.svelte @@ -1,15 +1,15 @@
- +
- +
- +