Theming changes

This commit is contained in:
2022-06-07 14:43:01 +02:00
parent aed4c3b301
commit 6bed9e9374
96 changed files with 649 additions and 495 deletions

View File

@@ -2,6 +2,7 @@ package webcontroller
import (
"fmt"
"html/template"
"net/http"
"strings"
"time"
@@ -24,12 +25,35 @@ func browserCompat(ua string) bool {
}
type fileViewerData struct {
Type string `json:"type"` // file or list
APIResponse interface{} `json:"api_response"`
CaptchaKey string `json:"captcha_key"`
ViewToken string `json:"view_token"`
Embedded bool `json:"embedded"`
UserAdsEnabled bool `json:"user_ads_enabled"`
Type string `json:"type"` // file or list
APIResponse interface{} `json:"api_response"`
CaptchaKey string `json:"captcha_key"`
ViewToken string `json:"view_token"`
Embedded bool `json:"embedded"`
UserAdsEnabled bool `json:"user_ads_enabled"`
ThemeURI template.URL `json:"theme_uri"`
}
func (vd *fileViewerData) themeOverride(r *http.Request, files []pixelapi.ListFile) {
vd.ThemeURI = "/theme.css"
var theme = r.URL.Query().Get("style")
var hue = r.URL.Query().Get("hue")
if files[0].Branding != nil {
if theme == "" {
theme = files[0].Branding["theme"]
}
if hue == "" {
hue = files[0].Branding["hue"]
}
}
if theme != "" {
vd.ThemeURI += template.URL("?style=" + theme)
if hue != "" {
vd.ThemeURI += template.URL("&hue=" + hue)
}
}
}
// ServeFileViewer controller for GET /u/:id
@@ -95,10 +119,9 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
vd.Embedded = true
}
vd.themeOverride(r, files)
templateData.Other = vd
fileStyleOverride(templateData, files)
for _, file := range files {
if file.AbuseType != "" {
w.WriteHeader(http.StatusUnavailableForLegalReasons)
@@ -157,9 +180,9 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
if _, ok := r.URL.Query()["embed"]; ok {
vd.Embedded = true
}
templateData.Other = vd
fileStyleOverride(templateData, list.Files)
vd.themeOverride(r, list.Files)
templateData.Other = vd
for _, file := range list.Files {
if file.AbuseType != "" {
@@ -179,16 +202,6 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
}
}
func fileStyleOverride(td *TemplateData, files []pixelapi.ListFile) {
if len(files) == 0 {
return
}
if files[0].Branding != nil && files[0].Branding["theme"] != "" {
td.setStyle(userStyle(files[0].Branding["theme"]))
}
}
// ServeFileViewerDemo is a dummy API response that responds with info about a
// non-existent demo file. This is required by the a-ads ad network to allow for
// automatic checking of the presence of the ad unit on this page.

View File

@@ -1,17 +1,29 @@
package webcontroller
import (
"bytes"
"fmt"
"html/template"
"math/rand"
"net/http"
"strconv"
"time"
"github.com/julienschmidt/httprouter"
)
func (wc *WebController) themeHandler(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
w.Header().Set("Content-Type", "text/css")
w.Write([]byte(userStyleFromRequest(r)))
}
func userStyleFromRequest(r *http.Request) (s template.CSS) {
// Get the chosen style from the URL
var style = r.URL.Query().Get("style")
var hue = -1
if hueStr := r.URL.Query().Get("hue"); hueStr != "" {
hue, _ = strconv.Atoi(hueStr)
}
// If the URL style was empty use the cookie value
if style == "" {
@@ -19,110 +31,175 @@ func userStyleFromRequest(r *http.Request) (s template.CSS) {
style = cookie.Value
}
}
if hue == -1 {
if cookie, err := r.Cookie("hue"); err == nil {
hue, _ = strconv.Atoi(cookie.Value)
}
}
return userStyle(style)
return userStyle(style, hue)
}
func userStyle(style string) template.CSS {
func userStyle(style string, hue int) template.CSS {
var (
def styleSheet
light styleSheet
hasLight bool
)
switch style {
case "nord":
return template.CSS(nordDarkStyle.withLight(nordLightStyle))
case "nord_dark":
return template.CSS(nordDarkStyle.String())
case "nord_light", "snowstorm":
return template.CSS(nordLightStyle.String())
case "solarized":
return template.CSS(solarizedDarkStyle.withLight(solarizedLightStyle))
case "solarized_dark":
return template.CSS(solarizedDarkStyle.String())
case "solarized_light":
return template.CSS(solarizedLightStyle.String())
case "classic":
return template.CSS(classicStyle.String())
case "purple_drain":
return template.CSS(defaultPixeldrainStyle.String())
case "maroon":
return template.CSS(maroonStyle.String())
case "hacker":
return template.CSS(hackerStyle.String())
case "canta":
return template.CSS(cantaPixeldrainStyle.String())
case "skeuos":
return template.CSS(skeuosPixeldrainStyle.String())
case "sweet":
return template.CSS(sweetPixeldrainStyle.String())
case "adwaita":
return template.CSS(adwaitaDarkStyle.withLight(adwaitaLightStyle))
default:
return template.CSS(nordDarkStyle.withLight(nordLightStyle))
fallthrough
case "nord":
def = nordDarkStyle
light = nordLightStyle
hasLight = true
case "nord_dark":
def = nordDarkStyle
case "nord_light", "snowstorm":
def = nordLightStyle
case "solarized":
def = solarizedDarkStyle
light = solarizedLightStyle
hasLight = true
case "solarized_dark":
def = solarizedDarkStyle
case "solarized_light":
def = solarizedLightStyle
case "classic":
def = classicStyle
hue = -1 // Does not support custom hues
case "purple_drain":
def = purpleDrainStyle
hue = -1 // Does not support custom hues
case "maroon":
def = maroonStyle
case "hacker":
def = hackerStyle
hue = -1 // Does not support custom hues
case "canta":
def = cantaPixeldrainStyle
case "skeuos":
def = skeuosPixeldrainStyle
case "sweet":
def = sweetPixeldrainStyle
case "adwaita":
def = adwaitaDarkStyle
light = adwaitaLightStyle
hasLight = true
}
if hue >= 0 && hue <= 360 {
def = def.withHue(hue)
light = light.withHue(hue)
}
if hasLight {
return template.CSS(def.withLight(light))
} else {
return template.CSS(def.String())
}
}
type styleSheet struct {
Link hsl // Based on Highlight if undefined
Input Color
InputHover Color
InputText Color
InputDisabledText Color
HighlightBackground Color
Highlight hsl // Links, highlighted buttons, list navigation
HighlightText hsl // Text on buttons
Danger hsl
ScrollbarForeground Color // Based on Highlight if undefined
ScrollbarHover Color // Based on ScrollbarForeground if undefined
Link HSL // Based on Highlight if undefined
Input CSS
InputHover CSS
InputText CSS
InputDisabledText CSS
HighlightBackground CSS
Highlight HSL // Links, highlighted buttons, list navigation
HighlightText HSL // Text on buttons
Danger HSL
ScrollbarForeground CSS // Based on Highlight if undefined
ScrollbarHover CSS // Based on ScrollbarForeground if undefined
BackgroundColor hsl
Background Color
BackgroundText hsl
BackgroundPattern Color
ParallaxSlider Color
Navigation Color
BodyColor hsl
BodyBackground Color
BodyText hsl
Separator Color
CardColor hsl
CardText hsl
BackgroundColor HSL
Background CSS
BackgroundText HSL
BackgroundPattern CSS
ParallaxSlider CSS
Navigation CSS
BodyColor HSL
BodyBackground CSS
BodyText HSL
Separator CSS
CardColor HSL
CardText HSL
// Colors to use in graphs
Chart1 hsl
Chart2 hsl
Chart3 hsl
Chart1 HSL
Chart2 HSL
Chart3 HSL
Shadow hsl
Shadow HSL
}
func (s styleSheet) withDefaults() styleSheet {
// Set default colors
var noColor = hsl{0, 0, 0}
var defaultHSL = func(color *hsl, def hsl) {
if *color == noColor {
*color = def
var noColor = HSL{0, 0, 0}
var defaultHSL = func(target *HSL, def HSL) {
if *target == noColor {
*target = def
}
}
var defaultColor = func(color *Color, def Color) {
if *color == nil {
*color = def
var defaultCSS = func(target *CSS, def CSS) {
if *target == nil {
*target = def
}
}
defaultHSL(&s.Link, s.Highlight.Add(0, 0, -.05))
defaultColor(&s.ScrollbarForeground, s.Input)
defaultColor(&s.ScrollbarHover, s.Highlight)
defaultCSS(&s.ScrollbarForeground, s.Input)
defaultCSS(&s.ScrollbarHover, s.Highlight)
defaultHSL(&s.Chart1, s.Highlight)
defaultHSL(&s.Chart2, s.Chart1.Add(120, 0, 0))
defaultHSL(&s.Chart3, s.Chart2.Add(120, 0, 0))
defaultColor(&s.HighlightBackground, s.Highlight)
defaultColor(&s.Background, s.BackgroundColor)
defaultColor(&s.BackgroundPattern, s.BackgroundColor)
defaultColor(&s.ParallaxSlider, s.BackgroundColor)
defaultColor(&s.Navigation, NoColor)
defaultColor(&s.BodyBackground, s.BodyColor)
defaultCSS(&s.HighlightBackground, s.Highlight)
defaultCSS(&s.Background, s.BackgroundColor)
defaultCSS(&s.BackgroundPattern, s.BackgroundColor)
defaultCSS(&s.ParallaxSlider, s.BackgroundColor)
defaultCSS(&s.Navigation, RawCSS("none"))
defaultCSS(&s.BodyBackground, s.BodyColor)
defaultHSL(&s.BackgroundText, s.BodyText)
defaultColor(&s.Separator, s.BodyColor.Add(0, 0, .05))
defaultCSS(&s.Separator, s.BodyColor.Add(0, 0, .05))
return s
}
func (s styleSheet) withHue(hue int) styleSheet {
s = s.withDefaults()
var setHue = func(c CSS) CSS {
if hsl, ok := c.(HSL); ok {
hsl.Hue = hue
return hsl
} else {
return c
}
}
s.Input = setHue(s.Input)
s.InputHover = setHue(s.InputHover)
s.InputText = setHue(s.InputText)
s.InputDisabledText = setHue(s.InputDisabledText)
s.ScrollbarForeground = setHue(s.ScrollbarForeground)
s.ScrollbarHover = setHue(s.ScrollbarHover)
s.BackgroundColor.Hue = hue
s.Background = setHue(s.Background)
s.BackgroundText.Hue = hue
s.BackgroundPattern = setHue(s.BackgroundPattern)
s.ParallaxSlider = setHue(s.ParallaxSlider)
s.Navigation = setHue(s.Navigation)
s.BodyColor.Hue = hue
s.BodyBackground = setHue(s.BodyBackground)
s.BodyText.Hue = hue
s.Separator = setHue(s.Separator)
s.CardColor.Hue = hue
s.CardText.Hue = hue
s.Shadow.Hue = hue
return s
}
func (s styleSheet) String() string {
s = s.withDefaults()
@@ -144,6 +221,7 @@ func (s styleSheet) String() string {
--background_color: %s;
--background: %s;
--background_text_color: %s;
--background_pattern: url("%s");
--background_pattern_color: %s;
--parallax_slider_color: %s;
--navigation_background: %s;
@@ -175,6 +253,7 @@ func (s styleSheet) String() string {
s.BackgroundColor.CSS(),
s.Background.CSS(),
s.BackgroundText.CSS(),
BackgroundTiles(),
s.BackgroundPattern.CSS(),
s.ParallaxSlider.CSS(),
s.Navigation.CSS(),
@@ -203,7 +282,7 @@ func (dark styleSheet) withLight(light styleSheet) string {
)
}
func BackgroundTiles(tpl *template.Template) template.URL {
func BackgroundTiles() template.URL {
var (
now = time.Now()
month = now.Month()
@@ -226,262 +305,264 @@ func BackgroundTiles(tpl *template.Template) template.URL {
file = fmt.Sprintf("checker%d", now.UnixNano()%18)
}
var buf = bytes.Buffer{}
if err := tpl.ExecuteTemplate(&buf, file+"_transparent.png", nil); err != nil {
panic(err)
}
return template.URL(buf.String())
return template.URL("/res/img/background_patterns/" + file + "_transparent.png")
// var buf = bytes.Buffer{}
// if err := tpl.ExecuteTemplate(&buf, file+"_transparent.png", nil); err != nil {
// panic(err)
// }
// return template.URL(buf.String())
}
// Following are all the available styles
var defaultPixeldrainStyle = styleSheet{
Input: hsl{266, .85, .24},
InputHover: hsl{266, .85, .28},
InputText: hsl{0, 0, .9},
InputDisabledText: hsl{266, .85, .4},
HighlightBackground: NewGradient(150, hsl{150, .84, .39}, hsl{85, .85, .35}),
Highlight: hsl{117, .63, .46},
HighlightText: hsl{0, 0, 0},
Danger: hsl{357, .63, .46},
ScrollbarForeground: hsl{266, .85, .40},
ScrollbarHover: hsl{266, .85, .50},
var purpleDrainStyle = styleSheet{
Input: HSL{266, .85, .24},
InputHover: HSL{266, .85, .28},
InputText: HSL{0, 0, .9},
InputDisabledText: HSL{266, .85, .4},
HighlightBackground: NewGradient(150, HSL{150, .84, .39}, HSL{85, .85, .35}),
Highlight: HSL{117, .63, .46},
HighlightText: HSL{0, 0, 0},
Danger: HSL{357, .63, .46},
ScrollbarForeground: HSL{266, .85, .40},
ScrollbarHover: HSL{266, .85, .50},
BackgroundColor: hsl{273, .93, .12},
Background: NewGradient(120, hsl{250, .9, .14}, hsl{300, .9, .10}),
BackgroundPattern: NoColor,
ParallaxSlider: hsl{275, .8, .1},
BackgroundColor: HSL{273, .93, .12},
Background: NewGradient(120, HSL{250, .9, .14}, HSL{300, .9, .10}),
BackgroundPattern: RawCSS("none"),
ParallaxSlider: HSL{275, .8, .1},
Navigation: RGBA{0, 0, 0, 0.1},
BodyColor: hsl{274, .9, .14},
BodyBackground: NoColor,
BodyText: hsl{0, 0, .8},
CardColor: hsl{275, .8, .18},
BodyColor: HSL{274, .9, .14},
BodyBackground: RawCSS("none"),
BodyText: HSL{0, 0, .8},
CardColor: HSL{275, .8, .18},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var classicStyle = styleSheet{
Input: hsl{0, 0, .18},
InputHover: hsl{0, 0, .22},
InputText: hsl{0, 0, .9},
InputDisabledText: hsl{0, 0, .4},
Highlight: hsl{89, .60, .45},
HighlightText: hsl{0, 0, 0},
Danger: hsl{339, .65, .31},
ScrollbarForeground: hsl{0, 0, .40},
ScrollbarHover: hsl{0, 0, .50},
Input: HSL{0, 0, .18},
InputHover: HSL{0, 0, .22},
InputText: HSL{0, 0, .9},
InputDisabledText: HSL{0, 0, .4},
Highlight: HSL{89, .60, .45},
HighlightText: HSL{0, 0, 0},
Danger: HSL{339, .65, .31},
ScrollbarForeground: HSL{0, 0, .40},
ScrollbarHover: HSL{0, 0, .50},
BackgroundColor: hsl{0, 0, .08},
BodyColor: hsl{0, 0, .12},
BodyText: hsl{0, 0, .8},
CardColor: hsl{0, 0, .16},
BackgroundColor: HSL{0, 0, .08},
BodyColor: HSL{0, 0, .12},
BodyText: HSL{0, 0, .8},
CardColor: HSL{0, 0, .16},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var maroonStyle = styleSheet{
Input: hsl{0, .8, .20}, // hsl(0, 87%, 40%)
InputHover: hsl{0, .8, .24},
InputText: hsl{0, 0, 1},
InputDisabledText: hsl{0, 0, .5},
Highlight: hsl{137, 1, .37}, //hsl(137, 100%, 37%)
HighlightText: hsl{0, 0, 0},
Danger: hsl{9, .96, .42}, //hsl(9, 96%, 42%)
ScrollbarForeground: hsl{0, .75, .3},
ScrollbarHover: hsl{0, .75, .4},
Input: HSL{0, .8, .20}, // hsl(0, 87%, 40%)
InputHover: HSL{0, .8, .24},
InputText: HSL{0, 0, 1},
InputDisabledText: HSL{0, 0, .5},
Highlight: HSL{137, 1, .37}, //hsl(137, 100%, 37%)
HighlightText: HSL{0, 0, 0},
Danger: HSL{9, .96, .42}, //hsl(9, 96%, 42%)
ScrollbarForeground: HSL{0, .75, .3},
ScrollbarHover: HSL{0, .75, .4},
BackgroundColor: hsl{0, .7, .05},
BodyColor: hsl{0, .8, .08}, // hsl{0, .8, .15},
BodyText: hsl{0, 0, .8},
CardColor: hsl{0, .9, .14},
BackgroundColor: HSL{0, .7, .05},
BodyColor: HSL{0, .8, .08}, // HSL{0, .8, .15},
BodyText: HSL{0, 0, .8},
CardColor: HSL{0, .9, .14},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var hackerStyle = styleSheet{
Input: hsl{0, 0, .1},
InputHover: hsl{0, 0, .14},
InputText: hsl{0, 0, 1},
InputDisabledText: hsl{0, 0, .5},
Highlight: hsl{120, .8, .5},
HighlightText: hsl{0, 0, 0},
Danger: hsl{0, 1, .4},
ScrollbarForeground: hsl{120, .5, .25},
ScrollbarHover: hsl{120, .5, .35},
Input: HSL{0, 0, .1},
InputHover: HSL{0, 0, .14},
InputText: HSL{0, 0, 1},
InputDisabledText: HSL{0, 0, .5},
Highlight: HSL{120, .8, .5},
HighlightText: HSL{0, 0, 0},
Danger: HSL{0, 1, .4},
ScrollbarForeground: HSL{120, .5, .25},
ScrollbarHover: HSL{120, .5, .35},
BackgroundColor: hsl{0, 0, 0},
BodyColor: hsl{0, 0, .03},
BodyText: hsl{0, 0, .8},
CardColor: hsl{120, .4, .05},
BackgroundColor: HSL{0, 0, 0},
BodyColor: HSL{0, 0, .03},
BodyText: HSL{0, 0, .8},
CardColor: HSL{120, .4, .05},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var cantaPixeldrainStyle = styleSheet{
Input: hsl{167, .06, .30}, // hsl(167, 6%, 30%)
InputHover: hsl{167, .06, .34}, // hsl(167, 6%, 30%)
InputText: hsl{0, 0, 1},
InputDisabledText: hsl{0, 0, .5},
Highlight: hsl{165, 1, .40}, // hsl(165, 100%, 40%)
HighlightText: hsl{0, 0, 0},
Danger: hsl{40, 1, .5}, // hsl(40, 100%, 50%)
ScrollbarForeground: hsl{204, .05, .78}, // hsl(204, 5%, 78%)
ScrollbarHover: hsl{204, .05, .88},
Input: HSL{167, .06, .30}, // hsl(167, 6%, 30%)
InputHover: HSL{167, .06, .34}, // hsl(167, 6%, 30%)
InputText: HSL{0, 0, 1},
InputDisabledText: HSL{0, 0, .5},
Highlight: HSL{165, 1, .40}, // hsl(165, 100%, 40%)
HighlightText: HSL{0, 0, 0},
Danger: HSL{40, 1, .5}, // hsl(40, 100%, 50%)
ScrollbarForeground: HSL{204, .05, .78}, // hsl(204, 5%, 78%)
ScrollbarHover: HSL{204, .05, .88},
BackgroundColor: hsl{180, .04, .16},
BodyColor: hsl{168, .05, .21},
BodyText: hsl{0, 0, .8},
CardColor: hsl{170, .05, .26},
BackgroundColor: HSL{180, .04, .16},
BodyColor: HSL{168, .05, .21},
BodyText: HSL{0, 0, .8},
CardColor: HSL{170, .05, .26},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var skeuosPixeldrainStyle = styleSheet{
Input: hsl{226, .15, .23}, //hsl(226, 15%, 23%)
InputHover: hsl{226, .15, .27},
InputText: hsl{60, .06, .93},
InputDisabledText: hsl{0, 0, .5},
Highlight: hsl{282, .65, .54}, // hsl(282, 65%, 54%)
HighlightText: hsl{0, 0, 1},
Danger: hsl{0, .79, .43}, // hsl(0, 79%, 43%)
ScrollbarForeground: hsl{220, .02, .62}, // hsl(220, 2%, 62%)
ScrollbarHover: hsl{220, .02, .80},
Input: HSL{226, .15, .23}, //hsl(226, 15%, 23%)
InputHover: HSL{226, .15, .27},
InputText: HSL{60, .06, .93},
InputDisabledText: HSL{0, 0, .5},
Highlight: HSL{282, .65, .54}, // hsl(282, 65%, 54%)
HighlightText: HSL{0, 0, 1},
Danger: HSL{0, .79, .43}, // hsl(0, 79%, 43%)
ScrollbarForeground: HSL{220, .02, .62}, // hsl(220, 2%, 62%)
ScrollbarHover: HSL{220, .02, .80},
BackgroundColor: hsl{232, .14, .11}, //hsl(232, 14%, 11%)
BodyColor: hsl{229, .14, .16}, // hsl(229, 14%, 16%)
BodyText: hsl{60, .06, .93}, // hsl(60, 6%, 93%)
CardColor: hsl{225, .14, .17}, // hsl(225, 14%, 17%)
BackgroundColor: HSL{232, .14, .11}, //hsl(232, 14%, 11%)
BodyColor: HSL{229, .14, .16}, // hsl(229, 14%, 16%)
BodyText: HSL{60, .06, .93}, // hsl(60, 6%, 93%)
CardColor: HSL{225, .14, .17}, // hsl(225, 14%, 17%)
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var nordDarkStyle = styleSheet{
Input: hsl{220, .16, .36}, // nord3
InputHover: hsl{220, .16, .40},
InputText: hsl{218, .27, .92}, // nord5 hsl(218, 27%, 92%)
InputDisabledText: hsl{220, .16, .22}, // nord0 hsl(220, 16%, 22%)
Highlight: hsl{92, .28, .65}, // nord14 hsl(92, 28%, 65%)
HighlightText: hsl{220, .16, .22}, // nord0
Danger: hsl{354, .42, .56}, // nord11 hsl(354, 42%, 56%)
ScrollbarForeground: hsl{179, .25, .65}, // nord7 hsl(179, 25%, 65%)
ScrollbarHover: hsl{193, .43, .67}, // nord8 hsl(193, 43%, 67%)
Input: HSL{220, .16, .36}, // nord3
InputHover: HSL{220, .16, .40},
InputText: HSL{218, .27, .92}, // nord5 hsl(218, 27%, 92%)
InputDisabledText: HSL{220, .16, .22}, // nord0 hsl(220, 16%, 22%)
Highlight: HSL{92, .28, .65}, // nord14 hsl(92, 28%, 65%)
HighlightText: HSL{220, .16, .22}, // nord0
Danger: HSL{354, .42, .56}, // nord11 hsl(354, 42%, 56%)
ScrollbarForeground: HSL{179, .25, .65}, // nord7 hsl(179, 25%, 65%)
ScrollbarHover: HSL{193, .43, .67}, // nord8 hsl(193, 43%, 67%)
BackgroundColor: hsl{220, .16, .22}, // nord0
BodyColor: hsl{222, .16, .28}, // nord1
BodyText: hsl{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
CardColor: hsl{220, .17, .32}, // nord2
BackgroundColor: HSL{220, .16, .22}, // nord0
BodyColor: HSL{222, .16, .28}, // nord1
BodyText: HSL{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
CardColor: HSL{220, .17, .32}, // nord2
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var nordLightStyle = styleSheet{
Link: hsl{92, .40, .32},
Input: hsl{218, .27, .94}, // nord6 hsl(218, 27%, 94%)
InputHover: hsl{218, .27, .98},
InputText: hsl{222, .16, .28}, // nord1 hsl(222, 16%, 28%)
InputDisabledText: hsl{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
Highlight: hsl{92, .28, .65}, // nord14 hsl(92, 28%, 65%)
HighlightText: hsl{222, .16, .28}, // nord3 hsl(220, 16%, 36%)
Danger: hsl{354, .42, .56}, // nord11 hsl(354, 42%, 56%)
ScrollbarForeground: hsl{179, .25, .65}, // nord7 hsl(179, 25%, 65%)
ScrollbarHover: hsl{193, .43, .67}, // nord8 hsl(193, 43%, 67%)
Link: HSL{92, .40, .32},
Input: HSL{218, .27, .94}, // nord6 hsl(218, 27%, 94%)
InputHover: HSL{218, .27, .98},
InputText: HSL{222, .16, .28}, // nord1 hsl(222, 16%, 28%)
InputDisabledText: HSL{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
Highlight: HSL{92, .28, .65}, // nord14 hsl(92, 28%, 65%)
HighlightText: HSL{222, .16, .28}, // nord3 hsl(220, 16%, 36%)
Danger: HSL{354, .42, .56}, // nord11 hsl(354, 42%, 56%)
ScrollbarForeground: HSL{179, .25, .65}, // nord7 hsl(179, 25%, 65%)
ScrollbarHover: HSL{193, .43, .67}, // nord8 hsl(193, 43%, 67%)
BackgroundColor: hsl{220, .16, .36}, // nord3 hsl(220, 16%, 36%)
BackgroundText: hsl{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
ParallaxSlider: hsl{220, .16, .22}, // nord0 hsl(220, 16%, 22%)
BodyColor: hsl{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
BodyText: hsl{220, .17, .32}, // nord2 hsl(220, 17%, 32%)
BackgroundPattern: hsl{219, .28, .88}, // hsl(219, 28%, 88%)
CardColor: hsl{218, .27, .92}, // nord5 hsl(218, 27%, 92%)
BackgroundColor: HSL{220, .16, .36}, // nord3 hsl(220, 16%, 36%)
BackgroundText: HSL{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
ParallaxSlider: HSL{220, .16, .22}, // nord0 hsl(220, 16%, 22%)
BodyColor: HSL{219, .28, .88}, // nord4 hsl(219, 28%, 88%)
BodyText: HSL{220, .17, .32}, // nord2 hsl(220, 17%, 32%)
BackgroundPattern: HSL{219, .28, .88}, // hsl(219, 28%, 88%)
CardColor: HSL{218, .27, .92}, // nord5 hsl(218, 27%, 92%)
Shadow: hsl{220, .16, .36},
Shadow: HSL{220, .16, .36},
}
var sweetPixeldrainStyle = styleSheet{
Input: hsl{229, .25, .18}, // hsl(229, 25%, 14%)
InputHover: hsl{229, .25, .22}, // hsl(229, 25%, 14%)
InputText: hsl{223, .13, .79},
InputDisabledText: hsl{0, 0, .5},
Highlight: hsl{296, .88, .44},
HighlightText: hsl{0, 0, 0},
Danger: hsl{356, 1, .64}, // hsl(356, 100%, 64%)
Input: HSL{229, .25, .18}, // hsl(229, 25%, 14%)
InputHover: HSL{229, .25, .22}, // hsl(229, 25%, 14%)
InputText: HSL{223, .13, .79},
InputDisabledText: HSL{0, 0, .5},
Highlight: HSL{296, .88, .44},
HighlightText: HSL{0, 0, 0},
Danger: HSL{356, 1, .64}, // hsl(356, 100%, 64%)
BackgroundColor: hsl{225, .25, .06}, // hsl(225, 25%, 6%)
BodyColor: hsl{228, .25, .12}, // hsl(228, 25%, 12%)
BodyText: hsl{223, .13, .79}, // hsl(223, 13%, 79%)
BackgroundColor: HSL{225, .25, .06}, // hsl(225, 25%, 6%)
BodyColor: HSL{228, .25, .12}, // hsl(228, 25%, 12%)
BodyText: HSL{223, .13, .79}, // hsl(223, 13%, 79%)
Separator: RGBA{255, 255, 255, 0.05},
CardColor: hsl{229, .25, .14}, // hsl(229, 25%, 14%)
CardColor: HSL{229, .25, .14}, // hsl(229, 25%, 14%)
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var adwaitaDarkStyle = styleSheet{
Input: RGBA{255, 255, 255, .06},
InputHover: RGBA{255, 255, 255, .1},
InputText: hsl{0, 0, 1},
InputDisabledText: hsl{0, 0, .5},
Highlight: hsl{152, .62, .39}, // hsl(152, 62%, 39%)
HighlightText: hsl{0, 0, 0},
Danger: hsl{9, 1, .69}, // hsl(9, 100%, 69%)
InputText: HSL{0, 0, 1},
InputDisabledText: HSL{0, 0, .5},
Highlight: HSL{152, .62, .39}, // hsl(152, 62%, 39%)
HighlightText: HSL{0, 0, 0},
Danger: HSL{9, 1, .69}, // hsl(9, 100%, 69%)
BackgroundColor: hsl{0, 0, .19},
BodyColor: hsl{0, 0, .14},
BodyText: hsl{0, 0, 1},
BackgroundColor: HSL{0, 0, .19},
BodyColor: HSL{0, 0, .14},
BodyText: HSL{0, 0, 1},
Separator: RGBA{255, 255, 255, 0.04},
CardColor: hsl{0, 0, .08},
CardColor: HSL{0, 0, .08},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var adwaitaLightStyle = styleSheet{
Input: RGBA{0, 0, 0, .06},
InputHover: RGBA{0, 0, 0, .1},
InputText: hsl{0, 0, .2},
InputDisabledText: hsl{0, 0, .7},
Highlight: hsl{152, .62, .47}, // hsl(152, 62%, 47%)
HighlightText: hsl{0, 0, 1},
Danger: hsl{356, .75, .43}, // hsl(356, 75%, 43%)
InputText: HSL{0, 0, .2},
InputDisabledText: HSL{0, 0, .7},
Highlight: HSL{152, .62, .47}, // hsl(152, 62%, 47%)
HighlightText: HSL{0, 0, 1},
Danger: HSL{356, .75, .43}, // hsl(356, 75%, 43%)
BackgroundColor: hsl{0, 0, .92},
BodyColor: hsl{0, 0, .98},
BodyText: hsl{0, 0, .2},
CardColor: hsl{0, 0, 1},
BackgroundColor: HSL{0, 0, .92},
BodyColor: HSL{0, 0, .98},
BodyText: HSL{0, 0, .2},
CardColor: HSL{0, 0, 1},
Shadow: hsl{0, 0, 0.36},
Shadow: HSL{0, 0, 0.36},
}
var solarizedDarkStyle = styleSheet{
Input: hsl{192, .81, .18}, // hsl(194, 14%, 40%)
InputHover: hsl{192, .81, .22}, // hsl(196, 13%, 45%)
InputText: hsl{180, .07, .80}, // hsl(44, 87%, 94%)
InputDisabledText: hsl{194, .14, .30}, // hsl(194, 14%, 40%)
Highlight: hsl{68, 1, .30}, // hsl(68, 100%, 30%)
HighlightText: hsl{192, .81, .14}, // hsl(192, 100%, 11%)
Danger: hsl{1, .71, .52}, // hsl(1, 71%, 52%)
Input: HSL{192, .81, .18}, // hsl(194, 14%, 40%)
InputHover: HSL{192, .81, .22}, // hsl(196, 13%, 45%)
InputText: HSL{180, .07, .80}, // hsl(44, 87%, 94%)
InputDisabledText: HSL{194, .14, .30}, // hsl(194, 14%, 40%)
Highlight: HSL{68, 1, .30}, // hsl(68, 100%, 30%)
HighlightText: HSL{192, .81, .14}, // hsl(192, 100%, 11%)
Danger: HSL{1, .71, .52}, // hsl(1, 71%, 52%)
BackgroundColor: hsl{192, 1, .11}, //hsl(192, 100%, 11%)
BodyColor: hsl{192, .81, .14}, // hsl(192, 81%, 14%)
BodyText: hsl{180, .07, .60}, // hsl(180, 7%, 60%)
BackgroundColor: HSL{192, 1, .11}, //hsl(192, 100%, 11%)
BodyColor: HSL{192, .81, .14}, // hsl(192, 81%, 14%)
BodyText: HSL{180, .07, .60}, // hsl(180, 7%, 60%)
Separator: RGBA{255, 255, 255, 0.05},
CardColor: hsl{192, .81, .16},
CardColor: HSL{192, .81, .16},
Shadow: hsl{0, 0, 0},
Shadow: HSL{0, 0, 0},
}
var solarizedLightStyle = styleSheet{
Input: hsl{46, .42, .84}, //hsl(180, 7%, 60%)
InputHover: hsl{46, .42, .88},
InputText: hsl{194, .14, .20}, // hsl(192, 81%, 14%)
InputDisabledText: hsl{194, .14, .80},
Highlight: hsl{68, 1, .30}, // hsl(68, 100%, 30%)
HighlightText: hsl{44, .87, .94},
Danger: hsl{1, .71, .52}, // hsl(1, 71%, 52%)
Input: HSL{46, .42, .84}, //hsl(180, 7%, 60%)
InputHover: HSL{46, .42, .88},
InputText: HSL{194, .14, .20}, // hsl(192, 81%, 14%)
InputDisabledText: HSL{194, .14, .80},
Highlight: HSL{68, 1, .30}, // hsl(68, 100%, 30%)
HighlightText: HSL{44, .87, .94},
Danger: HSL{1, .71, .52}, // hsl(1, 71%, 52%)
BackgroundColor: hsl{46, .42, .88}, // hsl(46, 42%, 88%)
BodyColor: hsl{44, .87, .94}, // hsl(44, 87%, 94%)
BodyText: hsl{194, .14, .40}, // hsl(194, 14%, 40%)
BackgroundColor: HSL{46, .42, .88}, // hsl(46, 42%, 88%)
BodyColor: HSL{44, .87, .94}, // hsl(44, 87%, 94%)
BodyText: HSL{194, .14, .40}, // hsl(194, 14%, 40%)
Separator: RGBA{0, 0, 0, 0.05},
CardColor: hsl{44, .87, .96},
CardColor: HSL{44, .87, .96},
Shadow: hsl{0, 0, 0.36},
Shadow: HSL{0, 0, 0.36},
}

View File

@@ -2,29 +2,38 @@ package webcontroller
import (
"fmt"
"math"
)
type Color interface {
CSS
HSL() HSL
RGB() RGB
}
type CSS interface {
CSS() string
}
// Raw CSS
type CSS string
type RawCSS string
func (c CSS) CSS() string { return string(c) }
const NoColor = CSS("none")
func (c RawCSS) CSS() string { return string(c) }
// HSL color
type hsl struct {
type HSL struct {
Hue int
Saturation float64
Lightness float64
}
func (orig hsl) RGB() string {
var _ Color = HSL{} // Confirm interface compliance
func (hsl HSL) CSS() string { return hsl.RGB().CSS() }
func (hsl HSL) HSL() HSL { return hsl }
func (hsl HSL) RGB() RGB {
var r, g, b, q, p float64
var h, s, l = float64(orig.Hue) / 360, orig.Saturation, orig.Lightness
var h, s, l = float64(hsl.Hue) / 360, hsl.Saturation, hsl.Lightness
if s == 0 {
r, g, b = l, l, l
@@ -58,19 +67,15 @@ func (orig hsl) RGB() string {
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h-1.0/3.0)
}
return fmt.Sprintf("%02x%02x%02x", int(r*255), int(g*255), int(b*255))
}
func (orig hsl) CSS() string {
return "#" + orig.RGB()
return RGB{R: uint8(r * 255), G: uint8(g * 255), B: uint8(b * 255)}
}
// Add returns a NEW HSL struct, it doesn't modify the current one
func (h hsl) Add(hue int, saturation float64, lightness float64) hsl {
var new = hsl{
h.Hue + hue,
h.Saturation + saturation,
h.Lightness + lightness,
func (hsl HSL) Add(hue int, saturation float64, lightness float64) HSL {
var new = HSL{
hsl.Hue + hue,
hsl.Saturation + saturation,
hsl.Lightness + lightness,
}
// Hue bounds correction
if new.Hue < 0 {
@@ -94,21 +99,27 @@ func (h hsl) Add(hue int, saturation float64, lightness float64) hsl {
return new
}
func (h hsl) WithAlpha(alpha float64) HSLA {
return HSLA{h, alpha}
func (hsl HSL) WithAlpha(alpha float64) HSLA {
return HSLA{hsl.Hue, hsl.Saturation, hsl.Lightness, alpha}
}
type HSLA struct {
hsl
Alpha float64
Hue int
Saturation float64
Lightness float64
Alpha float64
}
var _ Color = HSLA{}
func (hsla HSLA) CSS() string {
return fmt.Sprintf(
"hsla(%d, %.2f%%, %.2f%%, %.2f)",
hsla.Hue, hsla.Saturation*100, hsla.Lightness*100, hsla.Alpha,
)
}
func (hsla HSLA) HSL() HSL { return HSL{hsla.Hue, hsla.Saturation, hsla.Lightness} }
func (hsla HSLA) RGB() RGB { return hsla.HSL().RGB() }
type RGB struct {
R uint8
@@ -116,9 +127,55 @@ type RGB struct {
B uint8
}
func (rgb RGB) CSS() string {
return fmt.Sprintf("#%02x%02x%02x", rgb.R, rgb.G, rgb.B)
var _ Color = RGB{}
func (rgb RGB) CSS() string { return fmt.Sprintf("#%02x%02x%02x", rgb.R, rgb.G, rgb.B) }
func (rgb RGB) HSL() HSL {
var r, g, b = float64(rgb.R), float64(rgb.G), float64(rgb.B)
var h, s, l float64
max := math.Max(math.Max(r, g), b)
min := math.Min(math.Min(r, g), b)
// Luminosity is the average of the max and min rgb color intensities.
l = (max + min) / 2
// saturation
delta := max - min
if delta == 0 {
// it's gray
return HSL{0, 0, l}
}
// it's not gray
if l < 0.5 {
s = delta / (max + min)
} else {
s = delta / (2 - max - min)
}
// hue
r2 := (((max - r) / 6) + (delta / 2)) / delta
g2 := (((max - g) / 6) + (delta / 2)) / delta
b2 := (((max - b) / 6) + (delta / 2)) / delta
switch {
case r == max:
h = b2 - g2
case g == max:
h = (1.0 / 3.0) + r2 - b2
case b == max:
h = (2.0 / 3.0) + g2 - r2
}
if h < 0 {
h += 1
} else if h > 1 {
h -= 1
}
return HSL{int(h), s, l}
}
func (rgb RGB) RGB() RGB { return rgb }
type RGBA struct {
R uint8
@@ -127,15 +184,22 @@ type RGBA struct {
A float64
}
var _ Color = RGBA{}
func (rgba RGBA) CSS() string {
return fmt.Sprintf("rgba(%d, %d, %d, %f)", rgba.R, rgba.G, rgba.B, rgba.A)
}
func (rgba RGBA) HSL() HSL { return rgba.RGB().HSL() }
func (rgba RGBA) RGB() RGB { return RGB{rgba.R, rgba.G, rgba.B} }
type Gradient struct {
Angle int
Colors []Color
}
var _ CSS = Gradient{}
func NewGradient(angle int, colors ...Color) Gradient {
return Gradient{angle, colors}
}

View File

@@ -21,15 +21,13 @@ import (
// TemplateData is a struct that every template expects when being rendered. In
// the field Other you can pass your own template-specific variables.
type TemplateData struct {
tpm *TemplateManager
Authenticated bool
User pixelapi.UserInfo
UserAgent string
UserStyle template.CSS
BackgroundPattern template.URL
APIEndpoint template.URL
PixelAPI pixelapi.PixelAPI
Hostname template.HTML
tpm *TemplateManager
Authenticated bool
User pixelapi.UserInfo
UserAgent string
APIEndpoint template.URL
PixelAPI pixelapi.PixelAPI
Hostname template.HTML
// Only used on file viewer page
Title string
@@ -45,11 +43,6 @@ type TemplateData struct {
Form Form
}
func (td *TemplateData) setStyle(style template.CSS) {
td.UserStyle = style
td.BackgroundPattern = BackgroundTiles(td.tpm.tpl)
}
func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request) (t *TemplateData) {
t = &TemplateData{
tpm: wc.templates,
@@ -65,8 +58,6 @@ func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request)
URLQuery: r.URL.Query(),
}
t.setStyle(userStyleFromRequest(r))
// If the user is authenticated we'll indentify him and put the user info
// into the templatedata. This is used for putting the username in the menu
// and stuff like that
@@ -245,7 +236,7 @@ func (tm *TemplateManager) mul(a, b interface{}) float64 { return toFloat(a) * t
func (tm *TemplateManager) div(a, b interface{}) float64 { return toFloat(a) / toFloat(b) }
func (tm *TemplateManager) formatData(i interface{}) string {
return util.FormatData(int64(detectInt(i)))
return util.FormatData(detectInt(i))
}
func (tm *TemplateManager) formatSC(amt float64) string {
var fmtSize = func(n float64, u string) string {

View File

@@ -133,7 +133,7 @@ func New(
r.NotFound = http.HandlerFunc(wc.serveNotFound)
// Request method shorthands. These help keep the array of handlers aligned
const PST, GET, PUT, DEL = "POST", "GET", "PUT", "DELETE"
const PST, GET = "POST", "GET"
// Loop over the handlers and register all of them in the router
for _, h := range []struct {
@@ -217,6 +217,7 @@ func New(
// Misc
{GET, "misc/sharex/pixeldrain.com.sxcu", wc.serveShareXConfig},
{GET, "theme.css", wc.themeHandler},
} {
r.Handle(h.method, prefix+"/"+h.path, h.handler)
}