Colour customisation
This commit is contained in:
parent
5dc3cfa8b3
commit
677f405826
33
app/http/endpoints/api/customisation/getcolours.go
Normal file
33
app/http/endpoints/api/customisation/getcolours.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package customisation
|
||||||
|
|
||||||
|
import (
|
||||||
|
dbclient "github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
|
"github.com/TicketsBot/worker/bot/customisation"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetColours TODO: Don't depend on worker
|
||||||
|
func GetColours(ctx *gin.Context) {
|
||||||
|
guildId := ctx.Keys["guildid"].(uint64)
|
||||||
|
|
||||||
|
// TODO: Don't duplicate
|
||||||
|
raw, err := dbclient.Client.CustomColours.GetAll(guildId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, utils.ErrorJson(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
colours := make(map[customisation.Colour]utils.HexColour)
|
||||||
|
for id, hex := range raw {
|
||||||
|
colours[customisation.Colour(id)] = utils.HexColour(hex)
|
||||||
|
}
|
||||||
|
|
||||||
|
for id, hex := range customisation.DefaultColours {
|
||||||
|
if _, ok := colours[id]; !ok {
|
||||||
|
colours[id] = utils.HexColour(hex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, colours)
|
||||||
|
}
|
54
app/http/endpoints/api/customisation/updatecolours.go
Normal file
54
app/http/endpoints/api/customisation/updatecolours.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package customisation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
dbclient "github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
|
"github.com/TicketsBot/worker/bot/customisation"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateColours TODO: Don't depend on worker
|
||||||
|
func UpdateColours(ctx *gin.Context) {
|
||||||
|
guildId := ctx.Keys["guildid"].(uint64)
|
||||||
|
|
||||||
|
var data map[customisation.Colour]utils.HexColour
|
||||||
|
if err := ctx.BindJSON(&data); err != nil {
|
||||||
|
ctx.JSON(400, utils.ErrorJson(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) > len(customisation.DefaultColours) {
|
||||||
|
ctx.JSON(400, utils.ErrorStr("Invalid colour"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for colourCode, hex := range customisation.DefaultColours {
|
||||||
|
if _, ok := data[colourCode]; !ok {
|
||||||
|
data[colourCode] = utils.HexColour(hex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Single query
|
||||||
|
group, _ := errgroup.WithContext(context.Background())
|
||||||
|
for colourCode, hex := range data {
|
||||||
|
colourCode := colourCode
|
||||||
|
hex := hex
|
||||||
|
|
||||||
|
fmt.Printf("%d: %d\n", colourCode, hex)
|
||||||
|
|
||||||
|
group.Go(func() error {
|
||||||
|
fmt.Printf("%d: %d\n", colourCode, hex.Int())
|
||||||
|
return dbclient.Client.CustomColours.Set(guildId, colourCode.Int16(), hex.Int())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := group.Wait(); err != nil {
|
||||||
|
ctx.JSON(500, utils.ErrorJson(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, utils.SuccessResponse)
|
||||||
|
}
|
@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/TicketsBot/GoPanel/app/http/endpoints/api"
|
"github.com/TicketsBot/GoPanel/app/http/endpoints/api"
|
||||||
api_autoclose "github.com/TicketsBot/GoPanel/app/http/endpoints/api/autoclose"
|
api_autoclose "github.com/TicketsBot/GoPanel/app/http/endpoints/api/autoclose"
|
||||||
api_blacklist "github.com/TicketsBot/GoPanel/app/http/endpoints/api/blacklist"
|
api_blacklist "github.com/TicketsBot/GoPanel/app/http/endpoints/api/blacklist"
|
||||||
|
api_customisation "github.com/TicketsBot/GoPanel/app/http/endpoints/api/customisation"
|
||||||
api_panels "github.com/TicketsBot/GoPanel/app/http/endpoints/api/panel"
|
api_panels "github.com/TicketsBot/GoPanel/app/http/endpoints/api/panel"
|
||||||
api_settings "github.com/TicketsBot/GoPanel/app/http/endpoints/api/settings"
|
api_settings "github.com/TicketsBot/GoPanel/app/http/endpoints/api/settings"
|
||||||
api_tags "github.com/TicketsBot/GoPanel/app/http/endpoints/api/tags"
|
api_tags "github.com/TicketsBot/GoPanel/app/http/endpoints/api/tags"
|
||||||
@ -127,6 +128,9 @@ func StartServer() {
|
|||||||
guildAuthApiAdmin.GET("/autoclose", api_autoclose.GetAutoClose)
|
guildAuthApiAdmin.GET("/autoclose", api_autoclose.GetAutoClose)
|
||||||
guildAuthApiAdmin.POST("/autoclose", api_autoclose.PostAutoClose)
|
guildAuthApiAdmin.POST("/autoclose", api_autoclose.PostAutoClose)
|
||||||
|
|
||||||
|
guildAuthApiAdmin.GET("/customisation/colours", api_customisation.GetColours)
|
||||||
|
guildAuthApiAdmin.POST("/customisation/colours", api_customisation.UpdateColours)
|
||||||
|
|
||||||
guildAuthApiAdmin.GET("/team", api_team.GetTeams)
|
guildAuthApiAdmin.GET("/team", api_team.GetTeams)
|
||||||
guildAuthApiAdmin.GET("/team/:teamid", rl(middleware.RateLimitTypeUser, 10, time.Second*30), api_team.GetMembers)
|
guildAuthApiAdmin.GET("/team/:teamid", rl(middleware.RateLimitTypeUser, 10, time.Second*30), api_team.GetMembers)
|
||||||
guildAuthApiAdmin.POST("/team", rl(middleware.RateLimitTypeUser, 10, time.Minute), api_team.CreateTeam)
|
guildAuthApiAdmin.POST("/team", rl(middleware.RateLimitTypeUser, 10, time.Minute), api_team.CreateTeam)
|
||||||
|
16
frontend/src/components/Badge.svelte
Normal file
16
frontend/src/components/Badge.svelte
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<div class="badge">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.badge {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
background-color: #3472f7;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,7 +3,7 @@
|
|||||||
<div class="parent">
|
<div class="parent">
|
||||||
<label class="form-label">{label}</label>
|
<label class="form-label">{label}</label>
|
||||||
{#if badge !== undefined}
|
{#if badge !== undefined}
|
||||||
<div class="badge" style="margin-left: 4px">{badge}</div>
|
<Badge>{badge}</Badge>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -27,6 +27,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Badge from "../Badge.svelte";
|
||||||
|
|
||||||
export let label;
|
export let label;
|
||||||
export let badge;
|
export let badge;
|
||||||
export let disabled = false; // note: bind:disabled isn't valid
|
export let disabled = false; // note: bind:disabled isn't valid
|
||||||
@ -104,14 +106,4 @@
|
|||||||
margin: 0 0 0.5em 0;
|
margin: 0 0 0.5em 0;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.badge) {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
background-color: #3472f7;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 0 4px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
@ -13,6 +13,7 @@
|
|||||||
<NavElement icon="fas fa-ticket-alt" link="/manage/{guildId}/tickets" on:click={closeDropdown}>Tickets</NavElement>
|
<NavElement icon="fas fa-ticket-alt" link="/manage/{guildId}/tickets" on:click={closeDropdown}>Tickets</NavElement>
|
||||||
<NavElement icon="fas fa-ban" link="/manage/{guildId}/blacklist" on:click={closeDropdown}>Blacklist</NavElement>
|
<NavElement icon="fas fa-ban" link="/manage/{guildId}/blacklist" on:click={closeDropdown}>Blacklist</NavElement>
|
||||||
<NavElement icon="fas fa-tags" link="/manage/{guildId}/tags" on:click={closeDropdown}>Tags</NavElement>
|
<NavElement icon="fas fa-tags" link="/manage/{guildId}/tags" on:click={closeDropdown}>Tags</NavElement>
|
||||||
|
<NavElement icon="fas fa-paint-brush" link="/manage/{guildId}/appearance" on:click={closeDropdown}>Customise Appearance</NavElement>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -64,7 +65,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 950px) {
|
@media only screen and (max-width: 1154px) {
|
||||||
.nav-section {
|
.nav-section {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import Tags from './views/Tags.svelte'
|
|||||||
import Teams from './views/Teams.svelte'
|
import Teams from './views/Teams.svelte'
|
||||||
import Tickets from './views/Tickets.svelte'
|
import Tickets from './views/Tickets.svelte'
|
||||||
import TicketView from './views/TicketView.svelte'
|
import TicketView from './views/TicketView.svelte'
|
||||||
|
import Appearance from './views/Appearance.svelte';
|
||||||
|
|
||||||
export const routes = [
|
export const routes = [
|
||||||
{name: '/', component: Index, layout: IndexLayout},
|
{name: '/', component: Index, layout: IndexLayout},
|
||||||
@ -33,6 +34,7 @@ export const routes = [
|
|||||||
nestedRoutes: [
|
nestedRoutes: [
|
||||||
{name: 'index', component: Error404, layout: ErrorLayout},
|
{name: 'index', component: Error404, layout: ErrorLayout},
|
||||||
{name: 'settings', component: Settings, layout: ManageLayout},
|
{name: 'settings', component: Settings, layout: ManageLayout},
|
||||||
|
{name: 'appearance', component: Appearance, layout: ManageLayout},
|
||||||
{
|
{
|
||||||
name: 'transcripts',
|
name: 'transcripts',
|
||||||
nestedRoutes: [
|
nestedRoutes: [
|
||||||
|
116
frontend/src/views/Appearance.svelte
Normal file
116
frontend/src/views/Appearance.svelte
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<div class="parent">
|
||||||
|
<div class="content">
|
||||||
|
<Card footer={false}>
|
||||||
|
<span slot="title">Looking for whitelabel?</span>
|
||||||
|
<div slot="body" class="body-wrapper">
|
||||||
|
<p>If you're looking for whitelabel settings (customising bot name and avatar), this is managed on a separate
|
||||||
|
page, <Navigate to="/whitelabel" styles="link row">available here</Navigate>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card footer={false}>
|
||||||
|
<span slot="title">Colour Scheme</span>
|
||||||
|
<div slot="body" class="body-wrapper">
|
||||||
|
<form class="settings-form" on:submit|preventDefault={updateColours}>
|
||||||
|
<div class="row">
|
||||||
|
<Colour col3={true} label="Success" bind:value={colours["0"]} />
|
||||||
|
<Colour col3={true} label="Failure" bind:value={colours["1"]} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<Button icon="fas fa-paper-plane">Submit</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Card from "../components/Card.svelte";
|
||||||
|
import {notifyError, notifySuccess, withLoadingScreen} from '../js/util'
|
||||||
|
import axios from "axios";
|
||||||
|
import {API_URL} from "../js/constants";
|
||||||
|
import {setDefaultHeaders} from '../includes/Auth.svelte'
|
||||||
|
import {Navigate} from "svelte-router-spa";
|
||||||
|
import Colour from "../components/form/Colour.svelte";
|
||||||
|
import Button from "../components/Button.svelte";
|
||||||
|
|
||||||
|
export let currentRoute;
|
||||||
|
let guildId = currentRoute.namedParams.id;
|
||||||
|
|
||||||
|
let colours = {};
|
||||||
|
|
||||||
|
async function updateColours() {
|
||||||
|
const res = await axios.post(`${API_URL}/api/${guildId}/customisation/colours`, colours);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
notifyError(res.data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifySuccess(`Your colour scheme has been saved`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadColours() {
|
||||||
|
const res = await axios.get(`${API_URL}/api/${guildId}/customisation/colours`);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
notifyError(res.data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
colours = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
withLoadingScreen(async () => {
|
||||||
|
setDefaultHeaders();
|
||||||
|
await loadColours();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.parent {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 96%;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 950px) {
|
||||||
|
.row {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
4
go.mod
4
go.mod
@ -6,8 +6,8 @@ require (
|
|||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/TicketsBot/archiverclient v0.0.0-20210220155137-a562b2f1bbbb
|
github.com/TicketsBot/archiverclient v0.0.0-20210220155137-a562b2f1bbbb
|
||||||
github.com/TicketsBot/common v0.0.0-20210910205523-7ce93fba6fa5
|
github.com/TicketsBot/common v0.0.0-20210910205523-7ce93fba6fa5
|
||||||
github.com/TicketsBot/database v0.0.0-20211102194216-65aaa0ce6ce9
|
github.com/TicketsBot/database v0.0.0-20211109153802-24100e383d78
|
||||||
github.com/TicketsBot/worker v0.0.0-20211102194549-f7058a7791fa
|
github.com/TicketsBot/worker v0.0.0-20211108224403-97ac8e44b789
|
||||||
github.com/apex/log v1.1.2
|
github.com/apex/log v1.1.2
|
||||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
|
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
|
||||||
github.com/getsentry/sentry-go v0.11.0
|
github.com/getsentry/sentry-go v0.11.0
|
||||||
|
20
go.sum
20
go.sum
@ -13,20 +13,15 @@ github.com/TicketsBot/common v0.0.0-20210910205523-7ce93fba6fa5 h1:IfNrgUB35hs+M
|
|||||||
github.com/TicketsBot/common v0.0.0-20210910205523-7ce93fba6fa5/go.mod h1:SVwX6gKkxRCMbp+qwJIgvQiy/Ut0fUddexEqRB/NTzc=
|
github.com/TicketsBot/common v0.0.0-20210910205523-7ce93fba6fa5/go.mod h1:SVwX6gKkxRCMbp+qwJIgvQiy/Ut0fUddexEqRB/NTzc=
|
||||||
github.com/TicketsBot/database v0.0.0-20200516170158-fd8a949aec2c/go.mod h1:eky4tBL+IZ0svPgTT0N/9i6j7ygHDQH3784DW+HgfcA=
|
github.com/TicketsBot/database v0.0.0-20200516170158-fd8a949aec2c/go.mod h1:eky4tBL+IZ0svPgTT0N/9i6j7ygHDQH3784DW+HgfcA=
|
||||||
github.com/TicketsBot/database v0.0.0-20210902172951-4e1f8ced84b7/go.mod h1:A4T2uQFIWC/ttCYpfgv7AkPjR09mMRgzG13lgoV/+aI=
|
github.com/TicketsBot/database v0.0.0-20210902172951-4e1f8ced84b7/go.mod h1:A4T2uQFIWC/ttCYpfgv7AkPjR09mMRgzG13lgoV/+aI=
|
||||||
github.com/TicketsBot/database v0.0.0-20210906215136-2d0c54bd1109/go.mod h1:A4T2uQFIWC/ttCYpfgv7AkPjR09mMRgzG13lgoV/+aI=
|
github.com/TicketsBot/database v0.0.0-20211108142700-c406ab0fc1bb h1:hDN153ofF4rmAnA9Rs/j3b/+xazi3QFzQqXSJ6HNgZI=
|
||||||
github.com/TicketsBot/database v0.0.0-20211030123522-eeed94443867 h1:2tYF3avpUUY1voXuzcY2gQHggnk17M+1btblS7Zkygk=
|
github.com/TicketsBot/database v0.0.0-20211108142700-c406ab0fc1bb/go.mod h1:72oWvH/Gq1iKeXCZhVRZn1JFbNVC5iAgERZWTrEarEo=
|
||||||
github.com/TicketsBot/database v0.0.0-20211030123522-eeed94443867/go.mod h1:72oWvH/Gq1iKeXCZhVRZn1JFbNVC5iAgERZWTrEarEo=
|
github.com/TicketsBot/database v0.0.0-20211109153802-24100e383d78 h1:zzjOyxCdXN1fGDL2Na6Q82EDU96Cfd1vnlafeY1utUQ=
|
||||||
github.com/TicketsBot/database v0.0.0-20211030133445-3b8906e1b64a h1:nn8rmdIXR4jY3JsE+pyf6Ff0LOAYvHjx8F8E+InWaRk=
|
github.com/TicketsBot/database v0.0.0-20211109153802-24100e383d78/go.mod h1:72oWvH/Gq1iKeXCZhVRZn1JFbNVC5iAgERZWTrEarEo=
|
||||||
github.com/TicketsBot/database v0.0.0-20211030133445-3b8906e1b64a/go.mod h1:72oWvH/Gq1iKeXCZhVRZn1JFbNVC5iAgERZWTrEarEo=
|
|
||||||
github.com/TicketsBot/database v0.0.0-20211102194216-65aaa0ce6ce9 h1:x4xs4IynlfDwpPTTcVbYjt5h1VmL9AeUW9ZFY31dyP0=
|
|
||||||
github.com/TicketsBot/database v0.0.0-20211102194216-65aaa0ce6ce9/go.mod h1:72oWvH/Gq1iKeXCZhVRZn1JFbNVC5iAgERZWTrEarEo=
|
|
||||||
github.com/TicketsBot/logarchiver v0.0.0-20200423221245-a3f92edf8c14/go.mod h1:whts8TRxrAF4WuDuEAMllkWA/inKem0NhDEFeyuoOvE=
|
github.com/TicketsBot/logarchiver v0.0.0-20200423221245-a3f92edf8c14/go.mod h1:whts8TRxrAF4WuDuEAMllkWA/inKem0NhDEFeyuoOvE=
|
||||||
github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261 h1:NHD5GB6cjlkpZFjC76Yli2S63/J2nhr8MuE6KlYJpQM=
|
github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261 h1:NHD5GB6cjlkpZFjC76Yli2S63/J2nhr8MuE6KlYJpQM=
|
||||||
github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261/go.mod h1:2zPxDAN2TAPpxUPjxszjs3QFKreKrQh5al/R3cMXmYk=
|
github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261/go.mod h1:2zPxDAN2TAPpxUPjxszjs3QFKreKrQh5al/R3cMXmYk=
|
||||||
github.com/TicketsBot/worker v0.0.0-20210910205947-89f7bd5ccf67 h1:ZZt7+rCmj+za01PVkgaflrJecLVi2laly1Gjz81YMlk=
|
github.com/TicketsBot/worker v0.0.0-20211108224403-97ac8e44b789 h1:wmHfOWVDT875v91YHs2yorQjwWEuR0z411lwFxI3sZY=
|
||||||
github.com/TicketsBot/worker v0.0.0-20210910205947-89f7bd5ccf67/go.mod h1:n6gqs84FS2GxcVJrA2uznGf6WC5qXVfeEF2fr181TNY=
|
github.com/TicketsBot/worker v0.0.0-20211108224403-97ac8e44b789/go.mod h1:BjXxj6Og1fuup+kxbjIiQ7E3l9oitL7vRF3y4tYN16o=
|
||||||
github.com/TicketsBot/worker v0.0.0-20211102194549-f7058a7791fa h1:/4Fp1qNYG6Svsjv4swrfUlOipKpdWD3fdiPhrlqe4r4=
|
|
||||||
github.com/TicketsBot/worker v0.0.0-20211102194549-f7058a7791fa/go.mod h1:ZX0b2l/SHb6OI3avFkh/0ztqdaqcENjHcMZF12T73AA=
|
|
||||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
github.com/apex/log v1.1.2 h1:bnDuVoi+o98wOdVqfEzNDlY0tcmBia7r4YkjS9EqGYk=
|
github.com/apex/log v1.1.2 h1:bnDuVoi+o98wOdVqfEzNDlY0tcmBia7r4YkjS9EqGYk=
|
||||||
github.com/apex/log v1.1.2/go.mod h1:SyfRweFO+TlkIJ3DVizTSeI1xk7jOIIqOnUPZQTTsww=
|
github.com/apex/log v1.1.2/go.mod h1:SyfRweFO+TlkIJ3DVizTSeI1xk7jOIIqOnUPZQTTsww=
|
||||||
@ -361,9 +356,6 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC
|
|||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/rxdn/gdl v0.0.0-20200522202912-4ae241eb98c1/go.mod h1:2gPBB++1s9Zh11AGM/y84KpmqTyLCnjGwEnt6xRRKL4=
|
github.com/rxdn/gdl v0.0.0-20200522202912-4ae241eb98c1/go.mod h1:2gPBB++1s9Zh11AGM/y84KpmqTyLCnjGwEnt6xRRKL4=
|
||||||
github.com/rxdn/gdl v0.0.0-20210527173953-25dde613ff0a/go.mod h1:jvcb1N6AdaGx3/e8MoLedO6qSo/+UdA5GGHOA8cnAeU=
|
github.com/rxdn/gdl v0.0.0-20210527173953-25dde613ff0a/go.mod h1:jvcb1N6AdaGx3/e8MoLedO6qSo/+UdA5GGHOA8cnAeU=
|
||||||
github.com/rxdn/gdl v0.0.0-20210906182609-337cb3c44a4c/go.mod h1:rENs8TxMsoYSJRssegNS/+fy18NCI9EUdCJX8R83PlY=
|
|
||||||
github.com/rxdn/gdl v0.0.0-20210921120128-02188fdcfd88 h1:DpLqFmCtCAREiRK5nq4SYJGOQV3G6qTTz7H4C4Wb1kU=
|
|
||||||
github.com/rxdn/gdl v0.0.0-20210921120128-02188fdcfd88/go.mod h1:rENs8TxMsoYSJRssegNS/+fy18NCI9EUdCJX8R83PlY=
|
|
||||||
github.com/rxdn/gdl v0.0.0-20211030160619-a8772c268ca4 h1:vHSTqcCCZZwlj6trBUj3tqys5hnKbBf9J6mtuG7DvgM=
|
github.com/rxdn/gdl v0.0.0-20211030160619-a8772c268ca4 h1:vHSTqcCCZZwlj6trBUj3tqys5hnKbBf9J6mtuG7DvgM=
|
||||||
github.com/rxdn/gdl v0.0.0-20211030160619-a8772c268ca4/go.mod h1:rENs8TxMsoYSJRssegNS/+fy18NCI9EUdCJX8R83PlY=
|
github.com/rxdn/gdl v0.0.0-20211030160619-a8772c268ca4/go.mod h1:rENs8TxMsoYSJRssegNS/+fy18NCI9EUdCJX8R83PlY=
|
||||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
35
utils/hexcode.go
Normal file
35
utils/hexcode.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HexColour int
|
||||||
|
|
||||||
|
func (h HexColour) Int() int {
|
||||||
|
return int(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HexColour) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(fmt.Sprintf(`"#%06x"`, h)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HexColour) UnmarshalJSON(data []byte) error {
|
||||||
|
str := strings.TrimPrefix(string(data), `"`)
|
||||||
|
str = strings.TrimPrefix(str, "#")
|
||||||
|
str = strings.TrimSuffix(str, `"`)
|
||||||
|
|
||||||
|
i, err := strconv.ParseInt(str, 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if i < 0 || i > 0xFFFFFF {
|
||||||
|
return fmt.Errorf("invalid hex colour: %s", str)
|
||||||
|
}
|
||||||
|
|
||||||
|
*h = HexColour(i)
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user