logseq post

This commit is contained in:
Michael Zhang 2023-08-31 10:33:14 -05:00
parent 10426919e1
commit 0c2ac5e521
13 changed files with 1249 additions and 48 deletions

View file

@ -1,13 +1,14 @@
import { defineConfig } from "astro/config";
import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
import { astroImageTools } from "astro-imagetools";
import { remarkReadingTime } from "./plugin/remark-reading-time";
// https://astro.build/config
export default defineConfig({
site: "https://mzhang.io",
integrations: [mdx(), sitemap()],
integrations: [mdx(), sitemap(), astroImageTools],
markdown: {
syntaxHighlight: false,
remarkPlugins: [remarkReadingTime],

1061
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@
"@astrojs/rss": "^3.0.0",
"@astrojs/sitemap": "^3.0.0",
"astro": "^3.0.3",
"astro-imagetools": "^0.9.0",
"fork-awesome": "^1.2.0",
"lodash-es": "^4.17.21",
"mdast-util-to-string": "^4.0.0",

View file

@ -4,25 +4,29 @@ const posts = defineCollection({
type: "content",
// Type-check frontmatter using a schema
schema: z.object({
title: z.string(),
date: z.date(),
schema: ({ image }) =>
z.object({
title: z.string(),
date: z.date(),
// Transform string to Date object
pubDate: z
.string()
.or(z.date())
.transform((val) => new Date(val))
.optional(),
updatedDate: z
.string()
.optional()
.transform((str) => (str ? new Date(str) : undefined))
.optional(),
// Transform string to Date object
pubDate: z
.string()
.or(z.date())
.transform((val) => new Date(val))
.optional(),
updatedDate: z
.string()
.optional()
.transform((str) => (str ? new Date(str) : undefined))
.optional(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
heroImage: image().optional(),
heroAlt: z.string().optional(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
export const collections = { posts };

View file

@ -1,16 +0,0 @@
---
title: Thoughts on Logseq
date: 2023-08-31T13:57:29.022Z
tags:
- organization
- logseq
draft: true
---
After working for quite a bit I like to catch up with some friends from time to
time, when I made a shocking discovery -- most of them don't really use a
calendar of any sort to manage their lives.
For a while I've always wanted a kind of personal information manager: something
that would put all my information in one place and make it easy for me to query
across apps.

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 KiB

View file

@ -0,0 +1,119 @@
---
title: Thoughts on personal organization
date: 2023-08-31T13:57:29.022Z
tags:
- organization
- logseq
heroImage: ./calendarHero.png
heroAlt: pastel colored stationery background with a bunch of calendars and personal organization tools in a crayon drawing style
---
After working for quite a bit I like to catch up with some old friends from time
to time, when I made a surprising discovery -- many of them don't really use a
calendar of any sort to manage their lives. Tracking something that happens more
than a week into the future is generally out of the picture.
But I understand. Putting events into a calendar is kind of a chore. Calendars
that are [standards-compliant][3] are still primarily use email for the most part
(sending invites, updating times, etc.) and calendars that aren't
standards-compliant won't be compatible between different people unless they're
using the same service.
[3]: https://datatracker.ietf.org/doc/html/rfc5545
The personal management story has always been kind of fragmented. Calendars are
supposed to manage the entire picture of my personal schedule, yet they only see
a small slice without more information. The only things calendars can see
automatically with no intervention on my part are emails that happen to include
.ics files.
> I'm sure Google or Apple could probably ritz up their mail servers to scan text
> and try to see if there's events without there being an actual .ics file, but
> that's missing the point. The vast majority of people I associate with rarely
> sends email events anymore.
## Journals
For a while I've always wanted a kind of personal information manager: something
that would put all my information in one place and make it easy for me to query
across apps. When I embarked on this search I wouldn't have thought that the
most promising tool would end up being a journaling app.
(by journaling app I mean something like [Logseq], [Obsidian], [Notion],
[Workflowy] or [the][roam] [million][joplin] [other][craft]
[similar][stdnotes] [apps][bear] that allow you to write some markdown-ish
content, store it, and then never look back at it again)
[logseq]: https://logseq.com
[obsidian]: https://obsidian.md/
[notion]: https://www.notion.so/
[workflowy]: https://workflowy.com/
[roam]: https://roamresearch.com/
[joplin]: https://joplinapp.org/
[craft]: https://www.craft.do/
[stdnotes]: https://standardnotes.com/
[bear]: https://bear.app/
The world of journaling apps is vast but undiverse. Most of the apps just have
the same features others do, minus one or two gimmicks that makes it a ride or
die. But there's one important feature that I have started looking out for
recently: the ability to attach arbitrary metadata to journal entries and be
able to query for them.
I think the community is starting to realize that these journals are really just
databases, and extracting structured fields is extremely important if you want
any kind of smart understanding of what is being journaled.
[Logseq], the app that I've settled on, is backed by a [Datascript] store and
exposes a lot of this functionality to you as a user. It allows you to query
directly on properties that you write into your daily journal or any other page,
for example like this:
```
- ... other content ...
- minicross:: 34
- ... other content ...
```
I use this on my daily journals to track how long it takes me to do the [NY
Times daily crossword][minicross]. But Logseq is able to index this property in
particular and let me query on it later:
[datascript]: https://github.com/tonsky/datascript
[minicross]: https://www.nytimes.com/crosswords/game/mini
![performing a query in logseq](./logseqQuery.png)
I can write todo items inline in my journal and find them all at a time as well.
As an example, here's all of the todo items that I've tagged specifically with
#read:
![reading list in logseq](./readingList.png)
The fact that it truly is a database means I can start piling things in here and
automatically perform data extraction for a more complete picture of my daily
life. In the future I'd like to do dumps for my sleep and health data as well
and have Logseq be my ultimate source of truth.
I've also started developing a [calendar plugin for Logseq][2] that will have
the ability to display numerical data using various visualizations by using the
[D3] library.
[d3]: https://d3js.org/
[2]: https://git.mzhang.io/michael/logseq-calendar
## Privacy
Because people are dumping so much of their lives into journals, it's absolutely
crucial that boundaries are clear. Without control, this would be a dream come
true for any data collection company: rather than having to go out and gather
the data, users are entering and structuring it all by themselves.
End-to-end encryption is a feature that ensures data is never able to be
accessed by your storage or synchronization providers. Of course, end-to-end
encryption is [not possible unless the entire software is able to be scrutinized
by the user or community][1]. Do careful research before deciding who to trust
with your data.
[1]: /posts/2021-10-31-e2e-encryption-useless-without-client-freedom

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

View file

@ -1,7 +1,7 @@
---
import PostList from "../components/PostList.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
import { join } from "path";
import { join, dirname } from "path";
const currentUrl = Astro.url;
---
@ -9,5 +9,5 @@ const currentUrl = Astro.url;
<BaseLayout>
<h2>Blog</h2>
<PostList basePath={join(currentUrl.pathname, "posts")} drafts="only" />
<PostList basePath={join(dirname(currentUrl.pathname), "posts")} drafts="only" />
</BaseLayout>

View file

@ -3,7 +3,7 @@ import "../../styles/post.scss";
import BaseLayout from "../../layouts/BaseLayout.astro";
import { type CollectionEntry, getCollection } from "astro:content";
import Timestamp from "../../components/Timestamp.astro";
// import BlogPost from "../../layouts/BlogPost.astro";
import { getImage } from "astro:assets";
export async function getStaticPaths() {
const posts = await getCollection("posts");
@ -17,17 +17,33 @@ type Props = CollectionEntry<"posts">;
const post = Astro.props;
const { Content, remarkPluginFrontmatter } = await post.render();
const { heroImage: heroImagePath, heroAlt } = post.data;
let heroImage;
if (heroImagePath) {
heroImage = await getImage({ src: heroImagePath });
}
---
<BaseLayout>
<h1 class="post-title">{post.data.title}</h1>
<div class="post-container">
<h1 class="post-title">{post.data.title}</h1>
<small class="post-meta">
Posted on <Timestamp timestamp={post.data.date} />
- {remarkPluginFrontmatter.minutesRead}
</small>
<small class="post-meta">
Posted on <Timestamp timestamp={post.data.date} />
- {remarkPluginFrontmatter.minutesRead}
</small>
<!-- <BlogPost {...post.data}> -->
<Content />
{
heroImage && heroAlt && (
<div style={`background-image: url(${heroImage.src});`} title={heroAlt} class="hero" />
)
}
<!-- <BlogPost {...post.data}> -->
<div class="post-content">
<Content />
</div>
</div>
<!-- </BlogPost> -->
</BaseLayout>

View file

@ -65,7 +65,7 @@ a code {
}
blockquote {
margin-inline: 14px 14px;
margin-inline: 0;
color: var(--small-text-color);
border-left: 4px solid var(--small-text-color);
padding-left: 12px;

View file

@ -9,6 +9,16 @@
margin-bottom: 20px;
}
.hero {
display: block;
width: 100%;
height: 180px;
background-size: cover;
aspect-ratio: 1;
border-radius: 8px;
margin: 24px 0;
}
.post-container {
display: flex;
@ -23,6 +33,11 @@
display: none;
}
p img {
max-width: 100%;
height: auto;
}
/*
@media screen and (max-width: 520px) {
flex-direction: column;
@ -153,7 +168,7 @@
}
> p {
line-height: 1.5;
line-height: 1.25;
}
> p > img {
@ -163,7 +178,7 @@
.footnotes {
font-size: 0.9em;
line-height: 1.2;
line-height: 1.05;
}
}