Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com

Kanding page changes, added an About page

+87 -20
+4 -1
cmd/server/main.go
··· 59 59 } 60 60 61 61 pages := []string{ 62 - "atproto_login", "documents", "document_view", "document_edit", 62 + "about", "atproto_login", "documents", "document_view", "document_edit", 63 63 "landing", "login", "new_document", "register", 64 64 } 65 65 tmpls := make(map[string]*template.Template, len(pages)) ··· 92 92 mux.HandleFunc("GET /auth/atproto", h.ATProtoLoginPage) 93 93 mux.HandleFunc("POST /auth/atproto", h.ATProtoLoginSubmit) 94 94 mux.HandleFunc("GET /auth/atproto/callback", h.ATProtoCallback) 95 + 96 + // Page routes 97 + mux.HandleFunc("GET /about", h.AboutPage) 95 98 96 99 // Dashboard 97 100 mux.HandleFunc("GET /", h.Dashboard)
+10
internal/handler/handler.go
··· 157 157 http.Redirect(w, r, "/", http.StatusSeeOther) 158 158 } 159 159 160 + // --- Page handlers --- 161 + 162 + func (h *Handler) AboutPage(w http.ResponseWriter, r *http.Request) { 163 + user := h.currentUser(r) 164 + h.render(w, "about.html", PageData{ 165 + Title: "About", 166 + User: user, 167 + }) 168 + } 169 + 160 170 // --- Dashboard --- 161 171 162 172 func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
+27 -7
static/css/style.css
··· 72 72 h1, h2, h3, h4, h5 { 73 73 font-family: var(--heading-font); 74 74 font-weight: 500; 75 + margin-top: 1.5rem; 76 + margin-bottom: 0.5rem; 75 77 } 78 + 79 + ul { 80 + list-style: disc; 81 + margin-left: 1.5rem; 82 + } 83 + 84 + li { 85 + margin-bottom: 0.25rem; 86 + margin-left: 1rem; 87 + } 88 + 76 89 77 90 /* Navbar */ 78 91 .navbar { ··· 212 225 padding: 4rem 0; 213 226 } 214 227 215 - .landing h1 { font-size: 2.5rem; margin-bottom: 1rem; } 216 - .landing p { font-size: 1.1rem; font-weight: 400; margin-bottom: 2rem; } 228 + .landing h1, .about-page h1 { font-size: 2.5rem; margin-bottom: 1.25rem; } 229 + .landing p, .about-page p { font-size: 1.1rem; font-weight: 400; margin-bottom: 1.25rem; } 217 230 .landing-actions { display: flex; gap: 1rem; justify-content: center; } 218 231 219 - .landing-header { 232 + .landing-header, .about-header { 220 233 text-align: center; 221 234 } 222 235 223 - .landing-content { 236 + .landing-header p, .about-header p { 237 + text-align: left; 238 + font-size: 1.1rem; 239 + font-weight: 400; 240 + margin-bottom: 1.25rem; 241 + } 242 + 243 + .landing-content, .about-content{ 224 244 color: var(--text-secondary); 225 245 display: grid; 226 246 grid-template-columns: 1fr 1fr; ··· 229 249 margin-bottom: 2rem; 230 250 } 231 251 232 - .landing-hr { 252 + .landing-hr, .about-hr { 233 253 margin: 2rem 0; 234 254 } 235 255 236 256 @media (max-width: 640px) { 237 - .landing-content { 257 + .landing-content, .about-content { 238 258 grid-template-columns: 1fr; 239 - } 259 + 240 260 } 241 261 242 262 /* Dashboard */
+40
templates/about.html
··· 1 + {{template "base" .}} 2 + {{define "content"}} 3 + <div class="about-page"> 4 + <section class="about-header"> 5 + <h1>About Diffdown</h1> 6 + </section> 7 + <section class="about-content"> 8 + <div class="about-col"> 9 + <h2>What is Diffdown?</h2> 10 + <p>Diffdown is a real-time collaborative Markdown editor/previewer built on the <a href="https://atproto.com/">AT Protocol</a> (the tech that powers <a href="https://bsky.app">Bluesky</a>). 11 + 12 + <p>Diffdown is decentralized; it stores documents as AT Protocol records on the document creator's PDS, not on the Diffdown server or some cloud provider.</p> 13 + 14 + <p>I built Diffdown to learn <a href="https://atproto.com/">AT Protocol</a>, <a href="https://atproto.com/guides/lexicon">lexicons</a>, and <a href="https://www.ibm.com/think/topics/agentic-engineering">agentic engineering</a>. Consider it a "pre-alpha" prototype. Because AT Proto does not support private records (<a href="https://atproto.wiki/en/working-groups/private-data">yet</a>), <strong>any documents you create will be visible to anyone with the URL</strong> (<a href="https://atproto.at/viewer?uri=did:plc:za4vlvbizdstoym7lpymc5q5/com.diffdown.document/3mgzsp6m5hs24">example</a>).</p> 15 + 16 + <h2>About Me</h2> 17 + <p>I've worked in tech for a long time as a product manager and executive. These days, I'm a co-founder of <a href="https://limeleaf.coop">Limeleaf Worker Collective</a>, and an advisor to a few startups. Read about my journey building Diffdown <a href="https://www.jluther.net/tags/nonfiction/">on my Leaflet</a>.</p> 18 + 19 + </div> 20 + <div class="about-col"> 21 + <h2>Technology</h2> 22 + <ul> 23 + <li><strong>Backend:</strong> Go, SQLite</li> 24 + <li><strong>Frontend:</strong> Vanilla HTML, CSS, JavaScript</li> 25 + <li><strong>Editor:</strong> <a href="https://prosemirror.net/">ProseMirror</a> with <a href="https://github.com/ProseMirror/prosemirror-collab">prosemirror-collab</a> for real-time collaboration; <a href="https://milkdown.dev/">Milkdown</a> for Markdown</li> 26 + <li><strong>Authentication:</strong> ATProto OAuth (any PDS)</li> 27 + <li><strong>Deployment and hosting:</strong> Fly.io</li> 28 + </ul> 29 + <h2>Status</h2> 30 + <p>This is a prototype. I wouldn't even call it an Alpha.</p> 31 + <p><strong>Important:</strong> Because AT Proto does not support private data <a href="https://atproto.wiki/en/working-groups/private-data">(yet)</a>, any documents you create will be visible to anyone with the URL.</p> 32 + <p>Expect bugs, breaking changes, and limited features.</p> 33 + <p>However, any documents you create will be stored in your AT Proto account, so even if Diffdown goes away, you will still have your documents.</p> 34 + 35 + <h2>Contact</h2> 36 + <p>Feedback, bug reports, and feature requests are welcome. Reach out via Bluesky or check the <a href="https://github.com/limeleaf/diffdown">GitHub repository</a>.</p> 37 + </div> 38 + </section> 39 + </div> 40 + {{end}}
+2
templates/base.html
··· 38 38 <div class="nav-right"> 39 39 {{if .User}} 40 40 <a href="/">Documents</a> 41 + <a href="/about">About</a> 41 42 <span class="nav-user">{{.User.Name}}</span> 42 43 <form method="post" action="/auth/logout" style="display:inline"> 43 44 <button type="submit" class="btn-link">Log out</button> ··· 45 46 {{else}} 46 47 <a href="/auth/login">Log in</a> 47 48 <a href="/auth/register" class="btn btn-sm">Sign up</a> 49 + <a href="/about">About</a> 48 50 {{end}} 49 51 <button id="theme-toggle" class="btn-link" aria-label="Toggle dark mode" onclick="toggleTheme()" style="font-size:1.1rem;padding:0.25rem">☀</button> 50 52 </div>
+4 -12
templates/landing.html
··· 3 3 <div class="landing"> 4 4 <section class="landing-header"> 5 5 <h1>Collaborative Markdown Editing</h1> 6 - <p>Write, review, and collaborate on Markdown documents with your team in <a href="https://www.bskyinfo.com/glossary/atmosphere/">the ATmosphere</a>.</p> 6 + <p>Write, review, and collaborate on Markdown documents with your team in <a href="https://www.bskyinfo.com/glossary/atmosphere/">the ATmosphere</a>. It uses your Bluesky or <a href="https://atproto.com/">AT Protocol</a> account, so no need to create an account, just log in.</p> 7 7 </section> 8 8 <div class="landing-actions"> 9 - <a href="/auth/register" class="btn btn-lg">Get Started</a> 10 - <a href="/auth/login" class="btn btn-lg btn-outline">Log In</a> 9 + <a href="/auth/login" class="btn btn-lg">Log In</a> 11 10 </div> 12 11 <hr class="landing-hr"> 13 - <section class="landing-content"> 14 - <div class="landing-col"> 15 - <h2>About This Project</h2> 16 - <p>This app is a toy I built to learn <a href="https://atproto.com/">AT Protocol</a>, <a href="https://atproto.com/guides/lexicon">lexicons</a>, and <a href="https://www.ibm.com/think/topics/agentic-engineering">agentic engineering</a>. It is not meant for actual use. Because AT Proto does not support private records (<a href="https://atproto.wiki/en/working-groups/private-data">yet</a>), any documents you create will be visible to anyone with the URL (<a href="https://atproto.at/viewer?uri=did:plc:za4vlvbizdstoym7lpymc5q5/com.diffdown.document/3mgzsp6m5hs24">example</a>).</p> 17 - </div> 18 - <div class="landing-col"> 19 - <h2>About Me</h2> 20 - <p>I've worked in tech for a long time as a product manager and executive. These days, I'm a co-founder of <a href="https://limeleaf.coop">Limeleaf Worker Collective</a>, and an advisor to a few tech projects. <a href="https://jluther.net">I like to write.</a></p> 21 - </div> 12 + <section> 13 + <p>This is barely Alpha-quality software. Don't use it for anything important. <a href="/about">Learn more about Diffdown</a>.</p> 22 14 </section> 23 15 24 16 </div>