From c2924fe2cf6f6e66cab9f747507681c381ca4c33 Mon Sep 17 00:00:00 2001 From: Justin <9146678+brickfrog@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:38:45 -0400 Subject: [PATCH] Quartz sync: Jul 4, 2024, 9:38 AM --- content/daily/2024/06/2024-06-25.md | 4 +- content/daily/2024/07/2024-07-02.md | 4 +- content/daily/2024/07/2024-07-03.md | 52 ++++ content/daily/2024/07/2024-07-04.md | 46 ++++ content/index.md | 22 +- content/main/i_saw_the_tv_glow.md | 37 --- content/main/movies.md | 77 +++--- content/main/quartz.md | 4 +- functions.ts | 2 + quartz.config.ts | 12 +- quartz.layout.ts | 1 + quartz/components/Quoteback.tsx | 60 +++++ quartz/components/index.ts | 2 + quartz/components/scripts/quoteback.js | 331 ++++++++++++++++++++++++ quartz/static/js/quoteback.js | 338 +++++++++++++++++++++++++ quartz/styles/custom.scss | 153 ++++++----- 16 files changed, 988 insertions(+), 157 deletions(-) create mode 100644 content/daily/2024/07/2024-07-03.md create mode 100644 content/daily/2024/07/2024-07-04.md delete mode 100644 content/main/i_saw_the_tv_glow.md create mode 100644 quartz/components/Quoteback.tsx create mode 100644 quartz/components/scripts/quoteback.js create mode 100644 quartz/static/js/quoteback.js diff --git a/content/daily/2024/06/2024-06-25.md b/content/daily/2024/06/2024-06-25.md index 721c40517..ea4f01365 100644 --- a/content/daily/2024/06/2024-06-25.md +++ b/content/daily/2024/06/2024-06-25.md @@ -1,7 +1,7 @@ --- title: 2024-06-25 author: ["Justin"] -lastmod: 2024-06-27T13:55:51-04:00 +lastmod: 2024-07-03T11:48:43-04:00 draft: false --- @@ -13,7 +13,7 @@ draft: false - [X] Anki Review - Chinese - [X] Exercise - [X] Watch a new movie - - [I Saw the TV Glow]({{< relref "../../../main/i_saw_the_tv_glow.md" >}}) +- [I Saw the TV Glow]({{< relref "../../../main/movies.md#i-saw-the-tv-glow" >}}) - [X] Write a new note - [ ] Read - Did not get to read in any meaningful capacity (books, that is, finished diff --git a/content/daily/2024/07/2024-07-02.md b/content/daily/2024/07/2024-07-02.md index 7bd4391e7..70c5cf8f2 100644 --- a/content/daily/2024/07/2024-07-02.md +++ b/content/daily/2024/07/2024-07-02.md @@ -1,7 +1,7 @@ --- title: 2024-07-02 author: ["Justin"] -lastmod: 2024-07-02T15:38:57-04:00 +lastmod: 2024-07-02T17:20:17-04:00 draft: false --- @@ -14,7 +14,7 @@ draft: false ### Tasks {#tasks} - [ ] Chinese -- [ ] Read +- [X] Read diff --git a/content/daily/2024/07/2024-07-03.md b/content/daily/2024/07/2024-07-03.md new file mode 100644 index 000000000..31be00dd9 --- /dev/null +++ b/content/daily/2024/07/2024-07-03.md @@ -0,0 +1,52 @@ +--- +title: 2024-07-03 +author: ["Justin"] +lastmod: 2024-07-03T18:34:50-04:00 +draft: false +--- + +
+ +## Agenda {#agenda} + +
+ +### Tasks {#tasks} + +- [X] Chinese + - Ish +- [X] Read +- [X] Film + - [Robot Dreams]({{< relref "../../../main/movies.md#robot-dreams" >}}) + +
+ +
+ +
+ +## Note {#note} + +- [The Power Of A Coin Toss In Big Data - YouTube](https://www.youtube.com/watch?v=MZI3aL1igP8&t=337s) + - CVM algorithm[^fn:1] + - I figured out CSL, so that's fun. + - + +
+ +
+ +## Journal {#journal} + +I forgot to (fully) review Chinese, so uh, there goes most of my day. Was +tinkering around with the programming language crystal for funsies. Next, I'd +like to try out gleam. + +Going to try moving some files around to see if that fits +a flow of writing better? - I basically made a master list like 'movies' with +each movie as a subheader. Might get a little bit clustery with large files but +I don't really use images so I don't think it hurts. + +
+ +[^fn:1]: Sourav Chakraborty, N. V. Vinodchandran, and Kuldeep S. Meel, “Distinct Elements in Streams: An Algorithm for the (Text) Book,” Lipics, Volume 244, Esa 2022 244 (2022): 34:1–34:6, https://doi.org/10.4230/LIPIcs.ESA.2022.34. diff --git a/content/daily/2024/07/2024-07-04.md b/content/daily/2024/07/2024-07-04.md new file mode 100644 index 000000000..b2270d833 --- /dev/null +++ b/content/daily/2024/07/2024-07-04.md @@ -0,0 +1,46 @@ +--- +title: 2024-07-04 +author: ["Justin"] +lastmod: 2024-07-04T06:47:41-04:00 +draft: false +--- + +
+ +## Agenda {#agenda} + +
+ +### Tasks {#tasks} + +- [ ] Chinese +- [X] Read + +
+ +
+ +
+ +## Notes {#notes} + +
+ +### Reading {#reading} + +- + - scheme in rust, found it because apparently it's (going to be) used for the + plugin system in helix? + - Might be neat as a scripting tool since I have rust on all my computers + +
+ +
+ +
+ +## Journal {#journal} + +4th of July! Messed with the site CSS a bit more. + +
diff --git a/content/index.md b/content/index.md index 011053b25..4cbe54e75 100644 --- a/content/index.md +++ b/content/index.md @@ -2,11 +2,23 @@ title: Index --- -> 袖まくり たすきがけ -> 鉢巻しめて がんばって -> 疲れたら お茶にして -> 少すこしずつ良よくなるよ -> お勉強 +
+
+
+ 袖そでまくり たすきがけ + 鉢巻はちまきしめて がんばって
+ 疲つかれたら お茶ちゃにして + 少すこしずつ良よくなるよ お勉強べんきょう + +
+
+
+

Please don't strongly interpret the dot!

+ +
+
+ +(this is an excuse to test out quotebacks) I haven't prettied it up yet, but plan on using this as a dumping ground for notes and media and such. The ideal would be then to utilize those for bigger articles on the [main site(?)](https://justin.vc) - we'll see how it goes. It's abit heavier on dependencies than I would like. diff --git a/content/main/i_saw_the_tv_glow.md b/content/main/i_saw_the_tv_glow.md deleted file mode 100644 index 7f90dc6d5..000000000 --- a/content/main/i_saw_the_tv_glow.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "I Saw the TV Glow" -author: ["Justin"] -date: 2024-06-25T06:59:00-04:00 -lastmod: 2024-06-26T02:21:19-04:00 -tags: ["film", "media"] -draft: false ---- - -[I Saw the TV Glow - Wikipedia](https://en.wikipedia.org/wiki/I_Saw_the_TV_Glow) - 2024 film, I wandered into this because of Rotten Tomatoes, -I think. I liked it, the audience score is higher than I thought given -the themes (suburbia, conformity, identity). I could see someone being -disappointed if they came into it purely as a 'horror' fan. - - -## Watching Notes {#watching-notes} - -- A24! I feel like I see them everywhere now. -- Are you afraid of the dark analogue? Campfire scene thingymajig -- I'm curious if we're going to get more 90's nostalgia like we did with the - 80's -- Unsure what the pink opaque itself could be a reference to - - monster of the week? (was mentioned after - yeah) - - musical choice and framing reminds me of twin peaks -- identity discussion, not feeling anything, asexuality? - - (after watching) oh. -- the time skips aren't as distracting as I was worried about -- okay, so the uh.. "i need to leave" was literal -- the overlays feel a bit off, I'm not sure if that was intended? -- if this was a real show, and I watched it as a kid, I probably would've been traumatized -- I think I get what it's going for, but uh.. -- I caught a glimpse of the reviews mentioning the trans identity issues - as of - writing this I didn't expect it to be that object-level? I am curious where it's - going to go with it -- soup party -- so, uh, it was literal, huh -- okay, working that job is more dread inducing than diff --git a/content/main/movies.md b/content/main/movies.md index 5ad98e09d..72fb30d0d 100644 --- a/content/main/movies.md +++ b/content/main/movies.md @@ -2,7 +2,7 @@ title: "movies" author: ["Justin"] date: 2024-07-02T04:05:00-04:00 -lastmod: 2024-07-02T14:52:05-04:00 +lastmod: 2024-07-03T15:00:18-04:00 tags: ["movies"] draft: false --- @@ -11,50 +11,41 @@ Testing something out. Beep.
-## Index movies {#index} +## Index moviesmedia {#index}
-### KILL Film {#film} +### I Saw the TV Glow {#i-saw-the-tv-glow} -

CLOSED: [2024-07-02 Tue 14:52]

- -- Test - - Test? +[I Saw the TV Glow - Wikipedia](https://en.wikipedia.org/wiki/I_Saw_the_TV_Glow) - 2024 film, I wandered into this because of Rotten Tomatoes, +I think. I liked it, the audience score is higher than I thought given +the themes (suburbia, conformity, identity). I could see someone being +disappointed if they came into it purely as a 'horror' fan.
-#### Thoughts {#thoughts} +#### Watching Notes {#watching-notes} -Test - -
- -##### 4th down {#4th-down} - -Test - -
- -###### 5th down {#5th-down} - -Test - - - -- 6th down - - - - - 7th down - - - - - 8th down - -
- -
+- A24! I feel like I see them everywhere now. +- Are you afraid of the dark analogue? Campfire scene thingymajig +- I'm curious if we're going to get more 90's nostalgia like we did with the + 80's +- Unsure what the pink opaque itself could be a reference to + - monster of the week? (was mentioned after - yeah) + - musical choice and framing reminds me of twin peaks +- identity discussion, not feeling anything, asexuality? + - (after watching) oh. +- the time skips aren't as distracting as I was worried about +- okay, so the uh.. "i need to leave" was literal +- the overlays feel a bit off, I'm not sure if that was intended? +- if this was a real show, and I watched it as a kid, I probably would've been traumatized +- I think I get what it's going for, but uh.. +- I caught a glimpse of the reviews mentioning the trans identity issues - as of + writing this I didn't expect it to be that object-level? I am curious where it's + going to go with it +- soup party +- so, uh, it was literal, huh +- okay, working that job is more dread inducing than
@@ -62,12 +53,14 @@ Test
-### Film 2 {#film-2} +### Robot Dreams {#robot-dreams} -- Hello - - Howdy - - Word - - Yo +[Robot Dreams (film) - Wikipedia](https://en.wikipedia.org/wiki/Robot_Dreams_(film)) - I liked this. Excluding music lyrics, it's +silent. Vibes heavy and full of NYC references. You can see the Guardian +Angels on the subway, and things like that. Came to my surprise that it was a +Spanish director/studio that made this. I don't have any deep thoughts on the +themes but it was wholesome. Some of the meta stuff in the middle felt a bit off +but it didn't detract too much.
diff --git a/content/main/quartz.md b/content/main/quartz.md index a616d9d91..d88ef3472 100644 --- a/content/main/quartz.md +++ b/content/main/quartz.md @@ -2,7 +2,7 @@ title: "quartz (software)" author: ["Justin"] date: 2024-06-30T05:14:00-04:00 -lastmod: 2024-07-02T17:14:30-04:00 +lastmod: 2024-07-02T17:17:08-04:00 draft: false --- @@ -25,7 +25,7 @@ Anyways I plan to use this for ideas / add-ons / goals wrt to my site too. doesn't exist on the quartz side - [ ] Maybe some CSS header movement, make it look more org-like, bullets, etc. - give it my own vibe -- [ ] The big issue with this is how do I stop remark from screwing with the html, +- The big issue with this is how do I stop remark from screwing with the html, it basically strips out half the stuff ox-hugo does. - [X] Figure out why sort / emojis don't work inside folders - Okay, that was me being dumb and not noticing it used two explorers, diff --git a/functions.ts b/functions.ts index c8f03965f..694079f15 100644 --- a/functions.ts +++ b/functions.ts @@ -7,6 +7,8 @@ export const mapFn: Options["mapFn"] = (node) => { if (node.file) { if (node.file.relativePath?.includes("daily/")) { node.displayName = "🗓️ " + node.displayName + } else if (node.name == "movies") { + node.displayName = "🎬 " + node.displayName } else { node.displayName = "📄 " + node.displayName } diff --git a/quartz.config.ts b/quartz.config.ts index ab6eeae0a..dec40f187 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -8,7 +8,7 @@ import * as Plugin from "./quartz/plugins" */ const config: QuartzConfig = { configuration: { - pageTitle: "🌆 𝕟𝕠𝕥𝕖𝕤", + pageTitle: "𝕟𝕠𝕥𝕖𝕤| justin.vc", enableSPA: true, enablePopovers: true, analytics: { @@ -37,11 +37,11 @@ const config: QuartzConfig = { secondary: "#284b63", tertiary: "#84a59d", highlight: "rgba(143, 159, 169, 0.15)", - orgh2: "#c54f72" /* Darker shade of light pink */, - orgh3: "#d47c50" /* Darker shade of peach */, - orgh4: "#cf9f6d" /* Muted pale yellow */, - orgh5: "#77b28c" /* Darker shade of light green */, - orgh6: "#5691c8" /* Darker shade of sky blue */, + orgh2: "#4CAF50" /* Soft Green */, + orgh3: "#2196F3" /* Moderate Blue */, + orgh4: "#9C27B0" /* Medium Purple */, + orgh5: "#FF9800" /* Warm Orange */, + orgh6: "#795548" /* Soft Brown */, }, darkMode: { light: "#1e1e2e", // background color (base) diff --git a/quartz.layout.ts b/quartz.layout.ts index 2066b7b04..9b3b8aabe 100644 --- a/quartz.layout.ts +++ b/quartz.layout.ts @@ -31,6 +31,7 @@ export const defaultContentPageLayout: PageLayout = { Component.MobileOnly(Component.Spacer()), Component.Search(), Component.Darkmode(), + Component.Quoteback(), Component.DesktopOnly( Component.Explorer({ mapFn: mapFn, diff --git a/quartz/components/Quoteback.tsx b/quartz/components/Quoteback.tsx new file mode 100644 index 000000000..76ed0e984 --- /dev/null +++ b/quartz/components/Quoteback.tsx @@ -0,0 +1,60 @@ +import { QuartzComponentConstructor, QuartzComponentProps } from "./types" + +interface Options { + includeScript: boolean +} + +const defaultOptions: Options = { + includeScript: true, +} + +export default ((userOpts?: Options) => { + const opts = { ...defaultOptions, ...userOpts } + + function Quoteback(props: QuartzComponentProps) { + if (!opts.includeScript) { + return null + } + + return ( + <> + + + + ) + } + + return Quoteback +}) satisfies QuartzComponentConstructor diff --git a/quartz/components/index.ts b/quartz/components/index.ts index b3db76bed..87a2ccc82 100644 --- a/quartz/components/index.ts +++ b/quartz/components/index.ts @@ -19,6 +19,7 @@ import DesktopOnly from "./DesktopOnly" import MobileOnly from "./MobileOnly" import RecentNotes from "./RecentNotes" import Breadcrumbs from "./Breadcrumbs" +import Quoteback from "./Quoteback" export { ArticleTitle, @@ -42,4 +43,5 @@ export { RecentNotes, NotFound, Breadcrumbs, + Quoteback, } diff --git a/quartz/components/scripts/quoteback.js b/quartz/components/scripts/quoteback.js new file mode 100644 index 000000000..2932cfd43 --- /dev/null +++ b/quartz/components/scripts/quoteback.js @@ -0,0 +1,331 @@ +var editSVG = `` +var quoteStyle = ` +.quoteback-container { + --background-color: #eff1f5; + --border-color-normal: #cad3f5; + --border-color-hover: #b4befe; + --author-color: #575268; + --title-color: #1e1e2e; + --gototext-color: #b4befe; + --content-color: #575268; + --internal-blockquote-color: #1e1e2e; +} + +.quoteback-container.dark-theme { + --background-color: #1e1e2e; + --border-color-normal: #302d41; + --border-color-hover: #f2cdcd; + --author-color: #f5c2e7; + --title-color: #cba6f7; + --gototext-color: #f2cdcd; + --content-color: #cba6f7; + --internal-blockquote-color: #f5c2e7; +} + +.quoteback-container { + font-family: -apple-system, system-ui, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; + text-rendering: optimizeLegibility; + border: 1px solid var(--border-color-normal); + border-radius: 8px; + margin-bottom: 25px; + max-width: 800px; + background-color: var(--background-color); + text-align: left; + transition: all 0.2s ease; +} + +.quoteback-container:hover { + transform: translateY(-3px); + box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15); + border: 1px solid var(--border-color-hover); +} + +.quoteback-container .quoteback-parent { + overflow: hidden; + position: relative; + width: 100%; + box-sizing: border-box; +} + +.quoteback-container .quoteback-parent .quoteback-content { + font-family: -apple-system, system-ui, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 16px; + font-weight: 400; + padding: 15px; + color: var(--content-color); + line-height: 150%; +} + +.quoteback-container .quoteback-head { + border-top: 1px solid var(--border-color-normal); + display: flex; + flex-flow: row nowrap; + justify-content: start; + align-items: stretch; + padding-left: 15px; + transition: all 0.2s ease; +} + +.quoteback-container .quoteback-head .quoteback-avatar { + border-radius: 100%; + border: 1px solid var(--border-color-normal); + width: 42px; + height: 42px; + min-width: 42px !important; + margin: 12px 0px; + position: relative; +} + +.quoteback-container .quoteback-head .quoteback-avatar .mini-favicon { + width: 22px; + height: 22px; + position: absolute; + margin: auto; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.quoteback-container .quoteback-head .quoteback-metadata { + min-width: 0px; + display: flex; + flex-shrink: 1; + align-items: center; + margin-left: 10px; +} + +.quoteback-container .quoteback-head .metadata-inner { + font-size: 14px; + line-height: 1.2; + width: 100%; + max-width: 525px; +} + +@media (max-width: 414px) { + .quoteback-container .quoteback-head .metadata-inner { + max-width: 200px; + } +} + +.quoteback-container .quoteback-head .metadata-inner .quoteback-title { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-weight: 600; + padding-right: 20px; + color: var(--title-color); +} + +.quoteback-container .quoteback-head .metadata-inner .quoteback-author { + font-size: 14px; + line-height: 1.2; + color: var(--author-color); + font-weight: 600; + margin-bottom: 2px; +} + +.quoteback-container .quoteback-head .quoteback-backlink { + margin-left: auto; + display: flex; + flex-shrink: 1; + align-items: center; + width: 81px; + min-width: 81px !important; + padding: 0px 15px !important; + border-left: 1px solid var(--border-color-normal); +} + +.quoteback-container .quoteback-head .quoteback-backlink { + border: none !important; + font-family: inherit !important; + font-size: 14px !important; + color: var(--gototext-color) !important; + text-decoration: none !important; + transition: opacity 0.1s ease; +} + +.quoteback-arrow { + font-size: 24px !important; + text-decoration: none !important; +} + +.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:hover { + opacity: .5 !important; +} + +.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:visited { + text-decoration: none !important; +} + +.editable:focus { + outline: none; +} + +.editable:before { + margin-right: 8px; + content: url(data:image/svg+xml,${encodeURIComponent(editSVG)}); +} + +.quoteback-content a { + color: var(--content-color); + transition: opacity 0.2s ease; +} + +.quoteback-content a:hover { + opacity: .5; +} + +.quoteback-content p { + margin-block-start: 0px; + margin-block-end: .5em; +} + +.quoteback-content p:last-of-type { + margin-block-end: 0px; +} + +.quoteback-content img { + width: 100%; + height: auto; + margin: .5em 0em; +} + +.quoteback-content blockquote { + border-left: 2px solid var(--border-color-normal); + padding-left: .75em; + margin-inline-start: 1em; + color: var(--internal-blockquote-color); +} + +.quoteback-content ol, .quoteback-content ul { + margin-block-start: .5em; + margin-block-end: .5em; +} + +.quoteback-content h1, .quoteback-content h2, .quoteback-content h3 { + margin-block-start: .5em; + margin-block-end: .5em; +} +` + +document.addEventListener("DOMContentLoaded", function () { + // get all our classed blockquote components + var index = document.querySelectorAll(".quoteback") + + for (var item = 0; item < index.length; item++) { + // remove the footer element + console.log(index[item]) + index[item].removeChild(index[item].querySelector("footer")) + + var text = index[item].innerHTML + + var url = index[item].cite + var author = index[item].getAttribute("data-author") + var title = index[item].getAttribute("data-title") + var favicon = `https://s2.googleusercontent.com/s2/favicons?domain_url=${url}&sz=64` + var darkmode = index[item].getAttribute("darkmode") + + // create a new component with that data + var component = ` + + + ` + var newEl = document.createElement("div") + newEl.innerHTML = component + + // replace the original blockquote with our quoteback seed component + index[item].parentNode.replaceChild(newEl, index[item]) + + var template = document.createElement("template") + template.innerHTML = ` + +
+
+
+
+ +
+
+ + + +
+
` + + class QuoteBack extends HTMLElement { + constructor() { + super() + this.attachShadow({ mode: "open" }) + this.shadowRoot.appendChild(template.content.cloneNode(true)) + + this.text = decodeURIComponent(this.getAttribute("text")) + this.author = this.getAttribute("author") + this.title = decodeURIComponent(this.getAttribute("title")) + this.url = this.getAttribute("url") + this.favicon = this.getAttribute("favicon") + this.editable = this.getAttribute("editable") + this.darkmode = this.getAttribute("darkmode") + } + + connectedCallback() { + console.info("connected") + + if (this.darkmode == "true") { + this.shadowRoot.querySelector(".quoteback-container").classList += " dark-theme" + } + this.shadowRoot.querySelector(".quoteback-content").innerHTML = decodeURIComponent( + this.getAttribute("text"), + ) + this.shadowRoot.querySelector(".mini-favicon").src = this.getAttribute("favicon") + this.shadowRoot.querySelector(".quoteback-author").innerHTML = this.getAttribute("author") + this.shadowRoot + .querySelector(".quoteback-author") + .setAttribute("aria-label", "quote by " + this.getAttribute("author")) + this.shadowRoot.querySelector(".quoteback-title").innerHTML = decodeURIComponent( + this.getAttribute("title"), + ) + this.shadowRoot + .querySelector(".quoteback-title") + .setAttribute("aria-label", "title: " + decodeURIComponent(this.getAttribute("title"))) + this.shadowRoot.querySelector(".quoteback-arrow").href = this.getAttribute("url") + + // Manually focus and blur clicked targets + // This solves firefox bug where clicking between contenteditable fields doesn't work + if (this.editable == "true") { + let titlediv = this.shadowRoot.querySelector(".quoteback-title") + let authordiv = this.shadowRoot.querySelector(".quoteback-author") + + titlediv.addEventListener("click", (evt) => { + evt.target.contentEditable = true + evt.target.focus() + }) + titlediv.addEventListener("blur", (evt) => { + evt.target.contentEditable = false + }) + + authordiv.addEventListener("click", (evt) => { + evt.target.contentEditable = true + evt.target.focus() + }) + authordiv.addEventListener("blur", (evt) => { + evt.target.contentEditable = false + }) + } + // end this fix + } + } + + // if quoteback-component is already defined + if (customElements.get("quoteback-component")) { + null + } else { + window.customElements.define("quoteback-component", QuoteBack) + } + } +}) diff --git a/quartz/static/js/quoteback.js b/quartz/static/js/quoteback.js new file mode 100644 index 000000000..a9ef19778 --- /dev/null +++ b/quartz/static/js/quoteback.js @@ -0,0 +1,338 @@ +var editSVG = `` +var quoteStyle = ` +.quoteback-container { + --background-color: #eff1f5; + --border-color-normal: #cad3f5; + --border-color-hover: #b4befe; + --author-color: #575268; + --title-color: #1e1e2e; + --gototext-color: #b4befe; + --content-color: #575268; + --internal-blockquote-color: #1e1e2e; +} + +.quoteback-container.dark-theme { + --background-color: #1e1e2e; + --border-color-normal: #302d41; + --border-color-hover: #f2cdcd; + --author-color: #f5c2e7; + --title-color: #cba6f7; + --gototext-color: #f2cdcd; + --content-color: #cba6f7; + --internal-blockquote-color: #f5c2e7; +} + +.quoteback-container { + font-family: -apple-system, system-ui, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; + text-rendering: optimizeLegibility; + border: 1px solid var(--border-color-normal); + border-radius: 8px; + margin-bottom: 25px; + max-width: 800px; + background-color: var(--background-color); + text-align: left; + transition: all 0.2s ease; +} + +.quoteback-container:hover { + transform: translateY(-3px); + box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15); + border: 1px solid var(--border-color-hover); +} + +.quoteback-container .quoteback-parent { + overflow: hidden; + position: relative; + width: 100%; + box-sizing: border-box; +} + +.quoteback-container .quoteback-parent .quoteback-content { + font-family: -apple-system, system-ui, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 16px; + font-weight: 400; + padding: 15px; + color: var(--content-color); + line-height: 150%; +} + +.quoteback-container .quoteback-head { + border-top: 1px solid var(--border-color-normal); + display: flex; + flex-flow: row nowrap; + justify-content: start; + align-items: stretch; + padding-left: 15px; + transition: all 0.2s ease; +} + +.quoteback-container .quoteback-head .quoteback-avatar { + border-radius: 100%; + border: 1px solid var(--border-color-normal); + width: 42px; + height: 42px; + min-width: 42px !important; + margin: 12px 0px; + position: relative; +} + +.quoteback-container .quoteback-head .quoteback-avatar .mini-favicon { + width: 22px; + height: 22px; + position: absolute; + margin: auto; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.quoteback-container .quoteback-head .quoteback-metadata { + min-width: 0px; + display: flex; + flex-shrink: 1; + align-items: center; + margin-left: 10px; +} + +.quoteback-container .quoteback-head .metadata-inner { + font-size: 14px; + line-height: 1.2; + width: 100%; + max-width: 525px; +} + +@media (max-width: 414px) { + .quoteback-container .quoteback-head .metadata-inner { + max-width: 200px; + } +} + +.quoteback-container .quoteback-head .metadata-inner .quoteback-title { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-weight: 600; + padding-right: 20px; + color: var(--title-color); +} + +.quoteback-container .quoteback-head .metadata-inner .quoteback-author { + font-size: 14px; + line-height: 1.2; + color: var(--author-color); + font-weight: 600; + margin-bottom: 2px; +} + +.quoteback-container .quoteback-head .quoteback-backlink { + margin-left: auto; + display: flex; + flex-shrink: 1; + align-items: center; + width: 81px; + min-width: 81px !important; + padding: 0px 15px !important; + border-left: 1px solid var(--border-color-normal); +} + +.quoteback-container .quoteback-head .quoteback-backlink { + border: none !important; + font-family: inherit !important; + font-size: 14px !important; + color: var(--gototext-color) !important; + text-decoration: none !important; + transition: opacity 0.1s ease; +} + +.quoteback-arrow { + font-size: 24px !important; + text-decoration: none !important; +} + +.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:hover { + opacity: .5 !important; +} + +.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:visited { + text-decoration: none !important; +} + +.editable:focus { + outline: none; +} + +.editable:before { + margin-right: 8px; + content: url(data:image/svg+xml,${encodeURIComponent(editSVG)}); +} + +.quoteback-content a { + color: var(--content-color); + transition: opacity 0.2s ease; +} + +.quoteback-content a:hover { + opacity: .5; +} + +.quoteback-content p { + margin-block-start: 0px; + margin-block-end: .5em; +} + +.quoteback-content p:last-of-type { + margin-block-end: 0px; +} + +.quoteback-content img { + width: 100%; + height: auto; + margin: .5em 0em; +} + +.quoteback-content blockquote { + border-left: 2px solid var(--border-color-normal); + padding-left: .75em; + margin-inline-start: 1em; + color: var(--internal-blockquote-color); +} + +.quoteback-content ol, .quoteback-content ul { + margin-block-start: .5em; + margin-block-end: .5em; +} + +.quoteback-content h1, .quoteback-content h2, .quoteback-content h3 { + margin-block-start: .5em; + margin-block-end: .5em; +} +` +document.addEventListener("DOMContentLoaded", function () { + applyQuotebackStyles() +}) + +window.addEventListener("popstate", function () { + applyQuotebackStyles() +}) + +function applyQuotebackStyles() { + // get all our classed blockquote components + var index = document.querySelectorAll(".quoteback") + + for (var item = 0; item < index.length; item++) { + // remove the footer element + console.log(index[item]) + index[item].removeChild(index[item].querySelector("footer")) + + var text = index[item].innerHTML + + var url = index[item].cite + var author = index[item].getAttribute("data-author") + var title = index[item].getAttribute("data-title") + var favicon = `https://s2.googleusercontent.com/s2/favicons?domain_url=${url}&sz=64` + var darkmode = index[item].getAttribute("darkmode") + + // create a new component with that data + var component = ` + + + ` + var newEl = document.createElement("div") + newEl.innerHTML = component + + // replace the original blockquote with our quoteback seed component + index[item].parentNode.replaceChild(newEl, index[item]) + + var template = document.createElement("template") + template.innerHTML = ` + +
+
+
+
+ +
+
+ + + +
+
` + + class QuoteBack extends HTMLElement { + constructor() { + super() + this.attachShadow({ mode: "open" }) + this.shadowRoot.appendChild(template.content.cloneNode(true)) + + this.text = decodeURIComponent(this.getAttribute("text")) + this.author = this.getAttribute("author") + this.title = decodeURIComponent(this.getAttribute("title")) + this.url = this.getAttribute("url") + this.favicon = this.getAttribute("favicon") + this.editable = this.getAttribute("editable") + this.darkmode = this.getAttribute("darkmode") + } + + connectedCallback() { + console.info("connected") + + if (this.darkmode == "true") { + this.shadowRoot.querySelector(".quoteback-container").classList += " dark-theme" + } + this.shadowRoot.querySelector(".quoteback-content").innerHTML = decodeURIComponent( + this.getAttribute("text"), + ) + this.shadowRoot.querySelector(".mini-favicon").src = this.getAttribute("favicon") + this.shadowRoot.querySelector(".quoteback-author").innerHTML = this.getAttribute("author") + this.shadowRoot + .querySelector(".quoteback-author") + .setAttribute("aria-label", "quote by " + this.getAttribute("author")) + this.shadowRoot.querySelector(".quoteback-title").innerHTML = decodeURIComponent( + this.getAttribute("title"), + ) + this.shadowRoot + .querySelector(".quoteback-title") + .setAttribute("aria-label", "title: " + decodeURIComponent(this.getAttribute("title"))) + this.shadowRoot.querySelector(".quoteback-arrow").href = this.getAttribute("url") + + // Manually focus and blur clicked targets + // This solves firefox bug where clicking between contenteditable fields doesn't work + if (this.editable == "true") { + let titlediv = this.shadowRoot.querySelector(".quoteback-title") + let authordiv = this.shadowRoot.querySelector(".quoteback-author") + + titlediv.addEventListener("click", (evt) => { + evt.target.contentEditable = true + evt.target.focus() + }) + titlediv.addEventListener("blur", (evt) => { + evt.target.contentEditable = false + }) + + authordiv.addEventListener("click", (evt) => { + evt.target.contentEditable = true + evt.target.focus() + }) + authordiv.addEventListener("blur", (evt) => { + evt.target.contentEditable = false + }) + } + // end this fix + } + } + + // if quoteback-component is already defined + if (customElements.get("quoteback-component")) { + null + } else { + window.customElements.define("quoteback-component", QuoteBack) + } + } +} diff --git a/quartz/styles/custom.scss b/quartz/styles/custom.scss index 6cb6fe1c6..7d47d476f 100644 --- a/quartz/styles/custom.scss +++ b/quartz/styles/custom.scss @@ -93,24 +93,35 @@ p.timestamp-wrapper { } /* Org Mode Header Vibes */ - - -/* General styling for outline containers within .jvc */ -.jvc div.jvc { - margin-left: 5px; +/* Variables */ +:root { + --base-indent: 20px; + --heading-indent: 15px; + --base-font-size: 1em; + --base-margin: 10px; + --base-padding: 5px; } -.jvc ul { - margin-top: 0; - margin-bottom: 0; +/* Base styles */ +.jvc { + margin-left: var(--base-indent); +} + +.jvc div.jvc { + margin-left: var(--base-padding); +} + +/* Headings */ +.jvc h2, .jvc h3, .jvc h4, .jvc h5, .jvc h6 { + margin-top: var(--base-margin); + margin-bottom: var(--base-margin); } .jvc h2 { font-size: 1.5em; - padding-left: 0em; + margin-left: 0; + padding-left: 0; color: var(--orgh2); - margin-top: 10px; - margin-bottom: 10px; } .jvc h2::before { content: "○ "; @@ -118,32 +129,39 @@ p.timestamp-wrapper { .jvc h3 { font-size: 1.4em; - padding-left: 1em; + margin-left: var(--heading-indent); + padding-left: 0; color: var(--orgh3); - margin-top: 10px; - margin-bottom: 10px; } .jvc h3::before { content: "◆ "; } +/* Adjust content under h3 */ +.jvc h3 + * { + margin-left: calc(var(--heading-indent) * 2); +} + .jvc h4 { font-size: 1.3em; - padding-left: 1.25em; + margin-left: calc(var(--heading-indent) * 2); + padding-left: 0; color: var(--orgh4); - margin-top: 10px; - margin-bottom: 10px; } .jvc h4::before { content: "▲ "; } +/* Adjust content under h4 */ +.jvc h4 + * { + margin-left: calc(var(--heading-indent) * 3); +} + .jvc h5 { font-size: 1.2em; - padding-left: 1.5em; + margin-left: calc(var(--heading-indent) * 3); + padding-left: 0; color: var(--orgh5); - margin-top: 10px; - margin-bottom: 10px; } .jvc h5::before { content: "■ "; @@ -151,68 +169,73 @@ p.timestamp-wrapper { .jvc h6 { font-size: 1.1em; - padding-left: 2em; + margin-left: calc(var(--heading-indent) * 4); + padding-left: 0; color: var(--orgh6); - margin-top: 10px; - margin-bottom: 10px; } - .jvc h6::before { content: "● "; } +/* Lists */ .jvc ul, .jvc ol { - list-style-position: outside; - margin-left: 0px; + margin-top: 0.5em; + margin-bottom: 0.5em; + padding-left: var(--base-indent); + list-style-position: outside; } -.jvc li > p { - margin-top: 5px; - margin-bottom: 5px; +.jvc ul li, .jvc ol li { + margin-bottom: 0.3em; } -.jvc li > ul { - margin-top: 5px; - margin-bottom: 5px; +.jvc ul ul, .jvc ul ol, .jvc ol ul, .jvc ol ol { + padding-left: var(--heading-indent); } -.jvc ul > li:first-child, .jvc ol > li:first-child { - margin-left: 15px; } - -.jvc ul.contains-task-list > li:first-child, -.jvc ol.contains-task-list > li:first-child { - margin-left: 0; /* Adjust as needed, maybe 0 or another value */ - } - +/* Task lists */ .jvc .contains-task-list { - margin-left: 15px; + padding-left: 0; + margin-left: calc(var(--heading-indent) * 2); /* Adjust this multiplier as needed */ } -.jvc ul ul { - margin-left: -40px; +.jvc .contains-task-list .task-list-item { + position: relative; + padding-left: 1.5em; /* Space for checkbox */ + margin-bottom: 0.5em; } -.outline-5 ul, .outline-5 ol { - margin-left: -15px; } +/* Nested task lists */ +.jvc .contains-task-list .contains-task-list { + margin-left: var(--heading-indent); +} +/* Paragraphs */ .jvc > p { - padding-left: 2.25em; - margin-top: 0.25em; - margin-bottom: 0.25em; + padding-left: var(--heading-indent); + margin-top: 0.5em; + margin-bottom: 0.5em; } -.jvc > li { - padding-left: 2em; +.jvc > p::before { + content: "● "; + padding-right: 5px; + font-size: 12px; } -.jvc p::before { - content: "● "; padding-right: 5px; } - .jvc li p::before { - content: ''; } + content: ''; +} + +/* Outline-5 specific styles */ +.outline-5 ul, .outline-5 ol { + margin-left: -15px; +} .outline-5 p::before { - content: "◆ "; padding-right: 5px; font-size: 10px; + content: "◆ "; + padding-right: 5px; + font-size: 8px; } .outline-5 ul p::before, @@ -220,22 +243,30 @@ p.timestamp-wrapper { .outline-5 ul ul ul p::before, .outline-5 ul ul ul ul p::before, .outline-5 ul ul ul ul ul p::before { - content: "◆ "; font-size: 8px; - list-style-type: none; } + content: "◆ "; + font-size: 8px; +} .outline-5 li { - list-style-type: none; } + list-style-type: none; +} -/* EOF */ +/* Superscript */ +sup { + margin-left: 2px; +} +/* EOF marker */ article.popover-hint::after { content: "— EOF —"; - font-family: 'Courier New', monospace; /* Ensures a monospace font for stylistic consistency */ + font-family: 'Courier New', monospace; font-size: 0.9em; color: #666; margin-top: 1em; display: block; text-align: center; padding-top: 0.5em; - padding-bottom: 1em; /* Adds a little space below the EOF marker */ + padding-bottom: 1em; } + +/* Quotebacks */ \ No newline at end of file