feat: turned blog into a mini app ๐
8d83900f
10 file(s) ยท +57 โ46
| 1 | + | { |
|
| 2 | + | "accountAssociation": { |
|
| 3 | + | "header": "eyJmaWQiOjYwMjMsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHg0NTYxMzExNjFmODNDN0Q3ZkRBMTViMzJhNWY3QzIxRkQ0RTI3RTk2In0", |
|
| 4 | + | "payload": "eyJkb21haW4iOiJzdGV2ZWR5bGFuLmRldiJ9", |
|
| 5 | + | "signature": "MHgzNjRkMTc4NDUzYzk1MjY3ZmRiNjBmOTYwMmM2M2VjOGI4M2RiYzIxOTdkNWQ1NGQ3N2RkYTRmZjllMjA4YWZmNDljYTFlN2U5NGFkN2UxOWNjNzBlM2UzMzIyNDhkZDNiNzg5Y2MyMDIwYWVkNTExNzYzMmUxNTNmOTlmZDE3YTFi" |
|
| 6 | + | }, |
|
| 7 | + | "frame": { |
|
| 8 | + | "version": "1", |
|
| 9 | + | "name": "stevedylan.dev", |
|
| 10 | + | "iconUrl": "https://stevedylan.dev/icon.png", |
|
| 11 | + | "homeUrl": "https://stevedylan.dev", |
|
| 12 | + | "imageUrl": "https://stevedylan.dev/image.png", |
|
| 13 | + | "buttonTitle": "Read Blog", |
|
| 14 | + | "splashImageUrl": "https://stevedylan.dev/splash.png", |
|
| 15 | + | "splashBackgroundColor": "#000000", |
|
| 16 | + | "webhookUrl": "https://webhooks.pingem.xyz/f/0adv8" |
|
| 17 | + | } |
|
| 18 | + | } |
Binary file โ no preview.
Binary file โ no preview.
Binary file โ no preview.
Binary file โ no preview.
| 14 | 14 | ogImage ? ogImage : "/social-card.png", |
|
| 15 | 15 | Astro.url, |
|
| 16 | 16 | ).href; |
|
| 17 | + | const fcImage = new URL( |
|
| 18 | + | ogImage ? ogImage : "/image.png", |
|
| 19 | + | Astro.url, |
|
| 20 | + | ).href; |
|
| 21 | + | ||
| 22 | + | const fcData = JSON.stringify({ |
|
| 23 | + | version: "next", |
|
| 24 | + | imageUrl: fcImage, |
|
| 25 | + | button: { |
|
| 26 | + | title: "Read Blog", |
|
| 27 | + | action: { |
|
| 28 | + | type: "launch_frame", |
|
| 29 | + | name: "Read Blog", |
|
| 30 | + | url: canonicalURL, |
|
| 31 | + | splashImageUrl: "https://stevedylan.dev/splash.png", |
|
| 32 | + | splashBackgroundColor: "#000000" |
|
| 33 | + | } |
|
| 34 | + | } |
|
| 35 | + | }) |
|
| 17 | 36 | --- |
|
| 18 | 37 | ||
| 19 | 38 | <meta charset="utf-8" /> |
|
| 34 | 53 | <meta name="author" content={siteConfig.author} /> |
|
| 35 | 54 | ||
| 36 | 55 | <!-- Theme Colour --> |
|
| 37 | - | <meta name="theme-color" content={siteConfig.themeColorLight} /> |
|
| 56 | + | <meta name="theme-color" content="#000000" /> |
|
| 38 | 57 | ||
| 39 | 58 | <!-- Open Graph / Facebook --> |
|
| 40 | 59 | <meta property="og:type" content={articleDate ? "article" : "website"} /> |
|
| 64 | 83 | ||
| 65 | 84 | <!-- RSS auto-discovery --> |
|
| 66 | 85 | <link rel="alternate" type="application/rss+xml" title={siteConfig.title} href="/rss.xml" /> |
|
| 86 | + | ||
| 87 | + | <meta name="fc:frame" content={fcData} /> |
|
| 67 | 88 | ||
| 68 | 89 | <link |
|
| 69 | 90 | rel="preload" |
|
| 34 | 34 | ||
| 35 | 35 | </nav> |
|
| 36 | 36 | </footer> |
|
| 37 | + | ||
| 38 | + | <script type="module"> |
|
| 39 | + | import { sdk } from 'https://esm.sh/@farcaster/frame-sdk'; |
|
| 40 | + | window.onload = async () => { |
|
| 41 | + | try { |
|
| 42 | + | await sdk.actions.ready(); |
|
| 43 | + | await sdk.actions.addFrame(); |
|
| 44 | + | } catch (error) { |
|
| 45 | + | console.error(error); |
|
| 46 | + | } |
|
| 47 | + | }; |
|
| 48 | + | </script> |
| 6 | 6 | import SkipLink from "@/components/SkipLink"; |
|
| 7 | 7 | import siteConfig from "@/site-config"; |
|
| 8 | 8 | import { ViewTransitions } from "astro:transitions"; |
|
| 9 | - | import { Umami } from "astro-analytics"; |
|
| 10 | 9 | ||
| 11 | 10 | interface Props { |
|
| 12 | 11 | meta: SiteMeta; |
|
| 19 | 18 | ||
| 20 | 19 | <html lang={siteConfig.lang}> |
|
| 21 | 20 | <head> |
|
| 22 | - | <meta name="apple-mobile-web-app-capable" content="yes"> |
|
| 23 | - | <meta name="theme-color" content="#000000" /> |
|
| 21 | + | <meta name="apple-mobile-web-app-capable" content="yes"> |
|
| 22 | + | <meta name="theme-color" content="#000000" /> |
|
| 24 | 23 | <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> |
|
| 25 | 24 | <!-- Google tag (gtag.js) --> |
|
| 26 | 25 | <BaseHead title={title} description={description} ogImage={ogImage} articleDate={articleDate} /> |
|
| 27 | 26 | <script defer src="https://cloud.umami.is/script.js" data-website-id="6951e531-a667-495e-b045-4f7dbe062446"></script> |
|
| 28 | - | <!-- <script define:vars={{ siteConfig }}> |
|
| 29 | - | const root = document.documentElement; |
|
| 30 | - | const colorThemeMetaTag = document.querySelector("meta[name='theme-color']"); |
|
| 31 | - | ||
| 32 | - | // get user preference of dark mode, 1st local storage, 2nd browser |
|
| 33 | - | function getThemePreference() { |
|
| 34 | - | if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) { |
|
| 35 | - | return localStorage.getItem("theme"); |
|
| 36 | - | } |
|
| 37 | - | return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "dark"; |
|
| 38 | - | } |
|
| 39 | - | ||
| 40 | - | const isDark = getThemePreference() === "dark"; |
|
| 41 | - | ||
| 42 | - | // watch document element class attribute and update user preference when it changes. |
|
| 43 | - | const observer = new MutationObserver(() => { |
|
| 44 | - | const rootIsDark = root.classList.contains("dark"); |
|
| 45 | - | // set the meta attribute |
|
| 46 | - | colorThemeMetaTag.setAttribute( |
|
| 47 | - | "content", |
|
| 48 | - | siteConfig[rootIsDark ? "themeColorDark" : "themeColorLight"] |
|
| 49 | - | ); |
|
| 50 | - | // store user preference |
|
| 51 | - | if (typeof localStorage !== "undefined") { |
|
| 52 | - | localStorage.setItem("theme", rootIsDark ? "dark" : "dark"); |
|
| 53 | - | } |
|
| 54 | - | }); |
|
| 55 | - | observer.observe(root, { attributeFilter: ["class"] }); |
|
| 56 | - | ||
| 57 | - | // initailse root class attribute |
|
| 58 | - | root.classList.toggle("dark", isDark); |
|
| 59 | - | ||
| 60 | - | </script> --> |
|
| 61 | 27 | <ViewTransitions fallback="swap" /> |
|
| 62 | 28 | </head> |
|
| 63 | 29 | <body> |
|
| 1 | 1 | --- |
|
| 2 | 2 | import DecryptingHeader from "@/components/DecryptingHeader"; |
|
| 3 | 3 | import PageLayout from "@/layouts/Base"; |
|
| 4 | - | import GuestbookFeed from "src/components/GuestbookFeed"; |
|
| 4 | + | //import GuestbookFeed from "src/components/GuestbookFeed"; |
|
| 5 | 5 | ||
| 6 | 6 | const meta = { |
|
| 7 | 7 | title: "Guestbook", |
|
| 12 | 12 | <div class="space-y-6"> |
|
| 13 | 13 | <div class="flex flex-col gap-2 mb-6"> |
|
| 14 | 14 | <DecryptingHeader text="Guestbook" className="title mb-6" /> |
|
| 15 | - | <p>Welcome to my little digital guestbook! I built this using PGlite, Railway, Clerk, and <a href="https://pinata.cloud" class="style-link" target="_blank" rel="noreferrer">Pinata</a>, and you can <a href="/posts/building-a-guestbook-with-pglite-clerk-and-pinata" class="style-link">read about it here</a>. Login with your Github account to leave a message!</p> |
|
| 15 | + | <p>๐ง Under Construction ๐ง</p> |
|
| 16 | 16 | </div> |
|
| 17 | - | <GuestbookFeed API_URL={import.meta.env.PUBLIC_API_URL} client:only="react" /> |
|
| 18 | 17 | </div> |
|
| 19 | 18 | </PageLayout> |
|
| 23 | 23 | target="_blank" |
|
| 24 | 24 | rel="noopener noreferrer" |
|
| 25 | 25 | class="style-link">Orbiter</a |
|
| 26 | - | >, a simple yet open take on static site hosting. Take a look around and be sure to <a |
|
| 27 | - | class="style-link" |
|
| 28 | - | href="/guestbook" |
|
| 29 | - | data-astro-reload>sign my guestbook</a |
|
| 30 | - | >! |
|
| 31 | - | </p> |
|
| 26 | + | >, a simple yet open take on static site hosting.</p> |
|
| 32 | 27 | <SocialList /> |
|
| 33 | 28 | <p>Or anywhere with my handle <span class="text-accent">@stevedylandev</span></p> |
|
| 34 | 29 | </section> |