Feature: decorate the tag container

This commit is contained in:
VnPower 2023-06-14 17:24:34 +07:00
parent d9396ba671
commit f3f373f73f
Signed by: vnpower
GPG key ID: 881DE3DEB966106C
5 changed files with 245 additions and 154 deletions

View file

@ -3,144 +3,178 @@ package handler
import (
"fmt"
"html/template"
"math/rand"
"pixivfe/configs"
"regexp"
"strconv"
"strings"
"github.com/gofiber/template/jet/v2"
)
func GetTemplateFunctions(engine *jet.Engine) {
engine.AddFunc("inc", func(n int) int {
// For rankings to increment a number by 1
return n + 1
})
engine.AddFunc("add", func(a int, b int) int {
return a + b
})
func GetRandomColor() string {
// Some color shade I stole
colors := []string{
// Green
"#C8847E",
"#C8A87E",
"#C8B87E",
"#C8C67E",
"#C7C87E",
"#C2C87E",
"#BDC87E",
"#82C87E",
"#82C87E",
"#7EC8AF",
"#7EAEC8",
"#7EA6C8",
"#7E99C8",
"#7E87C8",
"#897EC8",
"#967EC8",
"#AE7EC8",
"#B57EC8",
"#C87EA5",
}
engine.AddFunc("dec", func(n int) int {
return n - 1
})
engine.AddFunc("toInt", func(s string) int {
n, _ := strconv.Atoi(s)
return n
})
engine.AddFunc("proxyImage", func(url string) string {
if strings.Contains(url, "s.pximg.net") {
// This subdomain didn't get proxied
return url
}
regex := regexp.MustCompile(`.*?pximg\.net`)
proxy := "https://" + configs.ProxyServer
return regex.ReplaceAllString(url, proxy)
})
engine.AddFunc("parseEmojis", func(s string) template.HTML {
regex := regexp.MustCompile(`\(([^)]+)\)`)
parsedString := regex.ReplaceAllStringFunc(s, func(s string) string {
s = s[1 : len(s)-1] // Get the string inside
var id string
switch s {
case "normal":
id = "101"
case "surprise":
id = "102"
case "serious":
id = "103"
case "heaven":
id = "104"
case "happy":
id = "105"
case "excited":
id = "106"
case "sing":
id = "107"
case "cry":
id = "108"
case "normal2":
id = "201"
case "shame2":
id = "202"
case "love2":
id = "203"
case "interesting2":
id = "204"
case "blush2":
id = "205"
case "fire2":
id = "206"
case "angry2":
id = "207"
case "shine2":
id = "208"
case "panic2":
id = "209"
case "normal3":
id = "301"
case "satisfaction3":
id = "302"
case "surprise3":
id = "303"
case "smile3":
id = "304"
case "shock3":
id = "305"
case "gaze3":
id = "306"
case "wink3":
id = "307"
case "happy3":
id = "308"
case "excited3":
id = "309"
case "love3":
id = "310"
case "normal4":
id = "401"
case "surprise4":
id = "402"
case "serious4":
id = "403"
case "love4":
id = "404"
case "shine4":
id = "405"
case "sweat4":
id = "406"
case "shame4":
id = "407"
case "sleep4":
id = "408"
case "heart":
id = "501"
case "teardrop":
id = "502"
case "star":
id = "503"
}
return fmt.Sprintf(`<img src="https://s.pximg.net/common/images/emoji/%s.png" alt="(%s)" class="emoji" />`, id, s)
})
return template.HTML(parsedString)
})
engine.AddFunc("isEmpty", func(s string) bool {
return len(s) < 1
})
engine.AddFunc("isEmphasize", func(s string) bool {
switch s {
case
"R-18",
"R-18G":
return true
}
return false
})
// Randomly choose one and return
return colors[rand.Intn(len(colors))]
}
func GetTemplateFunctions() template.FuncMap {
return template.FuncMap{
"inc": func(n int) int {
// For rankings to increment a number by 1
return n + 1
},
"add": func(a int, b int) int {
return a + b
},
"dec": func(n int) int {
return n - 1
},
"toInt": func(s string) int {
n, _ := strconv.Atoi(s)
return n
},
"proxyImage": func(url string) string {
if strings.Contains(url, "s.pximg.net") {
// This subdomain didn't get proxied
return url
}
regex := regexp.MustCompile(`.*?pximg\.net`)
proxy := "https://" + configs.ProxyServer
return regex.ReplaceAllString(url, proxy)
},
"parseEmojis": func(s string) template.HTML {
regex := regexp.MustCompile(`\(([^)]+)\)`)
parsedString := regex.ReplaceAllStringFunc(s, func(s string) string {
s = s[1 : len(s)-1] // Get the string inside
var id string
switch s {
case "normal":
id = "101"
case "surprise":
id = "102"
case "serious":
id = "103"
case "heaven":
id = "104"
case "happy":
id = "105"
case "excited":
id = "106"
case "sing":
id = "107"
case "cry":
id = "108"
case "normal2":
id = "201"
case "shame2":
id = "202"
case "love2":
id = "203"
case "interesting2":
id = "204"
case "blush2":
id = "205"
case "fire2":
id = "206"
case "angry2":
id = "207"
case "shine2":
id = "208"
case "panic2":
id = "209"
case "normal3":
id = "301"
case "satisfaction3":
id = "302"
case "surprise3":
id = "303"
case "smile3":
id = "304"
case "shock3":
id = "305"
case "gaze3":
id = "306"
case "wink3":
id = "307"
case "happy3":
id = "308"
case "excited3":
id = "309"
case "love3":
id = "310"
case "normal4":
id = "401"
case "surprise4":
id = "402"
case "serious4":
id = "403"
case "love4":
id = "404"
case "shine4":
id = "405"
case "sweat4":
id = "406"
case "shame4":
id = "407"
case "sleep4":
id = "408"
case "heart":
id = "501"
case "teardrop":
id = "502"
case "star":
id = "503"
}
return fmt.Sprintf(`<img src="https://s.pximg.net/common/images/emoji/%s.png" alt="(%s)" class="emoji" />`, id, s)
})
return template.HTML(parsedString)
},
"randomColor": func() string {
return GetRandomColor()
},
"isEmpty": func(s string) bool {
return len(s) < 1
},
"isEmphasize": func(s string) bool {
switch s {
case
"R-18",
"R-18G":
return true
}
return false
},
}
}

View file

@ -19,7 +19,7 @@ func setupRouter() *fiber.App {
// HTML templates, automatically loaded
engine := jet.New("./template", ".jet.html")
handler.GetTemplateFunctions(engine)
engine.AddFuncMap(handler.GetTemplateFunctions())
server := fiber.New(fiber.Config{
AppName: "PixivFE",

View file

@ -7,7 +7,7 @@ body {
margin: 0;
font-family: "Noto Sans CJK JP", "Open Sans", "Noto Sans", sans-serif;
font-size: 1rem;
color: #d8d4cf;
color: #f5f5f5;
background-color: #131516;
}
@ -36,7 +36,7 @@ body {
display: inline-flex;
align-items: center;
font-size: 1.2rem;
color: #d8d4cf;
color: #f5f5f5;
text-decoration: none;
}
.navbar .navbar-brand img {
@ -59,10 +59,10 @@ body {
padding: 7px 10px;
margin: 0;
border: none;
color: #d8d4cf;
color: #f5f5f5;
}
.navbar .search-bar .search-form-text::placeholder {
color: #d8d4cf;
color: #f5f5f5;
}
.navbar .navbar-button {
display: inline-block;
@ -100,7 +100,7 @@ body {
display: flex;
align-items: center;
list-style: none;
color: #d8d4cf;
color: #f5f5f5;
text-decoration: none;
padding: 10px;
width: 100%;
@ -393,12 +393,27 @@ body {
.tag-container {
background-color: #262a2b;
display: inline-block;
padding: 5px 10px;
display: inline-flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 40px;
padding-left: 20px;
padding-right: 20px;
margin-bottom: 4px;
text-decoration: none;
color: #d8d4cf;
text-align: center;
color: #f5f5f5;
font-weight: bold;
font-size: 1rem;
border-radius: 4px;
}
.tag-container .main {
font-size: 0.8em;
}
.tag-container .sub {
font-size: 0.7em;
font-weight: normal;
}
.switcher {
@ -412,9 +427,9 @@ body {
padding: 8px 5px;
margin-top: 5px;
background-color: #262a2b;
color: #d8d4cf;
color: #f5f5f5;
text-decoration: none;
text-decoration-color: #d8d4cf;
text-decoration-color: #f5f5f5;
}
.switcher .switch-button:hover {
background-color: rgba(38, 42, 43, 0.6);
@ -434,7 +449,7 @@ body {
.pagination .pagination-button {
display: inline-block;
padding: 5px;
color: #d8d4cf;
color: #f5f5f5;
}
.pagination .disabled {
pointer-events: none;
@ -448,7 +463,7 @@ body {
margin-bottom: 8px;
}
.footer a {
color: #d8d4cf;
color: #f5f5f5;
text-decoration: none;
}

View file

@ -1,5 +1,5 @@
$bg: #131516;
$fg: #d8d4cf;
$fg: #f5f5f5;
$bg-alt: #262a2b;
$bg-alt-dimmed: #262a2b99;
$blue: #3d7699;
@ -461,12 +461,28 @@ body {
.tag-container {
background-color: $bg-alt;
display: inline-block;
padding: 5px 10px;
display: inline-flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 40px;
padding-left: 20px;
padding-right: 20px;
margin-bottom: 4px;
text-decoration: none;
text-align: center;
color: $fg;
font-weight: bold;
font-size: 1rem;
border-radius: 4px;
.main {
font-size: 0.8em;
}
.sub {
font-size: 0.7em;
font-weight: normal;
}
}
.switcher {

View file

@ -8,7 +8,11 @@
<div class="container">
<div class="user-page">
<div class="user-details">
<img src="{{ proxyImage(User.Avatar) }}" alt="avatar" class="user-avatar" />
<img
src="{{ proxyImage(User.Avatar) }}"
alt="avatar"
class="user-avatar"
/>
<h2 class="user-name">{{ User.Name }}</h2>
<p class="user-id">
{{ User.Following }} Following | {{ User.MyPixiv }} MyPixiv
@ -18,7 +22,17 @@
</div>
<div>
{{ range User.FrequentTags }}
<a class="tag-container" href="/tags/{{ .Name }}">#{{ .Name }}</a>
<a href="/tags/{{ .Name }}">
<div class="tag-container" style="background-color: {{ randomColor() }}">
{{ if ! .TranslatedName }}
<div class="main">{{ .Name }}</div>
<div class="sub">#</div>
{{ else }}
<div class="main">{{ .TranslatedName }}</div>
<div class="sub">#{{ .Name }}</div>
{{ end }}
</div>
</a>
{{ end }}
</div>
<div>
@ -31,7 +45,11 @@
<a href="#" class="pagination-button disabled">Previous</a>
{{ else }}
<a href="/users/{{ User.ID }}?page=1" class="pagination-button">First</a>
<a href="/users/{{ User.ID }}?page={{ dec(Page) }}" class="pagination-button">Previous</a>
<a
href="/users/{{ User.ID }}?page={{ dec(Page) }}"
class="pagination-button"
>Previous</a
>
{{ end }}
<a href="#" class="pagination-button disabled">{{ Page }}</a>
@ -40,8 +58,16 @@
<a href="#" class="pagination-button disabled">Next</a>
<a href="#" class="pagination-button disabled">Last</a>
{{ else }}
<a href="/users/{{ User.ID }}?page={{ inc(Page) }}" class="pagination-button">Next</a>
<a href="/users/{{ User.ID }}?page={{ dec(PageLimit) }}" class="pagination-button">Last</a>
<a
href="/users/{{ User.ID }}?page={{ inc(Page) }}"
class="pagination-button"
>Next</a
>
<a
href="/users/{{ User.ID }}?page={{ dec(PageLimit) }}"
class="pagination-button"
>Last</a
>
{{ end }}
</div>
</div>