This commit is contained in:
rxdn 2022-06-16 15:53:09 +01:00
parent 094f8a3fb3
commit 01eca061ce
8 changed files with 193 additions and 16 deletions

View File

@ -0,0 +1,25 @@
package api
import (
"github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/utils"
"github.com/gin-gonic/gin"
)
func EmojisHandler(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.JSON(500, utils.ErrorJson(err))
return
}
emojis, err := botContext.GetGuildEmojis(guildId)
if err != nil {
ctx.JSON(500, utils.ErrorJson(err))
return
}
ctx.JSON(200, emojis)
}

View File

@ -75,6 +75,7 @@ func StartServer() {
guildAuthApiSupport.GET("/premium", api.PremiumHandler)
guildAuthApiSupport.GET("/user/:user", api.UserHandler)
guildAuthApiSupport.GET("/roles", api.RolesHandler)
guildAuthApiSupport.GET("/emojis", rl(middleware.RateLimitTypeGuild, 5, time.Second*30), api.EmojisHandler)
guildAuthApiSupport.GET("/members/search",
rl(middleware.RateLimitTypeGuild, 5, time.Second),
rl(middleware.RateLimitTypeGuild, 10, time.Second*30),

View File

@ -9,6 +9,7 @@ import (
"github.com/TicketsBot/database"
"github.com/rxdn/gdl/objects/channel"
"github.com/rxdn/gdl/objects/guild"
"github.com/rxdn/gdl/objects/guild/emoji"
"github.com/rxdn/gdl/objects/member"
"github.com/rxdn/gdl/objects/user"
"github.com/rxdn/gdl/rest"
@ -100,6 +101,19 @@ func (ctx BotContext) GetGuildRoles(guildId uint64) (roles []guild.Role, err err
return
}
func (ctx BotContext) GetGuildEmojis(guildId uint64) (emojis []emoji.Emoji, err error) {
if emojis := cache.Instance.GetGuildEmojis(guildId); len(emojis) > 0 {
return emojis, nil
}
emojis, err = rest.ListGuildEmojis(ctx.Token, ctx.RateLimiter, guildId)
if err == nil {
go cache.Instance.StoreEmojis(emojis, guildId)
}
return
}
func (ctx BotContext) SearchMembers(guildId uint64, query string) (members []member.Member, err error) {
data := rest.SearchGuildMembersData{
Query: query,

View File

@ -0,0 +1,97 @@
<script>
export let isActive = false;
export let isFirst = false;
export let isHover = false;
export let isSelectable = false;
export let getOptionLabel = undefined;
export let item = undefined;
export let filterText = '';
let itemClasses = '';
$: {
const classes = [];
if (isActive) {
classes.push('active');
}
if (isFirst) {
classes.push('first');
}
if (isHover) {
classes.push('hover');
}
if (item.isGroupHeader) {
classes.push('groupHeader');
}
if (item.isGroupItem) {
classes.push('groupItem');
}
if (!isSelectable) {
classes.push('notSelectable');
}
itemClasses = classes.join(' ');
}
</script>
<style>
.item {
cursor: default;
height: var(--height, 42px);
line-height: var(--height, 42px);
padding: var(--itemPadding, 0 20px);
color: var(--itemColor, inherit);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: flex;
flex-direction: row;
align-items: center;
}
.groupHeader {
text-transform: var(--groupTitleTextTransform, uppercase);
}
.groupItem {
padding-left: var(--groupItemPaddingLeft, 40px);
}
/*
.item:active {
background: var(--itemActiveBackground, #b9daff);
}
.item.active {
background: var(--itemIsActiveBG, #007aff);
color: var(--itemIsActiveColor, #fff);
}
*/
.item.notSelectable {
color: var(--itemIsNotSelectableColor, #999);
}
.item.first {
border-radius: var(--itemFirstBorderRadius, 4px 4px 0 0);
}
.item.hover:not(.active) {
background: var(--itemHoverBG, #e7f2ff);
color: var(--itemHoverColor, inherit);
}
.icon {
width: 32px;
height: 32px;
}
.name {
padding-left: 5px;
}
</style>
<div class="item {itemClasses}">
<img class="icon" src={`https://cdn.discordapp.com/emojis/${item.id}.png`} alt={item.name} />
<span class="name">:{item.name}:</span>
</div>

View File

@ -1,5 +1,7 @@
<div class:col-1={col1} class:col-2={col2} class:col-3={col3} class:col-4={col4}>
<label for="input" class="form-label">{label}</label>
{#if label !== undefined}
<label class="form-label">{label}</label>
{/if}
<div class="wrapper">
<input id="input" class="form-input" placeholder="{placeholder}" disabled="{disabled}" bind:value={value}>
{#if !disabled}

View File

@ -1,6 +1,6 @@
{#if label !== undefined}
`{#if label !== undefined}
<label class="form-label">{label}</label>
{/if}
{/if}`
<div class="multiselect-super">
<Select placeholder="Search..." optionIdentifier="id" items={roles}

View File

@ -12,26 +12,46 @@
<Colour col4=true label="Panel Colour" on:change={updateColour} bind:value={tempColour}/>
<ChannelDropdown label="Panel Channel" col4=true {channels} bind:value={data.channel_id}/>
<CategoryDropdown label="Ticket Category" col4=true {channels} bind:value={data.category_id}/>
<div class="col-4" style="z-index: 1">
<EmojiInput label="Button Emoji" col1=true bind:value={data.emote}/>
</div>
<Dropdown col4=true label="Form" bind:value={data.form_id}>
<option value=null>None</option>
{#each forms as form}
<option value={form.form_id}>{form.title}</option>
{/each}
</Dropdown>
</div>
<div class="row">
<Dropdown col3=true label="Button Style" bind:value={data.button_style}>
<Dropdown col4=true label="Button Style" bind:value={data.button_style}>
<option value="1">Blue</option>
<option value="2">Grey</option>
<option value="3">Green</option>
<option value="4">Red</option>
</Dropdown>
<Input col3={true} label="Button Text" placeholder="Open a ticket!" bind:value={data.button_label} />
<Input col4={true} label="Button Text" placeholder="Open a ticket!" bind:value={data.button_label} />
<Dropdown col3=true label="Form" bind:value={data.form_id}>
<option value=null>None</option>
{#each forms as form}
<option value={form.form_id}>{form.title}</option>
{/each}
</Dropdown>
<div class="col-2" style="z-index: 1">
<label for="emoji-pick-wrapper" class="form-label">Button Emoji</label>
<div id="emoji-pick-wrapper" class="row">
<div class="col-2">
<label for="use-custom-emoji" class="form-label">Custom Emoji</label>
<input id="use-custom-emoji" class="form-checkbox" type=checkbox bind:checked={data.use_custom_emoji} on:change={() => console.log('a')}>
</div>
{#if data.use_custom_emoji}
<!--bind:selectedValue={selectedMentions}
on:select={updateMentions}-->
<div class="multiselect-super">
<Select items={emojis}
Item={EmojiItem}
optionIdentifier="id"
getSelectionLabel={emojiNameMapper}
getOptionLabel={emojiNameMapper}
placeholderAlwaysShow={true} />
</div>
{:else}
<EmojiInput col1=true bind:value={data.emote}/>
{/if}
</div>
</div>
</div>
<div class="row" style="justify-content: center">
<div class="col-3">
@ -70,7 +90,7 @@
on:select={updateTeams}
isSearchable={false}
optionIdentifier="id"
getSelectionLabel={nameMapper}
getSelectionLabel={emojiNameMapper}
getOptionLabel={nameMapper}
isMulti={true} />
</div>
@ -95,8 +115,10 @@
import {colourToInt, intToColour} from "../../js/util";
import CategoryDropdown from "../CategoryDropdown.svelte";
import EmojiInput from "../form/EmojiInput.svelte";
import EmojiItem from "../EmojiItem.svelte";
import Select from 'svelte-select';
import Dropdown from "../form/Dropdown.svelte";
import Checkbox from "../form/Checkbox.svelte";
export let guildId;
export let seedDefault = true;
@ -109,6 +131,7 @@
export let channels = [];
export let roles = [];
export let emojis = [];
export let teams = [];
export let forms = [];
@ -144,6 +167,7 @@
}
const nameMapper = (team) => team.name;
const emojiNameMapper = (emoji) => `:${emoji.name}:`;
function mentionNameMapper(role) {
if (role.id === "user") {

View File

@ -16,6 +16,8 @@
<div slot="body" class="card-body">
<p>Your panel quota: <b>{panels.length} / {isPremium ? '∞' : '3'}</b></p>
<img src="https://cdn.discordapp.com/emojis/986995010136318022.png" />
<table style="margin-top: 10px">
<thead>
<tr>
@ -55,7 +57,7 @@
<div slot="body" class="body-wrapper">
{#if !$loadingScreen}
<PanelCreationForm {guildId} {channels} {roles} {teams} {forms} bind:data={panelCreateData}/>
<PanelCreationForm {guildId} {channels} {roles} {emojis} {teams} {forms} bind:data={panelCreateData}/>
<div style="display: flex; justify-content: center">
<div class="col-3">
<Button icon="fas fa-paper-plane" fullWidth={true} on:click={createPanel}>Submit</Button>
@ -142,6 +144,7 @@
let channels = [];
let roles = [];
let emojis = [];
let teams = [];
let forms = [];
let panels = [];
@ -332,6 +335,16 @@
roles = res.data.roles;
}
async function loadEmojis() {
const res = await axios.get(`${API_URL}/api/${guildId}/emojis`);
if (res.status !== 200) {
notifyError(res.data.error);
return;
}
emojis = res.data;
}
async function loadForms() {
const res = await axios.get(`${API_URL}/api/${guildId}/forms`);
if (res.status !== 200) {
@ -349,6 +362,7 @@
loadTeams(),
loadForms(),
loadRoles(),
loadEmojis(),
loadPanels(),
loadMultiPanels()
]);