Jacky Zhao
2023-08-20 236130ac221f7d254ec9881f529f4ca567e15234
css fixes, add recent notes, more robust quartz update
2 files added
6 files modified
142 ■■■■■ changed files
quartz/bootstrap-cli.mjs 11 ●●●●● patch | view | raw | blame | history
quartz/components/PageList.tsx 2 ●●● patch | view | raw | blame | history
quartz/components/RecentNotes.tsx 81 ●●●●● patch | view | raw | blame | history
quartz/components/index.ts 2 ●●●●● patch | view | raw | blame | history
quartz/components/pages/FolderContent.tsx 9 ●●●●● patch | view | raw | blame | history
quartz/components/pages/TagContent.tsx 13 ●●●●● patch | view | raw | blame | history
quartz/components/styles/recentNotes.scss 23 ●●●●● patch | view | raw | blame | history
quartz/styles/base.scss 1 ●●●● patch | view | raw | blame | history
quartz/bootstrap-cli.mjs
@@ -136,7 +136,10 @@
function gitPull(origin, branch) {
  const flags = ["--no-rebase", "--autostash", "-s", "recursive", "-X", "ours", "--no-edit"]
  spawnSync("git", ["pull", ...flags, origin, branch], { stdio: "inherit" })
  const out = spawnSync("git", ["pull", ...flags, origin, branch], { stdio: "inherit" })
  if (out.stderr) {
    throw new Error(`Error while pulling updates: ${out.stderr}`)
  }
}
yargs(hideBin(process.argv))
@@ -258,13 +261,13 @@
    const contentFolder = path.join(cwd, argv.directory)
    console.log(chalk.bgGreen.black(`\n Quartz v${version} \n`))
    console.log("Backing up your content")
    execSync(
      `git remote show upstream || git remote add upstream https://github.com/jackyzha0/quartz.git`,
    )
    await stashContentFolder(contentFolder)
    console.log(
      "Pulling updates... you may need to resolve some `git` conflicts if you've made changes to components or plugins.",
    )
    execSync(
      `git remote show upstream || git remote add upstream https://github.com/jackyzha0/quartz.git`,
    )
    gitPull(UPSTREAM_NAME, QUARTZ_SOURCE_BRANCH)
    await popContentFolder(contentFolder)
    console.log("Ensuring dependencies are up to date")
quartz/components/PageList.tsx
@@ -3,7 +3,7 @@
import { Date } from "./Date"
import { QuartzComponentProps } from "./types"
function byDateAndAlphabetical(f1: QuartzPluginData, f2: QuartzPluginData): number {
export function byDateAndAlphabetical(f1: QuartzPluginData, f2: QuartzPluginData): number {
  if (f1.dates && f2.dates) {
    // sort descending by last modified
    return f2.dates.modified.getTime() - f1.dates.modified.getTime()
quartz/components/RecentNotes.tsx
New file
@@ -0,0 +1,81 @@
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { FullSlug, SimpleSlug, resolveRelative } from "../util/path"
import { QuartzPluginData } from "../plugins/vfile"
import { byDateAndAlphabetical } from "./PageList"
import style from "./styles/recentNotes.scss"
import { Date } from "./Date"
interface Options {
  title: string
  limit: number
  linkToMore: SimpleSlug | false
  filter: (f: QuartzPluginData) => boolean
  sort: (f1: QuartzPluginData, f2: QuartzPluginData) => number
}
const defaultOptions: Options = {
  title: "Recent Notes",
  limit: 3,
  linkToMore: false,
  filter: () => true,
  sort: byDateAndAlphabetical,
}
export default ((userOpts?: Partial<Options>) => {
  const opts = { ...defaultOptions, ...userOpts }
  function RecentNotes(props: QuartzComponentProps) {
    const { allFiles, fileData } = props
    const pages = allFiles.filter(opts.filter).sort(opts.sort).slice(0, opts.limit)
    const remaining = Math.max(0, pages.length - opts.limit)
    return (
      <div class="recent-notes">
        <h3>{opts.title}</h3>
        <ul class="recent-ul">
          {pages.map((page) => {
            const title = page.frontmatter?.title
            const tags = page.frontmatter?.tags ?? []
            return (
              <li class="recent-li">
                <div class="section">
                  <div class="desc">
                    <h3>
                      <a href={resolveRelative(fileData.slug!, page.slug!)} class="internal">
                        {title}
                      </a>
                    </h3>
                  </div>
                  {page.dates && (
                    <p class="meta">
                      <Date date={page.dates.modified} />
                    </p>
                  )}
                  <ul class="tags">
                    {tags.map((tag) => (
                      <li>
                        <a
                          class="internal tag-link"
                          href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)}
                        >
                          #{tag}
                        </a>
                      </li>
                    ))}
                  </ul>
                </div>
              </li>
            )
          })}
        </ul>
        {opts.linkToMore && remaining > 0 && (
          <p>
            <a href={resolveRelative(fileData.slug!, opts.linkToMore)}>See {remaining} more →</a>
          </p>
        )}
      </div>
    )
  }
  RecentNotes.css = style
  return RecentNotes
}) satisfies QuartzComponentConstructor
quartz/components/index.ts
@@ -15,6 +15,7 @@
import Footer from "./Footer"
import DesktopOnly from "./DesktopOnly"
import MobileOnly from "./MobileOnly"
import RecentNotes from "./RecentNotes"
export {
  ArticleTitle,
@@ -34,4 +35,5 @@
  Footer,
  DesktopOnly,
  MobileOnly,
  RecentNotes,
}
quartz/components/pages/FolderContent.tsx
@@ -25,10 +25,11 @@
    allFiles: allPagesInFolder,
  }
  const content = (tree as Root).children.length === 0 ?
    fileData.description :
    // @ts-ignore
    toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
  const content =
    (tree as Root).children.length === 0
      ? fileData.description
      : // @ts-ignore
        toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
  return (
    <div class="popover-hint">
quartz/components/pages/TagContent.tsx
@@ -22,10 +22,11 @@
      (file.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes).includes(tag),
    )
  const content = (tree as Root).children.length === 0 ?
    fileData.description :
    // @ts-ignore
    toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
  const content =
    (tree as Root).children.length === 0
      ? fileData.description
      : // @ts-ignore
        toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
  if (tag === "") {
    const tags = [...new Set(allFiles.flatMap((data) => data.frontmatter?.tags ?? []))]
@@ -45,6 +46,9 @@
              ...props,
              allFiles: pages,
            }
            const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`)[0]
            const content = contentPage?.description
            return (
              <div>
                <h2>
@@ -52,6 +56,7 @@
                    #{tag}
                  </a>
                </h2>
                {content && <p>{content}</p>}
                <p>
                  {pages.length} items with this tag.{" "}
                  {pages.length > numPages && `Showing first ${numPages}.`}
quartz/components/styles/recentNotes.scss
New file
@@ -0,0 +1,23 @@
.recent-notes {
  & > h3 {
    font-size: 1rem;
  }
  & > ul.recent-ul {
    list-style: none;
    margin-top: 1.5rem;
    padding-left: 0;
    & > li {
      margin: 1rem 0;
      .section > .desc > h3 > a {
        background-color: transparent;
      }
      .section > .meta {
        margin: 0 0 0.5rem 0;
        opacity: 0.6;
      }
    }
  }
}
quartz/styles/base.scss
@@ -320,7 +320,6 @@
  border-radius: 5px;
  overflow-x: auto;
  border: 1px solid var(--lightgray);
  position: relative;
  &:has(> code.mermaid) {
    border: none;