necessário
This commit is contained in:
parent
92b0a902ca
commit
7edb0a17ed
5 changed files with 199 additions and 162 deletions
14
main.go
14
main.go
|
|
@ -111,7 +111,7 @@ func main() {
|
||||||
Port: ":2323",
|
Port: ":2323",
|
||||||
Root: "/home/xi/seed/gallery-dl/",
|
Root: "/home/xi/seed/gallery-dl/",
|
||||||
Galleries: make([]gallery.Gallery, 0, 50),
|
Galleries: make([]gallery.Gallery, 0, 50),
|
||||||
UniqueTags: make(map[gallery.Tag]int),
|
UniqueTags: make(map[string]int),
|
||||||
UniqueArtists: make(map[string]int),
|
UniqueArtists: make(map[string]int),
|
||||||
UniqueGroups: make(map[string]int),
|
UniqueGroups: make(map[string]int),
|
||||||
UniqueParodies: make(map[string]int),
|
UniqueParodies: make(map[string]int),
|
||||||
|
|
@ -276,21 +276,21 @@ func main() {
|
||||||
_ = png.Encode(io.MultiWriter(imageCache, w), destImage)
|
_ = png.Encode(io.MultiWriter(imageCache, w), destImage)
|
||||||
})
|
})
|
||||||
|
|
||||||
// http.DefaultServeMux.HandleFunc("POST /filter/{tag}/{sex}", func(w http.ResponseWriter, r *http.Request) {
|
// http.DefaultServeMux.HandleFunc("GET /filter/{tag}/{sex}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
// tagLookup := r.PathValue("tag")
|
// tagLookup := r.PathValue("tag")
|
||||||
// if tagLookup == "" {
|
// if tagLookup == "" {
|
||||||
// panic(fmt.Errorf("tag could not be found: %s", r.URL.Path))
|
// panic(fmt.Errorf("tag could not be found: %s", r.URL.Path))
|
||||||
// }
|
// }
|
||||||
// if tagLookup == "clear" {
|
// if tagLookup == "clear" {
|
||||||
// state.Filtered = []gallery.Tag{}
|
// state.Filtered = []gallery.Tag{}
|
||||||
// view.GalleriesListing(state.Galleries).Render(w)
|
// view.SearchResults(state.Galleries).Render(w)
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// tagSexLookup := r.PathValue("sex")
|
// tagSexLookup := r.PathValue("sex")
|
||||||
// if tagSexLookup == "" {
|
// if tagSexLookup == "" {
|
||||||
// panic(fmt.Errorf("tag sex could not be found: %s", r.URL.Path))
|
// panic(fmt.Errorf("tag sex could not be found: %s", r.URL.Path))
|
||||||
// }
|
// }
|
||||||
// sex := gallery.ToGender(tagSexLookup)
|
// sex := gallery.Gender(tagSexLookup)
|
||||||
// i := slices.IndexFunc(state.TagKeys, func(a gallery.Tag) bool {
|
// i := slices.IndexFunc(state.TagKeys, func(a gallery.Tag) bool {
|
||||||
// return a.Name == tagLookup && a.Sex == sex
|
// return a.Name == tagLookup && a.Sex == sex
|
||||||
// })
|
// })
|
||||||
|
|
@ -304,7 +304,7 @@ func main() {
|
||||||
// } else {
|
// } else {
|
||||||
// state.Filtered = slices.Delete(state.Filtered, i, i+1)
|
// state.Filtered = slices.Delete(state.Filtered, i, i+1)
|
||||||
// }
|
// }
|
||||||
// view.GalleriesListing(state.FilterGalleries()).Render(w)
|
// view.SearchResults(state.FilterGalleries()).Render(w)
|
||||||
// })
|
// })
|
||||||
|
|
||||||
http.DefaultServeMux.HandleFunc("GET /stats", func(w http.ResponseWriter, r *http.Request) {
|
http.DefaultServeMux.HandleFunc("GET /stats", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
@ -328,7 +328,7 @@ func main() {
|
||||||
query := r.FormValue("search")
|
query := r.FormValue("search")
|
||||||
log.Println("search form result:", query)
|
log.Println("search form result:", query)
|
||||||
if query == "" {
|
if query == "" {
|
||||||
view.SearchResults(state.Galleries, 0).Render(w)
|
view.SearchResults(state.Galleries).Render(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// ranks := fuzzy.RankFindFold(search, state.GalleryNames)
|
// ranks := fuzzy.RankFindFold(search, state.GalleryNames)
|
||||||
|
|
@ -362,7 +362,7 @@ func main() {
|
||||||
}
|
}
|
||||||
galleries = append(galleries, state.Galleries[r.OriginalIndex])
|
galleries = append(galleries, state.Galleries[r.OriginalIndex])
|
||||||
}
|
}
|
||||||
view.SearchResults(galleries, 0).Render(w)
|
view.SearchResults(galleries).Render(w)
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Fatal(server.Serve(ln))
|
log.Fatal(server.Serve(ln))
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package state
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"goreader/gallery"
|
"goreader/gallery"
|
||||||
"maps"
|
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
_ "golang.org/x/image/webp"
|
_ "golang.org/x/image/webp"
|
||||||
|
|
@ -15,7 +14,8 @@ type State struct {
|
||||||
CacheDir string
|
CacheDir string
|
||||||
Galleries []gallery.Gallery
|
Galleries []gallery.Gallery
|
||||||
GalleryNames []string
|
GalleryNames []string
|
||||||
UniqueTags map[gallery.Tag]int
|
// UniqueTags map[gallery.Tag]int
|
||||||
|
UniqueTags map[string]int
|
||||||
UniqueArtists map[string]int
|
UniqueArtists map[string]int
|
||||||
UniqueGroups map[string]int
|
UniqueGroups map[string]int
|
||||||
UniqueParodies map[string]int
|
UniqueParodies map[string]int
|
||||||
|
|
@ -28,11 +28,11 @@ func (s *State) AddGallery(g gallery.Gallery) error {
|
||||||
s.Galleries = append(s.Galleries, g)
|
s.Galleries = append(s.Galleries, g)
|
||||||
s.GalleryNames = append(s.GalleryNames, g.Name())
|
s.GalleryNames = append(s.GalleryNames, g.Name())
|
||||||
slices.SortFunc(s.Galleries, func(a, b gallery.Gallery) int {
|
slices.SortFunc(s.Galleries, func(a, b gallery.Gallery) int {
|
||||||
return a.CTime.Compare(b.CTime)
|
return -a.CTime.Compare(b.CTime)
|
||||||
|
|
||||||
})
|
})
|
||||||
for _, tag := range g.Tags() {
|
for _, tag := range g.Tags() {
|
||||||
s.UniqueTags[tag]++
|
s.UniqueTags[tag.Name]++
|
||||||
}
|
}
|
||||||
for _, artist := range g.Artists() {
|
for _, artist := range g.Artists() {
|
||||||
s.UniqueArtists[artist]++
|
s.UniqueArtists[artist]++
|
||||||
|
|
@ -43,7 +43,6 @@ func (s *State) AddGallery(g gallery.Gallery) error {
|
||||||
for _, parody := range g.Parodies() {
|
for _, parody := range g.Parodies() {
|
||||||
s.UniqueParodies[parody]++
|
s.UniqueParodies[parody]++
|
||||||
}
|
}
|
||||||
s.TagKeys = slices.Collect(maps.Keys(s.UniqueTags))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
146
views/index.go
146
views/index.go
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"goreader/gallery"
|
"goreader/gallery"
|
||||||
"goreader/state"
|
"goreader/state"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/silva-guimaraes/gtag"
|
"github.com/silva-guimaraes/gtag"
|
||||||
)
|
)
|
||||||
|
|
@ -37,15 +38,22 @@ func tag(t gallery.Tag, state *state.State) *gtag.Tag {
|
||||||
backgroundClass = "female"
|
backgroundClass = "female"
|
||||||
}
|
}
|
||||||
d := gtag.New("a").
|
d := gtag.New("a").
|
||||||
Href("javascript:void(0)").
|
Href(fmt.Sprintf("javascript:filter_tags('%s')", strings.TrimSpace(t.Name) /* FIXME */)).
|
||||||
Class("tag").
|
Class("tag")
|
||||||
SetAttr("hx-post", fmt.Sprintf("/filter/%s/%s", t.Name, t.Sex)).
|
|
||||||
SetAttr("hx-target", "#listing").
|
|
||||||
SetAttr("hx-swap", "outerHTML")
|
|
||||||
{
|
{
|
||||||
d.Tag("span").Text(gender).Class("name", backgroundClass)
|
d.Tag("span").Text(gender).Class("name", backgroundClass)
|
||||||
d.Tag("span").Text(t.Name).Class("name")
|
d.Tag("span").Text(t.Name).Class("name")
|
||||||
d.Tag("span").Text(strconv.Itoa(state.UniqueTags[t])).Class("name", backgroundClass)
|
d.Tag("span").Text(strconv.Itoa(state.UniqueTags[t.Name])).Class("name", backgroundClass)
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func artistTag(artistName string) *gtag.Tag {
|
||||||
|
d := gtag.New("a").
|
||||||
|
Href(fmt.Sprintf("javascript:filter_artist('%s')", artistName /* FIXME */)).
|
||||||
|
Class("tag")
|
||||||
|
{
|
||||||
|
d.Tag("span").Text(artistName).Class("name")
|
||||||
}
|
}
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +63,8 @@ func thumbnail(src string) *gtag.Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fullThumbnail(g gallery.Gallery) *gtag.Tag {
|
func fullThumbnail(g gallery.Gallery) *gtag.Tag {
|
||||||
return thumbnail(fmt.Sprintf("/page/%s/1", g.Uuid()))
|
thumb := thumbnail(fmt.Sprintf("/page/%s/1", g.Uuid()))
|
||||||
|
return gtag.Div().Id("image-wrapper").Append(thumb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func smallThumbnail(g gallery.Gallery) *gtag.Tag {
|
func smallThumbnail(g gallery.Gallery) *gtag.Tag {
|
||||||
|
|
@ -71,9 +80,21 @@ func InspectorInfo(g gallery.Gallery, state *state.State) *gtag.Tag {
|
||||||
d.Tag("a").
|
d.Tag("a").
|
||||||
SetAttr("href", fmt.Sprintf("/read/%s", g.Uuid())).
|
SetAttr("href", fmt.Sprintf("/read/%s", g.Uuid())).
|
||||||
SetAttr("hx-boost", "false").
|
SetAttr("hx-boost", "false").
|
||||||
SetAttr("style", "color: white").
|
Tag("h1").
|
||||||
Tag("h1").Text(g.Name())
|
SetAttr("style", "color: white; margin: 10px 0 10px 0;").
|
||||||
d.Tag("h2").Text(g.JpName())
|
Text(g.Name())
|
||||||
|
d.Tag("h2").Style("margin: 0").Text(g.JpName())
|
||||||
|
d.Tag("h3").
|
||||||
|
Text(fmt.Sprintf("Pages: %d", len(g.Images()))).
|
||||||
|
Style("font-size: 14px; ; margin: 0;")
|
||||||
|
d.Tag("h2").Text("Artists")
|
||||||
|
artists := d.Div()
|
||||||
|
{
|
||||||
|
for _, a := range g.Artists() {
|
||||||
|
artists.Append(artistTag(a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.Tag("h2").Text("Tags")
|
||||||
tags := d.Div()
|
tags := d.Div()
|
||||||
{
|
{
|
||||||
for _, t := range g.Tags() {
|
for _, t := range g.Tags() {
|
||||||
|
|
@ -85,10 +106,16 @@ func InspectorInfo(g gallery.Gallery, state *state.State) *gtag.Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
func cover(g gallery.Gallery) *gtag.Tag {
|
func cover(g gallery.Gallery) *gtag.Tag {
|
||||||
|
var s []string
|
||||||
|
for _, tag := range g.Tags() {
|
||||||
|
s = append(s, fmt.Sprintf("'%s'", strings.TrimSpace(tag.Name)) /* FIXME */)
|
||||||
|
}
|
||||||
|
dataset := fmt.Sprintf("[%s]", strings.Join(s, ", "))
|
||||||
a := gtag.New("a").
|
a := gtag.New("a").
|
||||||
Class("cover").
|
Class("cover").
|
||||||
Id(fmt.Sprintf("cover-%s", g.Uuid())).
|
Id(fmt.Sprintf("cover-%s", g.Uuid())).
|
||||||
SetAttr("href", fmt.Sprintf("/read/%s", g.Uuid())).
|
SetAttr("href", fmt.Sprintf("/read/%s", g.Uuid())).
|
||||||
|
SetAttr("data-tags", dataset).
|
||||||
SetAttr("hx-get", fmt.Sprintf("/details/%s", g.Uuid())).
|
SetAttr("hx-get", fmt.Sprintf("/details/%s", g.Uuid())).
|
||||||
SetAttr("onmouseenter", "inspectSetTimeout(event)").
|
SetAttr("onmouseenter", "inspectSetTimeout(event)").
|
||||||
SetAttr("onmouseleave", "inspectClearTimeout(event)").
|
SetAttr("onmouseleave", "inspectClearTimeout(event)").
|
||||||
|
|
@ -101,22 +128,19 @@ func cover(g gallery.Gallery) *gtag.Tag {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
const galleriesPerPage = 50
|
const galleriesPerPage = 70
|
||||||
|
|
||||||
func SearchResults(galleries []gallery.Gallery, page int) *gtag.Tag {
|
func SearchResults(galleries []gallery.Gallery) *gtag.Tag {
|
||||||
glm := max(len(galleries)-1, 0)
|
s := gtag.New("section")
|
||||||
recent := galleries[min(page*galleriesPerPage, glm):min((page+1)*galleriesPerPage, glm)]
|
results := s.Tag("section").Id("results")
|
||||||
m := gtag.New("main")
|
|
||||||
// HTMX faz com que isso receba [InspectorInfo] quando usuário paira o
|
|
||||||
// mouse sobre algum cover
|
|
||||||
m.Tag("section").Id("inspector")
|
|
||||||
results := m.Tag("section").Id("results")
|
|
||||||
{
|
{
|
||||||
for _, g := range recent {
|
results.Tag("header").Tag("h1").Text(fmt.Sprintf("Listing %d Galleries", len(galleries)))
|
||||||
results.Append(cover(g))
|
covers := results.Tag("main")
|
||||||
|
for _, g := range galleries {
|
||||||
|
covers.Append(cover(g))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func Stats(state *state.State) *gtag.Tag {
|
func Stats(state *state.State) *gtag.Tag {
|
||||||
|
|
@ -153,80 +177,18 @@ func Index(state *state.State, page int) *gtag.Tag {
|
||||||
{
|
{
|
||||||
nav := body.Tag("nav").Class("container")
|
nav := body.Tag("nav").Class("container")
|
||||||
{
|
{
|
||||||
|
nav.Tag("a").
|
||||||
|
Href("javascript:clear_filters()").
|
||||||
|
Text("clear filters")
|
||||||
nav.Div().Text("omakase v1")
|
nav.Div().Text("omakase v1")
|
||||||
}
|
}
|
||||||
center := body.Div().Id("center")
|
center := body.Div().Id("center")
|
||||||
{
|
{
|
||||||
top := center.Tag("div").Class("top")
|
d := center.Div()
|
||||||
{
|
// HTMX faz com que isso receba [InspectorInfo] quando usuário paira o
|
||||||
top.Div().Id("search-bar").VoidTag("input").
|
// mouse sobre algum cover
|
||||||
Class("ask-input").
|
d.Tag("section").Id("inspector")
|
||||||
SetAttr("type", "search").
|
d.Append(SearchResults(state.Galleries))
|
||||||
SetAttr("name", "search").
|
|
||||||
SetAttr("autocomplete", "false").
|
|
||||||
SetAttr("placeholder", "Slash to search...").
|
|
||||||
SetAttr("hx-post", "/search").
|
|
||||||
SetAttr("hx-trigger", "input changed delay:50ms, search").
|
|
||||||
SetAttr("hx-target", "#search-results")
|
|
||||||
header := top.Tag("header").Class("container")
|
|
||||||
{
|
|
||||||
header.Div().Id("omakase").
|
|
||||||
Tag("a").
|
|
||||||
SetAttr("href", "/random").
|
|
||||||
Text("おまかせ").
|
|
||||||
SetAttr("target", "_blank")
|
|
||||||
header.Tag("hr").Style("opacity: 0.2;")
|
|
||||||
header.Append(Stats(state))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret := center.Tag("main").Id("search-results")
|
|
||||||
{
|
|
||||||
controls := ret.Tag("section").AddClass("container").Id("controls")
|
|
||||||
{
|
|
||||||
paging := controls.Div()
|
|
||||||
{
|
|
||||||
maxPages := len(state.Galleries) / galleriesPerPage
|
|
||||||
previousPage := gtag.New("a").
|
|
||||||
AddClass("page-control").
|
|
||||||
Text("<")
|
|
||||||
if page > 1 {
|
|
||||||
previousPage.SetAttr("href",
|
|
||||||
fmt.Sprintf("?page=%d", page-1),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
paging.Append(previousPage)
|
|
||||||
p := page
|
|
||||||
for ; p < min(page+3, maxPages); p++ {
|
|
||||||
paging.Tag("a").
|
|
||||||
AddClass("page-control").
|
|
||||||
SetAttr("href",
|
|
||||||
fmt.Sprintf("?page=%d", p),
|
|
||||||
).Text(fmt.Sprint(p))
|
|
||||||
}
|
|
||||||
if len(state.Galleries) > 0 && p != maxPages {
|
|
||||||
paging.Tag("span").Text("...")
|
|
||||||
}
|
|
||||||
paging.Tag("a").
|
|
||||||
AddClass("page-control").
|
|
||||||
SetAttr("href",
|
|
||||||
fmt.Sprintf("?page=%d", maxPages),
|
|
||||||
).Text(fmt.Sprint(maxPages))
|
|
||||||
nextPage := gtag.New("a").
|
|
||||||
AddClass("page-control").
|
|
||||||
SetAttr("href", "?page=1").
|
|
||||||
Text(">")
|
|
||||||
if page < maxPages {
|
|
||||||
nextPage.SetAttr("href",
|
|
||||||
fmt.Sprintf("?page=%d", page+1),
|
|
||||||
)
|
|
||||||
} else if page == maxPages {
|
|
||||||
nextPage.SetAttr("disabled", "true")
|
|
||||||
}
|
|
||||||
paging.Append(nextPage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret.Append(SearchResults(state.Galleries, page))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
body.Tag("footer").P().Text(randomQuote())
|
body.Tag("footer").P().Text(randomQuote())
|
||||||
body.Tag("script").Asis(indexJavascript)
|
body.Tag("script").Asis(indexJavascript)
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,77 @@ hotkeys('/', {keyup: true}, function (event, _){
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let filtered_tags = new Set();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
function filter_tags(name) {
|
||||||
|
filtered_tags.add(name);
|
||||||
|
/**
|
||||||
|
* @type {NodeListOf<HTMLElement>}
|
||||||
|
*/
|
||||||
|
let covers = document.querySelectorAll('.cover');
|
||||||
|
for (let cover of covers) {
|
||||||
|
/**
|
||||||
|
* @type {Array<string>}
|
||||||
|
*/
|
||||||
|
let tags = eval(cover.dataset['tags']); // yeehaw!!! eu sou um cowboy yeehaw!!!
|
||||||
|
if (!(tags.includes(name))) {
|
||||||
|
cover.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const new_params = new URLSearchParams([
|
||||||
|
['tags', Array.from(filtered_tags).join('&')]
|
||||||
|
// ...Array.from(url.searchParams.entries()),
|
||||||
|
]).toString();
|
||||||
|
window.history.replaceState(null, "", `${url.pathname}?${new_params}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
function filter_artists(name) {
|
||||||
|
filtered_tags.add(name);
|
||||||
|
/**
|
||||||
|
* @type {NodeListOf<HTMLElement>}
|
||||||
|
*/
|
||||||
|
let covers = document.querySelectorAll('.cover');
|
||||||
|
for (let cover of covers) {
|
||||||
|
/**
|
||||||
|
* @type {Array<string>}
|
||||||
|
*/
|
||||||
|
let tags = eval(cover.dataset['tags']); // yeehaw!!! eu sou um cowboy yeehaw!!!
|
||||||
|
if (!(tags.includes(name))) {
|
||||||
|
cover.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const new_params = new URLSearchParams([
|
||||||
|
['tags', Array.from(filtered_tags).join('&')]
|
||||||
|
// ...Array.from(url.searchParams.entries()),
|
||||||
|
]).toString();
|
||||||
|
window.history.replaceState(null, "", `${url.pathname}?${new_params}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// filtra tags na url da página
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
filtered_tags = new Set(url.searchParams.get('tags')?.split('&'));
|
||||||
|
filtered_tags?.forEach(filter_tags);
|
||||||
|
|
||||||
|
function clear_filters() {
|
||||||
|
window.history.replaceState(null, "", url.pathname);
|
||||||
|
document.querySelectorAll('.cover').forEach(x => x.classList.remove('hidden'));
|
||||||
|
filtered_tags = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Event & {target: HTMLElement}} event
|
* @param {Event & {target: HTMLElement}} event
|
||||||
*/
|
*/
|
||||||
function inspectSetTimeout(event) {
|
function inspectSetTimeout(event) {
|
||||||
let target = event.target;
|
let target = event.target;
|
||||||
|
|
||||||
let id = setTimeout(
|
let id = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
let targetId = '#' + target.id;
|
let targetId = '#' + target.id;
|
||||||
|
|
@ -33,7 +97,7 @@ function inspectSetTimeout(event) {
|
||||||
500
|
500
|
||||||
);
|
);
|
||||||
|
|
||||||
target.dataset['timeout'] = id
|
target.dataset['timeout'] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,6 +105,6 @@ function inspectSetTimeout(event) {
|
||||||
*/
|
*/
|
||||||
function inspectClearTimeout(event) {
|
function inspectClearTimeout(event) {
|
||||||
let target = event.target;
|
let target = event.target;
|
||||||
clearTimeout(target.dataset['timeout'])
|
clearTimeout(target.dataset['timeout']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@
|
||||||
--main-margin: 62px;
|
--main-margin: 62px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
font-size-adjust: ex-height 0.53;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -20,7 +26,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pages-container {
|
#pages-container {
|
||||||
|
|
@ -94,12 +100,9 @@ body {
|
||||||
|
|
||||||
#index nav {
|
#index nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: space-between;
|
||||||
/* margin-bottom: 11px; */
|
|
||||||
/* background-color: var(--haughty-gray); */
|
|
||||||
border-bottom: 1px solid var(--silver-lining-white);
|
border-bottom: 1px solid var(--silver-lining-white);
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
/* box-shadow: black 1px 1px 1px 1px; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#index #content {
|
#index #content {
|
||||||
|
|
@ -116,14 +119,7 @@ body {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#index #center {
|
|
||||||
margin: var(--main-margin) var(--main-margin) auto var(--main-margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
/* width: 100%; */
|
|
||||||
/* display: flex; */
|
|
||||||
/* flex-direction: row; */
|
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
@ -172,7 +168,7 @@ div#search-bar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#index header {
|
#index > header {
|
||||||
width: min-content;
|
width: min-content;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
|
@ -233,10 +229,12 @@ footer {
|
||||||
|
|
||||||
.tag,
|
.tag,
|
||||||
.caption {
|
.caption {
|
||||||
font-family: Noto sans, sans-serif;
|
font-family: sans-serif;
|
||||||
font-weight: 600;
|
font-weight: 900;
|
||||||
color: white;
|
color: white;
|
||||||
text-decoration-line: none;
|
text-decoration-line: none;
|
||||||
|
margin: 2px;
|
||||||
|
border-radius: 3px 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
|
|
@ -244,6 +242,7 @@ footer {
|
||||||
color: var(--almost-white);
|
color: var(--almost-white);
|
||||||
text-decoration-line: none;
|
text-decoration-line: none;
|
||||||
padding: 0.13em;
|
padding: 0.13em;
|
||||||
|
background-color: var(--main-shadow);
|
||||||
|
|
||||||
&>span:first-child {
|
&>span:first-child {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
|
@ -251,9 +250,6 @@ footer {
|
||||||
border-radius: 3px 0 0 3px;
|
border-radius: 3px 0 0 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&>span:nth-child(2) {
|
|
||||||
background-color: var(--haughty-gray);
|
|
||||||
}
|
|
||||||
|
|
||||||
&>span:last-child {
|
&>span:last-child {
|
||||||
border-radius: 0 3px 3px 0;
|
border-radius: 0 3px 3px 0;
|
||||||
|
|
@ -283,6 +279,7 @@ footer {
|
||||||
.cover {
|
.cover {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
width: 11%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.caption {
|
.caption {
|
||||||
|
|
@ -292,17 +289,21 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
filter: blur(15px);
|
filter: blur(30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#index img {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.thumbnail,
|
.thumbnail,
|
||||||
.cover {
|
.cover {
|
||||||
width: 148px;
|
/* width: 148px; */
|
||||||
height: auto;
|
height: auto;
|
||||||
opacity: 0.93;
|
opacity: 0.93;
|
||||||
}
|
}
|
||||||
|
|
||||||
#search-results {
|
#index #center {
|
||||||
& #controls {
|
& #controls {
|
||||||
width: calc(min-content / 2);
|
width: calc(min-content / 2);
|
||||||
height: min-content;
|
height: min-content;
|
||||||
|
|
@ -325,9 +326,9 @@ img {
|
||||||
}
|
}
|
||||||
|
|
||||||
& #results {
|
& #results {
|
||||||
display: grid;
|
/* display: grid; */
|
||||||
width: 65%;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
width: 65%;
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
grid-template-columns: repeat(6, 1fr);
|
grid-template-columns: repeat(6, 1fr);
|
||||||
|
|
@ -349,9 +350,20 @@ img {
|
||||||
Arial,
|
Arial,
|
||||||
sans-serif;
|
sans-serif;
|
||||||
|
|
||||||
& img {
|
|
||||||
|
& #image-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 95vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
& #image-wrapper img {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
max-height: 95vh;
|
max-height: 95vh;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
/* width: auto; */
|
/* width: auto; */
|
||||||
/* height: auto; */
|
/* height: auto; */
|
||||||
}
|
}
|
||||||
|
|
@ -374,7 +386,7 @@ img {
|
||||||
font-size: large;
|
font-size: large;
|
||||||
}
|
}
|
||||||
|
|
||||||
& div {
|
& div:last-child {
|
||||||
margin-bottom: 100%;
|
margin-bottom: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue