Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions app/http/endpoints/api/panel/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ func DefaultApplicators(data *panelBody) []defaults.DefaultApplicator {
defaults.NewDefaultApplicator(defaults.EmptyStringCheck, &data.Content, "By clicking the button, a ticket will be opened for you."),
defaults.NewDefaultApplicator[*string](defaults.NilOrEmptyStringCheck, &data.ImageUrl, nil),
defaults.NewDefaultApplicator[*string](defaults.NilOrEmptyStringCheck, &data.ThumbnailUrl, nil),
defaults.NewDefaultApplicator(defaults.EmptyStringCheck, &data.ButtonLabel, data.Title),
defaults.NewDefaultApplicator(defaults.EmptyStringCheck, &data.ButtonLabel, "Open a ticket!"), // Title could have been blank
defaults.NewDefaultApplicator[*string](defaults.NilOrEmptyStringCheck, &data.NamingScheme, nil),
}
}
Expand Down Expand Up @@ -68,6 +66,7 @@ func panelValidators() []validation.Validator[PanelValidationContext] {
validateThumbnailUrl,
validateButtonStyle,
validateButtonLabel,
validateButtonLabelOrEmoji,
validateFormId,
validateExitSurveyFormId,
validateTeams,
Expand Down Expand Up @@ -126,6 +125,11 @@ func validateEmoji(c PanelValidationContext) validation.ValidationFunc {
return func() error {
emoji := c.Data.Emoji

// If no emoji is provided (empty name), skip validation
if len(emoji.Name) == 0 && !emoji.IsCustomEmoji {
return nil
}

if emoji.IsCustomEmoji {
if emoji.Id == nil {
return validation.NewInvalidInputError("Custom emoji was missing ID")
Expand All @@ -147,10 +151,6 @@ func validateEmoji(c PanelValidationContext) validation.ValidationFunc {
return validation.NewInvalidInputError("Emoji name mismatch")
}
} else {
if len(emoji.Name) == 0 {
return validation.NewInvalidInputError("Emoji name was empty")
}

// Convert from :emoji: to unicode if we need to
name := strings.TrimSpace(emoji.Name)
name = strings.Replace(name, ":", "", -1)
Expand Down Expand Up @@ -207,6 +207,19 @@ func validateButtonLabel(ctx PanelValidationContext) validation.ValidationFunc {
}
}

func validateButtonLabelOrEmoji(ctx PanelValidationContext) validation.ValidationFunc {
return func() error {
hasLabel := len(strings.TrimSpace(ctx.Data.ButtonLabel)) > 0
hasEmoji := len(strings.TrimSpace(ctx.Data.Emoji.Name)) > 0

if !hasLabel && !hasEmoji {
return validation.NewInvalidInputError("Button must have at least one of label or emoji")
}

return nil
}
}

func validatedNullableFormId(guildId uint64, formId *int) validation.ValidationFunc {
return func() error {
if formId == nil {
Expand Down
16 changes: 9 additions & 7 deletions frontend/src/components/manage/PanelCreationForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
// Unicode emoji regex
const unicodeEmojiRegex = /^\p{Emoji}$/u;
function validateUnicodeEmoji(value) {
if (value === "") return true;
if (typeof value !== "string") return false;
if (/^<a?:\w+:\d+>$/.test(value)) return false;
// Disallow spaces
Expand Down Expand Up @@ -105,12 +106,12 @@
data.emote = emojis && emojis.length > 0 ? emojis[0] : undefined;
}
} else {
// Save the current custom emoji before switching to default
// Save the current custom emoji before switching to unicode
if (data.emote && typeof data.emote === "object") {
lastCustomEmoji = data.emote;
}
// Restore last unicode emoji if available
data.emote = lastUnicodeEmoji || '📩';
// Restore last unicode emoji
data.emote = lastUnicodeEmoji;
}
}

Expand Down Expand Up @@ -211,6 +212,7 @@
default_team: true,
teams: [],
button_style: "1",
button_label: "Open a ticket!",
form_id: "null",
delete_mentions: false,
disabled: false,
Expand Down Expand Up @@ -449,9 +451,9 @@
/>

<div class="col-2" style="z-index: 1">
<label for="emoji-pick-wrapper" class="form-label"
>Button Emoji</label
>
<label for="emoji-pick-wrapper" class="form-label">
Button Emoji
</label>
<div id="emoji-pick-wrapper" class="row" style="gap: 2%">
<div class="col">
<label
Expand Down Expand Up @@ -481,7 +483,7 @@
/>
</div>
{:else}
<EmojiInput col1="true" bind:value={data.emote} />
<EmojiInput col1="true" placeholder="Button Emoji" bind:value={data.emote} />
{/if}
</div>
</div>
Expand Down
6 changes: 5 additions & 1 deletion utils/types/emoji.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ func (e *Emoji) UnmarshalJSON(data []byte) error {
return err
}

// Allow null emoji (no emoji provided)
if raw == nil {
return fmt.Errorf("emoji data was nil")
e.IsCustomEmoji = false
e.Name = ""
e.Id = nil
return nil
}

switch v := raw.(type) {
Expand Down