| -rw-r--r-- | internal/frontmatter/parser.go | 19 | ||||
| -rw-r--r-- | internal/glightbox/block.go | 5 | ||||
| -rw-r--r-- | internal/glightbox/html_renderer.go | 47 | ||||
| -rw-r--r-- | internal/glightbox/parser.go | 9 | ||||
| -rw-r--r-- | internal/router/basic-handler.go | 6 | ||||
| -rw-r--r-- | internal/router/handlers/lang-blog-title.go | 14 | ||||
| -rw-r--r-- | internal/router/handlers/lang-map.go | 8 | ||||
| -rw-r--r-- | internal/router/handlers/lang-user.go | 7 | ||||
| -rw-r--r-- | internal/router/handlers/lang.go | 8 | ||||
| -rw-r--r-- | internal/router/handlers/root.go | 7 | ||||
| -rw-r--r-- | internal/router/router.go | 12 | ||||
| -rw-r--r-- | internal/templatemanager/templatemanager.go | 3 | ||||
| -rw-r--r-- | locale/localization.en.yaml | 2 | ||||
| -rw-r--r-- | locale/localization.go | 4 | ||||
| -rw-r--r-- | locale/localization.ru.yaml | 2 | ||||
| -rw-r--r-- | static/input.css | 15 | ||||
| -rw-r--r-- | views/layouts/general-page.html | 3 | ||||
| -rw-r--r-- | views/pages/global-map.html | 29 | ||||
| -rw-r--r-- | views/pages/unsubscribe-page.html | 1 |
19 files changed, 141 insertions, 60 deletions
diff --git a/internal/frontmatter/parser.go b/internal/frontmatter/parser.go index 83312dc..6062113 100644 --- a/internal/frontmatter/parser.go +++ b/internal/frontmatter/parser.go @@ -9,15 +9,16 @@ import ( ) type Metadata struct { - Title string `yaml:"title"` - ShortDescription string `yaml:"shortDescription"` - ActionDate string `yaml:"actionDate"` - PublishedTime time.Time `yaml:"publishedTime"` - Thumbnail string `yaml:"thumbnail"` - Tags []string `yaml:"tags"` - Geolocation string `yaml:"geolocation"` - Medley string `yaml:"medley"` - MedleyPart int `yaml:"medleyPart"` + Title string `yaml:"title"` + ShortDescription string `yaml:"shortDescription"` + ActionDate string `yaml:"actionDate"` + PublishedTime time.Time `yaml:"publishedTime"` + Thumbnail string `yaml:"thumbnail"` + Tags []string `yaml:"tags"` + Geolocation string `yaml:"geolocation"` + Medley string `yaml:"medley"` + MedleyPart int `yaml:"medleyPart"` + ContentSettings map[string]string `yaml:"contentSettings"` } func ParseFrontmatter(content []byte) (metadata *Metadata, markdown []byte, err error) { diff --git a/internal/glightbox/block.go b/internal/glightbox/block.go index e53e67b..30cda1c 100644 --- a/internal/glightbox/block.go +++ b/internal/glightbox/block.go @@ -9,8 +9,9 @@ import ( // GLightboxBlock represents a light gallery block in the AST type GLightboxBlock struct { ast.BaseBlock - Images []GLightboxImage - Location *time.Location + Images []GLightboxImage + Location *time.Location + Namespace string } type GLightboxImage struct { diff --git a/internal/glightbox/html_renderer.go b/internal/glightbox/html_renderer.go index b7b256a..ac34880 100644 --- a/internal/glightbox/html_renderer.go +++ b/internal/glightbox/html_renderer.go @@ -68,7 +68,8 @@ func (r *GLightboxHTMLRenderer) renderGLightbox(w util.BufWriter, source []byte, var elements []string for i, img := range gallery.Images { - imageUrlSegments := strings.Split(img.URL, ".") + fullImageUrl := gallery.Namespace + img.URL + imageUrlSegments := strings.Split(fullImageUrl, ".") imageUrlWithoutExt := strings.Join(imageUrlSegments[:len(imageUrlSegments)-1], ".") imageUrlParts := strings.Split(imageUrlWithoutExt, "/") imageNameParts := strings.Split(imageUrlParts[len(imageUrlParts)-1], "-") @@ -122,7 +123,7 @@ func (r *GLightboxHTMLRenderer) renderGLightbox(w util.BufWriter, source []byte, </picture> <span class="grid-tooltip-text"><p>%s</p></span> <span class="grid-item-index">%d</span> - </a>`, img.URL, strings.Join(tagClassList, " "), galleryID, dayDate.Format("2006-01-02 15:04:05 -07:00"), dataDescriptionAttribute, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, anchorlessCaptionHTML, i+1)) + </a>`, fullImageUrl, strings.Join(tagClassList, " "), galleryID, dayDate.Format("2006-01-02 15:04:05 -07:00"), dataDescriptionAttribute, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, anchorlessCaptionHTML, i+1)) if glightboxDescId != "" { elements = append(elements, fmt.Sprintf(` @@ -132,43 +133,43 @@ func (r *GLightboxHTMLRenderer) renderGLightbox(w util.BufWriter, source []byte, } } - w.WriteString(fmt.Sprintf(` + w.WriteString(strings.ReplaceAll(` <div class="items-center flex flex-col"> <hr class="border-t-3 border-dotted border-main-hard mt-1 mb-2 w-[80%%] ml-auto mr-auto"> - <div class="grid masonry-grid-%s"> - <div class="grid-sizer grid-sizer-%s"></div> - %s + <div class="grid masonry-grid-{id}"> + <div class="grid-sizer grid-sizer-{id}"></div> + `+strings.Join(elements, "\n")+` </div> <hr class="border-t-3 border-dotted border-main-hard mt-1 mb-2 w-[80%%] ml-auto mr-auto"> -</div>`, galleryID, galleryID, strings.Join(elements, "\n"))) +</div> - w.WriteString(fmt.Sprintf(` <script> - var pckry_%s = new Packery('.masonry-grid-%s', { - itemSelector: '.grid-item-%s', - columnWidth: '.grid-sizer-%s', + var pckry_{id} = new Packery('.masonry-grid-{id}', { + itemSelector: '.grid-item-{id}', + columnWidth: '.grid-sizer-{id}', percentPosition: false }); - var imgLoad_%s_timer; - var imgLoad_%s = imagesLoaded('.masonry-grid-%s'); + var imgLoad_{id}_timer; + var imgLoad_{id} = imagesLoaded('.masonry-grid-{id}'); - function initMasonryLayout_%s(tm) { - clearTimeout(imgLoad_%s_timer); - imgLoad_%s_timer = setTimeout(() => pckry_%s.layout(), 100); + function initMasonryLayout_{id}(tm) { + clearTimeout(imgLoad_{id}_timer); + imgLoad_{id}_timer = setTimeout(() => pckry_{id}.layout(), 100); } - imgLoad_%s.on('progress', initMasonryLayout_%s); + imgLoad_{id}.on('progress', initMasonryLayout_{id}); - window.addEventListener('resize', initMasonryLayout_%s); + window.addEventListener('resize', initMasonryLayout_{id}); document.addEventListener('popout', (e) => { - window.removeEventListener('resize', initMasonryLayout_%s); - imgLoad_%s.off('progress', initMasonryLayout_%s); - initMasonryLayout_%s = null; - imgLoad_%s = null; + window.removeEventListener('resize', initMasonryLayout_{id}); + imgLoad_{id}.off('progress', initMasonryLayout_{id}); + initMasonryLayout_{id} = null; + imgLoad_{id} = null; }, {once: true}); -</script>`, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID, galleryID)) +</script> +`, "{id}", galleryID)) } return ast.WalkContinue, nil diff --git a/internal/glightbox/parser.go b/internal/glightbox/parser.go index 6780090..b376034 100644 --- a/internal/glightbox/parser.go +++ b/internal/glightbox/parser.go @@ -29,7 +29,7 @@ func (p *GLightboxParser) Open(parent ast.Node, reader text.Reader, pc parser.Co return nil, parser.NoChildren } - r := regexp.MustCompile(`^\{Gallery:([A-Za-z0-9\+\-/]+)\}$`) + r := regexp.MustCompile(`^\{Gallery:([A-Za-z0-9\+\-/]+)(:([A-Za-z0-9\+\-/]+))?\}$`) trimmed := bytes.TrimSpace(line) parts := r.FindSubmatch(trimmed) @@ -44,7 +44,12 @@ func (p *GLightboxParser) Open(parent ast.Node, reader text.Reader, pc parser.Co return nil, parser.NoChildren } - return &GLightboxBlock{Location: loc}, parser.NoChildren + ns := "" + if len(parts) >= 4 { + ns = string(parts[3]) + } + + return &GLightboxBlock{Location: loc, Namespace: ns}, parser.NoChildren } func (p *GLightboxParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State { diff --git a/internal/router/basic-handler.go b/internal/router/basic-handler.go index a859d10..4a94a48 100644 --- a/internal/router/basic-handler.go +++ b/internal/router/basic-handler.go @@ -41,6 +41,12 @@ func (r *BasicHandler) Render(c *fiber.Ctx, supplements *Supplements, lang strin return fiber.StatusNoContent, nil } +func (r *BasicHandler) AddMeta(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) { + return map[string]string{ + "robots": "noindex,nofollow", + }, nil +} + func (r *BasicHandler) RenderHeader(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { return fiber.StatusNoContent, nil } diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go index 0f4f564..97de089 100644 --- a/internal/router/handlers/lang-blog-title.go +++ b/internal/router/handlers/lang-blog-title.go @@ -46,6 +46,20 @@ func (r *BlogPageHandler) ToValidateLang() router.LangSetting { return router.InPath } +func (r *BlogPageHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) { + metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + c.Params("title") + ".md") + if err != nil { + return nil, fmt.Errorf("failed to read frontmatter of the desired blog post: %w", err) + } + + return map[string]string{ + "og:title": metadata.Title, + "og:description": fmt.Sprintf("%s [%s]", metadata.ShortDescription, metadata.ActionDate), + "og:image": fmt.Sprintf("https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp", metadata.Thumbnail), + "twitter:card": "summary_large_image", + }, nil +} + func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { _, pathParts, _, err := router.GetPathFromReferer(c) if err != nil { diff --git a/internal/router/handlers/lang-map.go b/internal/router/handlers/lang-map.go index dbf1437..7df6104 100644 --- a/internal/router/handlers/lang-map.go +++ b/internal/router/handlers/lang-map.go @@ -3,6 +3,7 @@ package handlers import ( "fmt" "log/slog" + "slices" "strconv" "strings" @@ -41,6 +42,9 @@ func (r *MapHandler) ToValidateLang() router.LangSetting { func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { pages, err := supplements.B2Client.Scan(lang + "/") + slices.SortFunc(pages, func(a *b2.BlogPage, b *b2.BlogPage) int { + return a.Metadata.PublishedTime.Compare(b.Metadata.PublishedTime) + }) status := fiber.StatusOK if err != nil { slog.Error("received an error while scanning b2 pages", @@ -52,6 +56,7 @@ func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang } type MapMarker struct { + Index int `json:"Index"` Title string `json:"Title"` PageLink string `json:"PageLink"` Lat float64 `json:"Lat"` @@ -61,7 +66,7 @@ func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang } mapMarkers := make([]*MapMarker, 0, len(pages)) - for _, page := range pages { + for i, page := range pages { geolocationParts := strings.Split(page.Metadata.Geolocation, " ") if len(geolocationParts) < 2 { continue @@ -78,6 +83,7 @@ func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang } mapMarkers = append(mapMarkers, &MapMarker{ + Index: i, Title: page.Metadata.Title, PageLink: fmt.Sprintf("/%s/blog/%s", lang, page.FileName), Lat: x, diff --git a/internal/router/handlers/lang-user.go b/internal/router/handlers/lang-user.go index db566fe..c22bcac 100644 --- a/internal/router/handlers/lang-user.go +++ b/internal/router/handlers/lang-user.go @@ -37,6 +37,13 @@ func (r *UserHandler) ToValidateLang() router.LangSetting { return router.InPath } +func (r *UserHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) { + return map[string]string{ + "og:title": supplements.Localization[lang].BlogSearch.Header, + "og:description": supplements.Localization[lang].BlogSearch.Description, + }, nil +} + func (r *UserHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { templateMap["Title"] = supplements.Localization[lang].UserProfile.Header diff --git a/internal/router/handlers/lang.go b/internal/router/handlers/lang.go index fc4deb6..74166ae 100644 --- a/internal/router/handlers/lang.go +++ b/internal/router/handlers/lang.go @@ -41,6 +41,14 @@ func (r *HomeHandler) ToValidateLang() router.LangSetting { return router.InPath } +func (r *HomeHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) { + return map[string]string{ + "og:title": supplements.Localization[lang].HomePage.Header, + "og:description": supplements.Localization[lang].HomePage.HomePageDescription, + "og:image": "https://f003.backblazeb2.com/file/sayana-static/home-page-gifs/" + fmt.Sprintf("otter-%d.gif", rand.Int()%3+1), + }, nil +} + func (r *HomeHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { templateMap["Title"] = supplements.Localization[lang].HomePage.Header templateMap["FilledHeartCount"] = uint(40) diff --git a/internal/router/handlers/root.go b/internal/router/handlers/root.go index c8c4cd4..9f15782 100644 --- a/internal/router/handlers/root.go +++ b/internal/router/handlers/root.go @@ -35,6 +35,13 @@ func (r *RootHandler) CacheDuration() time.Duration { return 24 * time.Hour } +func (r *RootHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) { + return map[string]string{ + "og:title": "Saya Blog", + "og:description": "The blog of a 25 years old, travelling God knows where, proud to be not mainstream // Личный блог 25-летки, странствующего по ебеням, зато не мейнстрим", + }, nil +} + func (r *RootHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, _ string, templateMap fiber.Map) (statusCode int, err error) { templateMap["Title"] = "Choose Your Language" templateMap["AvailableLanguages"] = supplements.AvailableLanguages diff --git a/internal/router/router.go b/internal/router/router.go index c0556f0..f28add2 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -60,6 +60,7 @@ type Route interface { ToValidateLang() LangSetting TemplatesToInject() []string Render(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) + AddMeta(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) RenderHeader(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) RenderBody(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) RenderFooter(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) @@ -382,11 +383,18 @@ func (r *Router) generalPage(c *fiber.Ctx, route Route, lang string) error { return c.Status(fiber.StatusOK).Type("html").Send(val) } - content, err := r.supplements.TemplateManager.Render("general-page", fiber.Map{ + valueMap := fiber.Map{ "L": r.supplements.Localization[lang], "Lang": lang, "QueryString": queryString, - }) + } + + var err error + if valueMap["Meta"], err = route.AddMeta(c, r.supplements, lang, valueMap); err != nil { + slog.Warn("failed to receive meta", slog.String("path", path), slog.String("error", err.Error())) + } + + content, err := r.supplements.TemplateManager.Render("general-page", valueMap) if err != nil { slog.Warn("failed to generate div", slog.String("path", path), slog.String("error", err.Error())) return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div") diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go index 75309e4..b23e2e8 100644 --- a/internal/templatemanager/templatemanager.go +++ b/internal/templatemanager/templatemanager.go @@ -32,6 +32,9 @@ var templateFuncMap = template.FuncMap{ return items }, "replace": strings.ReplaceAll, + "fdiv": func(a, b int) float64 { + return float64(a) / float64(b) + }, } func NewTemplateManager(templates ...TemplateManagerTemplates) (*TemplateManager, error) { diff --git a/locale/localization.en.yaml b/locale/localization.en.yaml index c7f2df8..e165866 100644 --- a/locale/localization.en.yaml +++ b/locale/localization.en.yaml @@ -1,6 +1,7 @@ TagsLabel: 'Tags:' BlogSearch: Header: 'Blog Search' + Description: "The Saya Blog posts' list" TagsHeader: 'Tags' OrderByHeader: 'Order by...' TitleOrdered: 'Title' @@ -9,6 +10,7 @@ BlogSearch: ChooseAllTags: 'Choose All' GlobalMap: Header: 'Global Map' + Description: "Global map with all the tags of places I've been to" HomePage: Header: 'Home Page' Contacts: 'Contacts' diff --git a/locale/localization.go b/locale/localization.go index c6467c4..a4f36f1 100644 --- a/locale/localization.go +++ b/locale/localization.go @@ -20,6 +20,7 @@ type LocaleConfig struct { type BlogSearchConfig struct { Header string `yaml:"Header" json:"Header"` + Description string `yaml:"Description" json:"Description"` TagsHeader string `yaml:"TagsHeader" json:"TagsHeader"` OrderByHeader string `yaml:"OrderByHeader" json:"OrderByHeader"` TitleOrdered string `yaml:"TitleOrdered" json:"TitleOrdered"` @@ -29,7 +30,8 @@ type BlogSearchConfig struct { } type GlobalMapConfig struct { - Header string `yaml:"Header" json:"Header"` + Header string `yaml:"Header" json:"Header"` + Description string `yaml:"Description" json:"Description"` } type HomePageConfig struct { diff --git a/locale/localization.ru.yaml b/locale/localization.ru.yaml index 5df82da..e65848a 100644 --- a/locale/localization.ru.yaml +++ b/locale/localization.ru.yaml @@ -1,6 +1,7 @@ TagsLabel: 'Тэги:' BlogSearch: Header: 'Поиск по блогу' + Description: 'Каталог записей Saya Blog' TagsHeader: 'Тэги' OrderByHeader: 'Упорядочить по...' TitleOrdered: 'названию' @@ -9,6 +10,7 @@ BlogSearch: ChooseAllTags: 'Выбрать все' GlobalMap: Header: 'Глобальная карта' + Description: 'Глобальная карта с метками мест, где я побывал' HomePage: Header: 'Домашняя страница' Contacts: 'Контакты' diff --git a/static/input.css b/static/input.css index 66d832c..40082c8 100644 --- a/static/input.css +++ b/static/input.css @@ -21,6 +21,11 @@ html { --split-right-position: left; } +body { + scrollbar-width: thin; + scrollbar-color: var(--background-light-color) var(--main-soft-color); +} + @media screen and (min-width: 640px) and (min-height: 640px) { html { font-size: 14px; @@ -76,8 +81,8 @@ html { [data-theme="lettuce"] { --main-dark-color-hard: #384a0c; - --main-dark-color-medium: #9bb665; - --main-dark-color-soft: #bbd095; + --main-dark-color-medium: #617c1f; + --main-dark-color-soft: #9bb665; --main-light-color-soft: #f5eee2; --main-light-color-medium: var(--background-dark-color); --main-light-color-hard: #fff9ef; @@ -93,9 +98,9 @@ html { --leaflet-text-color: var(--main-hard-color); --leaflet-link-color: var(--main-medium-color); --leaflet-link-hover-color: var(--main-soft-color); - --interlocked-hexagons-background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23f5ede1%22%2F%3E%3Cpath%20fill%3D%22%239ab663%22%20d%3D%22m33.64%200-.17.25h-33L4.3%206h33.07l4-6zm8.33%200-4.33%206.5h-33l3.83%205.75h33.06L49.7%200zm8.34%200-8.5%2012.75h-33l3.83%205.75H45.7L58.03%200zm8.33%200L45.97%2019h-33l3.83%205.75h33.06L66.36%200zm-8.5%2025.25L33.63%2050l3.86%205.8L54.03%2031h33l-3.83-5.75zm4.16%206.25L37.8%2056.25l3.87%205.8%2016.53-24.8h33l-3.84-5.75zm4.17%206.25L41.97%2062.5l3.86%205.8%2016.54-24.8h33l-3.84-5.75zM62.63%2044l-16.5%2024.75%203.87%205.8%2016.53-24.8h33L95.7%2044zM100%2050.45l-3.87%205.8%203.87%205.81v-11.6zM0%2050.46v11.6L12.5%2080.8l3.86-5.8zm95.83%206.25-3.87%205.8L100%2074.55v-11.6zm-4.17%206.24-3.86%205.8%2012.2%2018.3v-11.6zM0%2062.96v11.6l8.33%2012.49%203.86-5.8zm87.5%206.24L83.63%2075%20100%2099.54V87.96zM50%2075.45%2033.64%20100h7.72l12.5-18.75zm-50%200v11.6l4.16%206.24%203.87-5.8zm54.17%206.25L41.97%20100h7.73l8.33-12.5zm4.17%206.25L50.3%20100h7.73l4.17-6.25zM0%2087.95v11.59l3.86-5.8zm62.5%206.25-3.87%205.8h7.73z%22%2F%3E%3Cpath%20fill%3D%22%23bbd095%22%20d%3D%22M66.8.25%2062.97%206h33l4.03%206.05V.45l-.14-.2zM0%20.45v11.61L12.5%2030.8l3.86-5.8zM62.63%206.5l-3.83%205.75h33l8.2%2012.3v-11.6L95.7%206.5zm-4.16%206.25-3.84%205.75h33L100%2037.06v-11.6l-8.47-12.71zM0%2012.96v11.6l8.33%2012.49%203.86-5.8zM54.3%2019l-3.84%205.75h33L100%2049.55l.01-.01V37.96L87.36%2019zm-4.77%206.25H41.8L25.3%2050l16.66%2025-16.5%2024.75h7.74L49.7%2075%2033.03%2050zm-8.33%200h-7.74L16.96%2050l16.67%2025-16.5%2024.75h7.73L41.36%2075%2024.7%2050Zm-8.34%200h-7.73L8.63%2050%2025.3%2075%208.8%2099.75h7.73L33.03%2075%2016.36%2050zm-16.07%200L.3%2050l16.67%2025L.46%2099.75H8.2L24.7%2075%208.02%2050l16.5-24.75zM0%2025.46v11.6l4.16%206.24%203.87-5.8zm0%2012.5v11.58l3.86-5.79zm66.8%2012.29L50.3%2074.99l3.87%205.81%204.16%206.25%204.17%206.25%204.3%206.45h7.73L58.03%2075l16.5-24.75zm16.06%200h-7.73L58.63%2075l16.5%2024.75h7.73L66.36%2075zm.6%200L66.96%2075l16.5%2024.75h7.74L74.7%2075l16.5-24.75zm16.07%200H91.8L75.3%2075l16.5%2024.75h7.73L83.03%2075z%22%2F%3E%3C%2Fsvg%3E"); - --interlocked-hexagons-background-repeat: repeat; - --interlocked-hexagons-background-size: 10dvh; + --interlocked-hexagons-background: url('https://f003.backblazeb2.com/file/sayana-static/themes/lettuce/linen-fabric.webp'), url('https://f003.backblazeb2.com/file/sayana-static/themes/lettuce/lettuce-tiles.svg'); + --interlocked-hexagons-background-repeat: repeat, repeat; + --interlocked-hexagons-background-size: 11dvh, 20dvh; --squares-and-triangles-background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23bbd095%22%2F%3E%3Cpath%20fill%3D%22%23f5ede1%22%20d%3D%22M0%200v6.77L6.72%200zm8.91%200L0%208.96v3.86L12.83%200zm6.11%200L0%2015.06v3.87L18.9%200zm6.11%200L0%2021.12v3.92L25%200zM25%200l25%2024.99v-3.87L28.87%200zm25%2024.99%2025%2024.98L100%2025%2075%200zm-50%20.05v3.87l21.13%2021.12H25l-25-25zm25%2024.99h3.87L50%2028.9v-3.87zm0%200L0%2075l25%2025%2025-24.99zM50%2075l25-24.98h-3.87L50%2071.14v3.87zm0%200v3.87L71.13%20100H75L50%2075.01zm25%2025h3.87L100%2078.88v-3.87zm25-24.99v-3.87L78.87%2050.03H75L100%2075zM31.1%200%2050%2018.93v-3.87L34.98%200h-3.87zm6.07%200L50%2012.82V8.96L41.04%200zm6.1%200L50%206.77V0h-6.72zM25%202.19%202.14%2025.04H25zm0%2022.85v22.8l22.81-22.8zM75%203.92l21.13%2021.12L75%2046.16%2053.87%2025.04zm0%202.19L56.06%2025.04l18.89%2018.88%2018.94-18.88L75%206.1zm0%203.92%2015.07%2015L75%2040.06%2059.98%2025.04zm0%202.18L62.17%2025.04%2075%2037.86l12.83-12.82L75%2012.2zm0%203.82%208.96%209L75%2033.95%2066.04%2025zm0%202.24-6.72%206.77L75%2031.76l6.77-6.72h-.05zM0%2031.09v3.87l15.02%2015.07h3.87zm50%200L31.1%2050.03h3.88L50%2034.96V31.1zM0%2037.2v3.87l8.91%208.96h3.92zm50%200L37.17%2050.03h3.87L50%2041.07zM0%2043.3v6.73h6.72zm50%200-6.72%206.73H50zm0%206.73v6.71l6.72-6.71zm8.96%200L50%2058.93v3.92l12.83-12.82zm6.06%200L50%2065.03v3.88l18.94-18.88zm16.09%200L100%2068.9v-3.87l-15.02-15zm6.11%200L100%2062.85v-3.92l-8.91-8.9zm6.06%200%206.72%206.71v-6.71zM75%2052.2%2052.19%2075H75zM75%2075v22.8L97.81%2075zM25%2053.9l21.13%2021.12L25%2096.13%203.87%2075.01zm0%202.2L6.1%2074.95l18.95%2018.88%2018.9-18.88L25%2056.08zm0%203.9%2015.02%2015.01L25%2090.03%209.98%2075zm0%202.19L12.17%2075%2025%2087.84%2037.83%2075%2025%2062.2zm0%203.87L33.96%2075%2025%2083.97%2016.04%2075zm0%202.23-6.72%206.72L25%2081.73l6.72-6.72L25%2068.3zm25%2012.83v3.87L65.02%20100h3.87zm50%200L81.1%20100h3.88L100%2084.99zm-50%206.06v3.86l8.96%208.96h3.87zm50%200L87.22%20100h3.87l8.91-8.96zm-50%206.1V100h6.72zm50%200L93.28%20100H100z%22%2F%3E%3C%2Fsvg%3E"); --squares-and-triangles-background-repeat: repeat; --squares-and-triangles-background-width-coef: 10; diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html index 01043c6..3f5bcfd 100644 --- a/views/layouts/general-page.html +++ b/views/layouts/general-page.html @@ -3,6 +3,9 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> + {{- range $k, $v := .Meta }} + <meta name="{{ $k }}" content="{{ $v }}"> + {{- end }} <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"> <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.css"> <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/glightbox/3.3.0/css/glightbox.min.css"> diff --git a/views/pages/global-map.html b/views/pages/global-map.html index 7d788d6..4b07bd2 100644 --- a/views/pages/global-map.html +++ b/views/pages/global-map.html @@ -3,6 +3,8 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="og:title" content="{{ .L.GlobalMap.Header }}"> + <meta name="og:description" content="{{ .L.GlobalMap.Description }}"> <title>{{ .L.GlobalMap.Header }} // SAYA TODAY</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"> {{ block "header" . }}{{ end }} @@ -243,35 +245,32 @@ map.addLayer(markers); } - function stringToColor(str) { + function markerToHsl(str, newCoef) { let hash = 0; - for (let i = 0; i < str.length; i++) { + for (let i = 0; i < str.length / 2; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); + hash = str.charCodeAt(str.length - i - 1) + ((hash << 5) - hash); + hash %= 360; } - let color = '#'; - for (let i = 0; i < 3; i++) { - const value = (hash >> (i * 8)) & 0xFF; - color += ('00' + value.toString(16)).substr(-2); - } - - return color; + return [hash, (20 + newCoef * 80).toFixed(0), (20 + newCoef * 75).toFixed(0)]; } - function mapAddMarker(x, y, relativeErrorMeters = 0, title = "", link = "", thumbnail = "") { - const titleColor = stringToColor(title); + function mapAddMarker(x, y, relativeErrorMeters = 0, title = "", link = "", thumbnail = "", newCoef = 1) { + const [h, s, l] = markerToHsl(title, newCoef); + const color = `hsl(${h} ${s}% ${l}%)`; if (relativeErrorMeters != 0) { var circle = L.circle([x, y], { - color: titleColor, - fillColor: titleColor, + color: color, + fillColor: color, fillOpacity: 0.15, radius: relativeErrorMeters }).addTo(map); } var marker = L.marker([x, y], { - icon: createCustomIcon(titleColor), + icon: createCustomIcon(color), title: title, }).bindPopup(` <div class="flex flex-row justify-center justify-items-center"> @@ -285,7 +284,7 @@ document.addEventListener('DOMContentLoaded', () => { initLocationMap(); {{- range .MapMarkers }} - mapAddMarker({{ .Lat }}, {{ .Long }}, {{ .AccuracyMeters }}, {{ .Title }}, {{ .PageLink }}, {{ .Thumbnail }}); + mapAddMarker({{ .Lat }}, {{ .Long }}, {{ .AccuracyMeters }}, {{ .Title }}, {{ .PageLink }}, {{ .Thumbnail }}, {{ fdiv .Index (len $.MapMarkers) }}); {{- end }} }); diff --git a/views/pages/unsubscribe-page.html b/views/pages/unsubscribe-page.html index 3876818..c1db9d6 100644 --- a/views/pages/unsubscribe-page.html +++ b/views/pages/unsubscribe-page.html @@ -3,6 +3,7 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="robots" content="noindex,nofollow"> <title>{{ .L.UnsubscribePage.Header }} // SAYA TODAY</title> <style> html { |