Filter location tags
This commit is contained in:
parent
72fda72de5
commit
62e7ccf17b
5 changed files with 93 additions and 47 deletions
|
@ -22,7 +22,7 @@ function addPopoverStyle() {
|
|||
document.querySelectorAll("[popovertarget]").forEach(e => {
|
||||
e.addEventListener("click", () => {
|
||||
const rect = e.getBoundingClientRect()
|
||||
const width = Math.floor(rect.width + 85)
|
||||
const width = 266
|
||||
const left = Math.max(Math.floor(rect.left + rect.width / 2), width / 2)
|
||||
const t = `:popover-open { position: fixed; top: ${Math.floor(rect.bottom)}px; left: ${left}px; width: ${width}px; transform: translateX(-50%); margin: 0 }`
|
||||
document.styleSheets[0].insertRule(t, document.styleSheets[0].cssRules.length)
|
||||
|
|
|
@ -44,6 +44,28 @@ html
|
|||
.ml6 Switch account
|
||||
li.s-menu--divider(role="separator")
|
||||
li.s-menu--title Settings
|
||||
li(role="menuitem")
|
||||
if arrange === "tag"
|
||||
form.s-block-link.d-flex.ai-center(hx-post="/api/settings/location-tags" hx-trigger="change" hx-indicator="#location-tags-loading" hx-select="#tag-page" hx-target="#tag-page")
|
||||
span.fl-grow1.d-flex.ai-center
|
||||
!= icons.get("map-pin")
|
||||
.pl6 Region tags
|
||||
#location-tags-loading
|
||||
input(type="hidden" name="account" value=account)
|
||||
.s-toggle-switch.s-toggle-switch__multiple
|
||||
- const locationTagsSetting = h3.getCookie(event, "bcex-location-tags") || "all"
|
||||
input#location-tags-all(type="radio" name="location_tags" value="all" autocomplete="off" checked=(locationTagsSetting === "all"))
|
||||
label.px8.py6(for="location-tags-all") All
|
||||
input#location-tags-hide(type="radio" name="location_tags" value="hide" autocomplete="off" checked=(locationTagsSetting === "hide"))
|
||||
label.px8.py6(for="location-tags-hide") Hide
|
||||
input#location-tags-only(type="radio" name="location_tags" value="only" autocomplete="off" checked=(locationTagsSetting === "only"))
|
||||
label.px8.py6(for="location-tags-only") Only
|
||||
else
|
||||
.s-block-link.d-flex.ai-center
|
||||
span.fl-grow1.d-flex.ai-center.fc-black-400
|
||||
!= icons.get("map-pin")
|
||||
.pl6 Region tags
|
||||
a.fc-black-400.td-underline(href=and({arrange: "tag"})) Set on tags view
|
||||
li(role="menuitem")
|
||||
form.s-block-link.d-flex.ai-center(hx-post="/api/settings/inline-player" hx-trigger="change" hx-indicator="#inline-player-loading")
|
||||
label.fl-grow1.d-flex.ai-center
|
||||
|
@ -52,7 +74,7 @@ html
|
|||
#inline-player-loading
|
||||
input.s-toggle-switch#inline-player-switch(type="checkbox" name="inline_player" checked=(h3.getCookie(event, "bcex-inline-player-disabled") !== "true"))
|
||||
li(role="menuitem")
|
||||
form.s-block-link.d-flex.ai-center(hx-post="/api/settings/currency" hx-trigger="change" hx-select="#collection-stats" hx-target="#collection-stats" hx-indicator="#currency-loading")
|
||||
form.s-block-link.py2.d-flex.ai-center(hx-post="/api/settings/currency" hx-trigger="change" hx-select="#collection-stats" hx-target="#collection-stats" hx-indicator="#currency-loading")
|
||||
label.fl-grow1(for="currency-select").d-flex.ai-center
|
||||
!= icons.get("coins")
|
||||
.pl6 Currency
|
||||
|
|
|
@ -4,47 +4,56 @@ block title
|
|||
- title = `Tags | ${title}`
|
||||
|
||||
block view
|
||||
script
|
||||
| var items =
|
||||
!= JSON.stringify(items)
|
||||
| ; var filter_field =
|
||||
!= JSON.stringify(filter_field || null)
|
||||
.mx-auto.w100.wmx11.fs-body1
|
||||
.word-cloud(style="cursor: default")
|
||||
script.
|
||||
setTimeout(() => {
|
||||
const content = document.querySelector(".word-cloud")
|
||||
content.style.height = `${Math.round(Math.min(content.clientWidth, window.innerHeight)*0.8)}px`
|
||||
const dark = window.matchMedia?.("(prefers-color-scheme: dark)").matches
|
||||
WordCloud(content, {
|
||||
list: items,
|
||||
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif',
|
||||
fontWeight: "bold",
|
||||
color: dark ? "random-light": "random-dark",
|
||||
minSize: 4,
|
||||
gridSize: Math.round(content.clientWidth / 200),
|
||||
weightFactor: size => size * content.clientWidth / 180,
|
||||
rotateRatio: 0,
|
||||
click: item => {
|
||||
const highlightedItem = document.querySelector(".wc-hl")?.textContent || item[0]
|
||||
const newURL = new URL(location)
|
||||
newURL.searchParams.set("filter", highlightedItem)
|
||||
newURL.searchParams.set("filter_field", "tag")
|
||||
newURL.searchParams.delete("filter_fuzzy")
|
||||
newURL.searchParams.set("arrange", filter_field ? "album" : "label")
|
||||
content.setAttribute("hx-push-url", newURL) // workaround for https://github.com/bigskysoftware/htmx/issues/2744
|
||||
htmx.ajax("GET", newURL.search, {context: content, source: content})
|
||||
}
|
||||
#tag-page
|
||||
script
|
||||
-
|
||||
const locationTags = location_tags || h3.getCookie(event, "bcex-location-tags") || "all"
|
||||
const filteredItems = items.filter(item => {
|
||||
if (locationTags === "all") return true
|
||||
const isLocation = item[0][0].match(/[A-Z]/)
|
||||
if (locationTags === "only") return isLocation
|
||||
else return !isLocation
|
||||
})
|
||||
content.style.background = "none"
|
||||
content.addEventListener("wordcloudstop", () => {
|
||||
for (const child of content.children) {
|
||||
child.addEventListener("mouseenter", () => {
|
||||
child.classList.add("wc-hl")
|
||||
})
|
||||
child.addEventListener("mouseleave", () => {
|
||||
child.classList.remove("wc-hl")
|
||||
})
|
||||
}
|
||||
| var items =
|
||||
!= JSON.stringify(filteredItems)
|
||||
| ; var filter_field =
|
||||
!= JSON.stringify(filter_field || null)
|
||||
.mx-auto.w100.wmx11.fs-body1
|
||||
.word-cloud(style="cursor: default")
|
||||
script.
|
||||
setTimeout(() => {
|
||||
const content = document.querySelector(".word-cloud")
|
||||
content.style.height = `${Math.round(Math.min(content.clientWidth, window.innerHeight)*0.8)}px`
|
||||
const dark = window.matchMedia?.("(prefers-color-scheme: dark)").matches
|
||||
WordCloud(content, {
|
||||
list: items,
|
||||
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif',
|
||||
fontWeight: "bold",
|
||||
color: dark ? "random-light": "random-dark",
|
||||
minSize: 4,
|
||||
gridSize: Math.round(content.clientWidth / 200),
|
||||
weightFactor: size => size * content.clientWidth / 180,
|
||||
rotateRatio: 0,
|
||||
click: item => {
|
||||
const highlightedItem = document.querySelector(".wc-hl")?.textContent || item[0]
|
||||
const newURL = new URL(location)
|
||||
newURL.searchParams.set("filter", highlightedItem)
|
||||
newURL.searchParams.set("filter_field", "tag")
|
||||
newURL.searchParams.delete("filter_fuzzy")
|
||||
newURL.searchParams.set("arrange", filter_field ? "album" : "label")
|
||||
content.setAttribute("hx-push-url", newURL) // workaround for https://github.com/bigskysoftware/htmx/issues/2744
|
||||
htmx.ajax("GET", newURL.search, {context: content, source: content})
|
||||
}
|
||||
})
|
||||
content.style.background = "none"
|
||||
content.addEventListener("wordcloudstop", () => {
|
||||
for (const child of content.children) {
|
||||
child.addEventListener("mouseenter", () => {
|
||||
child.classList.add("wc-hl")
|
||||
})
|
||||
child.addEventListener("mouseleave", () => {
|
||||
child.classList.remove("wc-hl")
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
const {z} = require("zod")
|
||||
|
||||
const account = z.string().regex(/^[a-z0-9_-]+$/)
|
||||
|
||||
const schema = {
|
||||
appQuery: z.object({
|
||||
arrange: z.enum(["album", "artist", "label", "tag", "track"]),
|
||||
|
@ -11,11 +13,11 @@ const schema = {
|
|||
filter_fuzzy: z.enum(["true"]).optional()
|
||||
}),
|
||||
account: z.object({
|
||||
account: z.string().regex(/^[a-z0-9_-]+$/)
|
||||
account
|
||||
}),
|
||||
postCurrency: z.object({
|
||||
currency: z.string().regex(/^[A-Z]{3}$/),
|
||||
account: z.string()
|
||||
account
|
||||
}),
|
||||
play: z.object({
|
||||
item_type: z.enum(["album", "track"]),
|
||||
|
@ -24,6 +26,10 @@ const schema = {
|
|||
}),
|
||||
inlinePlayer: z.object({
|
||||
inline_player: z.string().optional()
|
||||
}),
|
||||
locationTags: z.object({
|
||||
location_tags: z.enum(["all", "hide", "only"]),
|
||||
account
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// @ts-check
|
||||
|
||||
const {sync, router} = require("../passthrough")
|
||||
const {defineEventHandler, readValidatedBody, setCookie, setResponseHeader} = require("h3")
|
||||
const {defineEventHandler, readValidatedBody, setCookie, setResponseHeader, sendRedirect} = require("h3")
|
||||
|
||||
/** @type {import("../pug-sync")} */
|
||||
const pugSync = sync.require("../pug-sync")
|
||||
|
||||
/** @type {import("./schema")} */
|
||||
const schema = sync.require("./schema")
|
||||
|
@ -12,3 +15,9 @@ router.post("/api/settings/inline-player", defineEventHandler(async event => {
|
|||
setResponseHeader(event, "HX-Refresh", "true")
|
||||
return null
|
||||
}))
|
||||
|
||||
router.post("/api/settings/location-tags", defineEventHandler(async event => {
|
||||
const {location_tags, account} = await readValidatedBody(event, schema.schema.locationTags.parse)
|
||||
setCookie(event, "bcex-location-tags", location_tags)
|
||||
return sendRedirect(event, `/${account}/?arrange=tag&shape=grid`)
|
||||
}))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue