From 6636ce6c95d4e9c21f3ecedb898768ae1b825bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Erbsh=C3=A4u=C3=9Fer?= Date: Sun, 24 May 2026 09:23:10 +0200 Subject: [PATCH] fix back button on blog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tobias Erbshäußer --- frontend/src/components/blog-article-list.njk | 10 ++++- frontend/src/components/blog-article-list.ts | 29 +++++++++---- frontend/src/components/blog-article.njk | 2 +- frontend/src/components/tag.njk | 4 ++ frontend/src/components/tag.ts | 8 ++++ frontend/src/scripts/blog.ts | 41 +++++++++++++++---- 6 files changed, 75 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/blog-article-list.njk b/frontend/src/components/blog-article-list.njk index 2e748e3..d5d3af2 100644 --- a/frontend/src/components/blog-article-list.njk +++ b/frontend/src/components/blog-article-list.njk @@ -8,7 +8,7 @@ :host > div { display: grid; - gap: var(--medium-padding); + gap: var(--large-padding); grid-template-columns: 1fr; grid-template-rows: auto 1fr auto; } @@ -36,13 +36,19 @@ display: grid; grid-template-columns: 1fr; grid-template-rows: auto auto auto; + padding: var(--medium-padding); text-decoration: none; } + .item:hover { + background-color: var(--gray); + color: unset; + } + .item > h3 { align-items: center; display: grid; - gap: var(--medium-padding); + gap: var(--large-padding); grid-auto-columns: auto; grid-auto-flow: column; justify-content: start; diff --git a/frontend/src/components/blog-article-list.ts b/frontend/src/components/blog-article-list.ts index dd82ed7..cf3680b 100644 --- a/frontend/src/components/blog-article-list.ts +++ b/frontend/src/components/blog-article-list.ts @@ -31,7 +31,7 @@ export class TesoftBlogArticleList extends TesoftComponent { this.error = shadowRoot.querySelector("tesoft-error")!; } - async load(page: number, tags: string[], onParametersChange: (page: number, tags: string[]) => void) { + async load(page: number, tags: string[]) { try { this.tagsDiv.innerHTML = ""; for (const tagName of await this.fetchTags()) { @@ -45,14 +45,22 @@ export class TesoftBlogArticleList extends TesoftComponent { this.pagination.addEventListener("update-page", (e) => { const page = (e as CustomEvent).detail.page; - onParametersChange(page, tags); - this.reload(page, tags, onParametersChange); + e.stopPropagation(); + + this.dispatchEvent(new CustomEvent("update-parameters", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + page: page, + }, + })); }); - await this.reload(page, tags, onParametersChange); + await this.reload(page, tags); } - private async reload(page: number, tags: string[], onParametersChange: (page: number, tags: string[]) => void) { + async reload(page: number, tags: string[]) { const itemsPerPage = 20; for (const tag of this.tagsDiv.children as any as TesoftTag[]) { @@ -67,8 +75,14 @@ export class TesoftBlogArticleList extends TesoftComponent { } const newTags = Array.from(tagSet); - onParametersChange(page, newTags); - this.reload(page, newTags, onParametersChange); + this.dispatchEvent(new CustomEvent("update-parameters", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + tags: newTags, + }, + })); }; if (tags.includes(tagName)) { @@ -120,6 +134,7 @@ export class TesoftBlogArticleList extends TesoftComponent { const tag = document.createElement("tesoft-tag") as TesoftTag; tag.textContent = tagName; tag.selected = ""; + tag.small = ""; tag.disabled = ""; tags.appendChild(tag); } diff --git a/frontend/src/components/blog-article.njk b/frontend/src/components/blog-article.njk index 1dd7f69..c62845f 100644 --- a/frontend/src/components/blog-article.njk +++ b/frontend/src/components/blog-article.njk @@ -27,7 +27,7 @@ .header > h1 { align-items: center; display: grid; - gap: var(--medium-padding); + gap: var(--large-padding); grid-template-columns: auto auto; grid-template-rows: auto; justify-content: start; diff --git a/frontend/src/components/tag.njk b/frontend/src/components/tag.njk index bd845df..47032da 100644 --- a/frontend/src/components/tag.njk +++ b/frontend/src/components/tag.njk @@ -15,6 +15,10 @@ padding: var(--small-padding) var(--medium-padding); } + :host([small]) tesoft-button::part(children) { + padding: 0 var(--small-padding); + } + svg { height: 2.4rem; width: 2.4rem; diff --git a/frontend/src/components/tag.ts b/frontend/src/components/tag.ts index 22a2ba4..b3a0e9f 100644 --- a/frontend/src/components/tag.ts +++ b/frontend/src/components/tag.ts @@ -58,6 +58,14 @@ export class TesoftTag extends TesoftComponent { this.setAttribute("selected", ""); } } + + set small(value: string | null) { + if (value === null) { + this.removeAttribute("small"); + } else { + this.setAttribute("small", ""); + } + } } customElements.define("tesoft-tag", TesoftTag); diff --git a/frontend/src/scripts/blog.ts b/frontend/src/scripts/blog.ts index 6b08437..48212e2 100644 --- a/frontend/src/scripts/blog.ts +++ b/frontend/src/scripts/blog.ts @@ -61,19 +61,28 @@ class BlogSite { this.parameters = parameters; } - load() { + async load() { if (this.parameters.id === null) { - this.blogArticleList.load(this.parameters.page ?? 1, this.parameters.tags, (page, tags) => { - this.parameters = new Parameters( + this.blogArticleList.addEventListener("update-parameters", (e) => { + const {page, tags} = (e as CustomEvent).detail; + e.stopPropagation(); + + window.history.pushState( null, - page, - tags, + "", + new Parameters( + null, + page ?? this.parameters.page, + tags ?? this.parameters.tags, + ).constructUrl(), ); - window.history.pushState(null, "", this.parameters.constructUrl()); + this.reload(); }); + + await this.blogArticleList.load(this.parameters.page ?? 1, this.parameters.tags); this.blogArticleList.classList.remove("hidden"); } else { - this.blogArticle.load(this.parameters.id, (tag) => { + await this.blogArticle.load(this.parameters.id, (tag) => { return new Parameters( null, null, @@ -83,14 +92,28 @@ class BlogSite { this.blogArticle.classList.remove("hidden"); } } + + async reload() { + this.parameters = Parameters.parse(new URLSearchParams(window.location.search)); + + await this.blogArticleList.reload(this.parameters.page ?? 1, this.parameters.tags); + } } onReady(async () => { + const parameters = Parameters.parse(new URLSearchParams(window.location.search)); + const blogSite = new BlogSite( document.querySelector("tesoft-blog-article")!, document.querySelector("tesoft-blog-article-list")!, - Parameters.parse(new URLSearchParams(window.location.search)), + parameters, ); - blogSite.load(); + if (parameters.id === null) { + window.addEventListener("popstate", async () => { + await blogSite.reload(); + }); + } + + await blogSite.load(); });