Only show own accounts on home page
This commit is contained in:
parent
2c05140382
commit
924c7395cf
7 changed files with 106 additions and 79 deletions
12
db/orm.js
12
db/orm.js
|
@ -113,12 +113,18 @@ class From {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Partial<U.Numberish<U.Models[Table]>>} conditions
|
||||
* @param {Partial<U.ValueOrArray<U.Numberish<U.Models[Table]>>>} conditions
|
||||
*/
|
||||
where(conditions) {
|
||||
|
||||
const wheres = Object.entries(conditions).map(([col, value]) => {
|
||||
this.parameters.push(value)
|
||||
return `"${col}" = ?`
|
||||
if (Array.isArray(value)) {
|
||||
this.parameters.push(...value)
|
||||
return `"${col}" IN (` + Array(value.length).fill("?").join(", ") + ")"
|
||||
} else {
|
||||
this.parameters.push(value)
|
||||
return `"${col}" = ?`
|
||||
}
|
||||
})
|
||||
this.sql += " WHERE " + wheres.join(" AND ")
|
||||
return this
|
||||
|
|
14
pug/home.pug
14
pug/home.pug
|
@ -16,15 +16,15 @@ html
|
|||
.ml6 BC Explorer
|
||||
|
||||
.mx-auto.wmx9.py24.px16.g24
|
||||
.s-prose
|
||||
h1 Select profile
|
||||
- const names = select("account", "account").pluck().all()
|
||||
ul
|
||||
each name in names
|
||||
li: a(href=`/${name}/`)= name
|
||||
if accounts.length
|
||||
.s-prose
|
||||
h1 Select account
|
||||
ul
|
||||
each account in accounts
|
||||
li: a(href=`/${account.account}/`) #{account.account} (#{account.count} items)
|
||||
|
||||
form.mt32(hx-post="/api/load-collection" hx-target="#results" hx-indicator="#submit-username")
|
||||
h2 Add your profile
|
||||
h1 Add an account
|
||||
.d-flex.gy4.fd-column.ps-relative
|
||||
label.s-label(for="username") Bandcamp username
|
||||
input.s-input.wmx3#username(name="account" placeholder="Enter your Bandcamp username here")
|
||||
|
|
71
routes/_index.js
Normal file
71
routes/_index.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
// @ts-check
|
||||
|
||||
const fs = require("fs")
|
||||
const {defineEventHandler, defaultContentType, handleCacheHeaders} = require("h3")
|
||||
const {sync, router} = require("../passthrough")
|
||||
|
||||
/** @type {import("../pug-sync")} */
|
||||
const pugSync = sync.require("../pug-sync")
|
||||
|
||||
// Routes
|
||||
|
||||
sync.require("./app")
|
||||
sync.require("./collection-stats")
|
||||
sync.require("./load-collection")
|
||||
sync.require("./home")
|
||||
sync.require("./play")
|
||||
sync.require("./settings")
|
||||
|
||||
// Files
|
||||
|
||||
router.get("/static/stacks.min.css", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/css")
|
||||
return fs.promises.readFile(require.resolve("@stackoverflow/stacks/dist/css/stacks.css"), "utf-8")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/style.css", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
defaultContentType(event, "text/css")
|
||||
return fs.promises.readFile("public/style.css", "utf-8")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/htmx.js", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/javascript")
|
||||
return Promise.all(["htmx.org/dist/htmx.js"].map(r =>
|
||||
fs.promises.readFile(require.resolve(r), "utf-8")
|
||||
)).then(files => files.join("\n\n\n"))
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/wordcloud.js", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/javascript")
|
||||
return fs.promises.readFile(require.resolve("wordcloud/src/wordcloud2.js"), "utf-8")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/player-marker.js", defineEventHandler({
|
||||
handler: async event => {
|
||||
defaultContentType(event, "text/javascript")
|
||||
return fs.promises.readFile("public/player-marker.js")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/favicon.png", defineEventHandler({
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/javascript")
|
||||
return fs.promises.readFile("public/favicon.png")
|
||||
}
|
||||
}))
|
|
@ -150,7 +150,7 @@ router.get("/:account/", defineEventHandler({
|
|||
loadPreviews(locals, "band_url", 6, whereClause, account, filter_field, filter, filter_fuzzy)
|
||||
}
|
||||
// if there are any untagged items then we don't have full track data
|
||||
locals.hasFullTrackData = !db.prepare("SELECT * FROM item LEFT JOIN item_tag USING (account, item_id) WHERE account = ? AND item_id = NULL").get(account)
|
||||
locals.hasFullTrackData = !db.prepare("SELECT * FROM item LEFT JOIN item_tag USING (account, item_id) WHERE account = ? AND tag IS NULL").get(account)
|
||||
return pugSync.render(event, `${arrange}_${shape}.pug`, locals)
|
||||
}
|
||||
}))
|
||||
|
|
15
routes/home.js
Normal file
15
routes/home.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
// @ts-check
|
||||
|
||||
const {z} = require("zod")
|
||||
const {defineEventHandler, getQuery, getValidatedQuery, sendRedirect, createError, getValidatedRouterParams, getCookie} = require("h3")
|
||||
const {router, db, sync, select, from} = require("../passthrough")
|
||||
const pugSync = sync.require("../pug-sync")
|
||||
|
||||
router.get("/", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
const names = (getCookie(event, "accounts") || "").split("|")
|
||||
const accounts = from("item").selectUnsafe("account", "count(*) AS count").where({account: names}).and("GROUP BY account").all()
|
||||
return pugSync.render(event, `home.pug`, {accounts})
|
||||
}
|
||||
}))
|
|
@ -4,7 +4,7 @@ const assert = require("assert/strict")
|
|||
const fs = require("fs")
|
||||
const sqlite = require("better-sqlite3")
|
||||
const domino = require("domino")
|
||||
const {defineEventHandler, readValidatedBody} = require("h3")
|
||||
const {defineEventHandler, readValidatedBody, setCookie, getCookie} = require("h3")
|
||||
const {z} = require("zod")
|
||||
|
||||
const {sync, db, router} = require("../passthrough")
|
||||
|
@ -95,5 +95,6 @@ const schema = z.object({
|
|||
router.post("/api/load-collection", defineEventHandler(async event => {
|
||||
const {account} = await readValidatedBody(event, schema.parse)
|
||||
const result = await loadCollection(account)
|
||||
setCookie(event, "accounts", (getCookie(event, "accounts") || "").split("|").concat(account).join("|"))
|
||||
return pugSync.render(event, "collection-loaded.pug", result)
|
||||
}))
|
||||
|
|
68
start.js
68
start.js
|
@ -1,13 +1,10 @@
|
|||
// @ts-check
|
||||
|
||||
const HeatSync = require("heatsync")
|
||||
const assert = require("assert")
|
||||
const fs = require("fs")
|
||||
const sqlite = require("better-sqlite3")
|
||||
const {createServer} = require("http")
|
||||
const h3 = require("h3")
|
||||
const {createApp, createRouter, toNodeListener} = require("h3")
|
||||
const {defineEventHandler, defaultContentType, getRequestHeader, setResponseHeader, handleCacheHeaders} = h3
|
||||
|
||||
const passthrough = require("./passthrough")
|
||||
const sync = new HeatSync()
|
||||
|
@ -27,72 +24,9 @@ const pugSync = sync.require("./pug-sync")
|
|||
/** @type {import("./icons")} */
|
||||
const icons = sync.require("./icons")
|
||||
|
||||
// Pug
|
||||
|
||||
pugSync.addGlobals({h3, select, icons})
|
||||
pugSync.createRoute(router, "/", "home.pug")
|
||||
|
||||
// Routes
|
||||
|
||||
sync.require("./routes/app")
|
||||
sync.require("./routes/load-collection")
|
||||
sync.require("./routes/play")
|
||||
sync.require("./routes/settings")
|
||||
sync.require("./routes/collection-stats")
|
||||
|
||||
// Files
|
||||
|
||||
router.get("/static/stacks.min.css", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/css")
|
||||
return fs.promises.readFile(require.resolve("@stackoverflow/stacks/dist/css/stacks.css"), "utf-8")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/style.css", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
defaultContentType(event, "text/css")
|
||||
return fs.promises.readFile("public/style.css", "utf-8")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/htmx.js", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/javascript")
|
||||
return Promise.all(["htmx.org/dist/htmx.js"].map(r =>
|
||||
fs.promises.readFile(require.resolve(r), "utf-8")
|
||||
)).then(files => files.join("\n\n\n"))
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/wordcloud.js", defineEventHandler({
|
||||
onBeforeResponse: pugSync.compressResponse,
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/javascript")
|
||||
return fs.promises.readFile(require.resolve("wordcloud/src/wordcloud2.js"), "utf-8")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/static/player-marker.js", defineEventHandler({
|
||||
handler: async event => {
|
||||
defaultContentType(event, "text/javascript")
|
||||
return fs.promises.readFile("public/player-marker.js")
|
||||
}
|
||||
}))
|
||||
|
||||
router.get("/favicon.png", defineEventHandler({
|
||||
handler: async event => {
|
||||
handleCacheHeaders(event, {maxAge: 86400})
|
||||
defaultContentType(event, "text/javascript")
|
||||
return fs.promises.readFile("public/favicon.png")
|
||||
}
|
||||
}))
|
||||
sync.require("./routes/_index")
|
||||
|
||||
createServer(toNodeListener(app)).listen(2239)
|
||||
console.log("running on http://localhost:2239")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue