mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
Add colours and Sentry feedback form
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { SENTRY_DSN } from '$lib/config';
|
import { SENTRY_DSN } from '$lib/config';
|
||||||
import { init as initSentry, handleErrorWithSentry, makeBrowserOfflineTransport, makeFetchTransport } from '@sentry/sveltekit';
|
import { init as initSentry, handleErrorWithSentry, makeBrowserOfflineTransport, makeFetchTransport, feedbackIntegration } from '@sentry/sveltekit';
|
||||||
|
|
||||||
initSentry({
|
initSentry({
|
||||||
dsn: SENTRY_DSN,
|
dsn: SENTRY_DSN,
|
||||||
@@ -14,8 +14,9 @@ initSentry({
|
|||||||
// sessions when an error occurs.
|
// sessions when an error occurs.
|
||||||
replaysOnErrorSampleRate: 1.0,
|
replaysOnErrorSampleRate: 1.0,
|
||||||
|
|
||||||
// If you don't want to use Session Replay, just remove the line below:
|
integrations: [feedbackIntegration({
|
||||||
// integrations: [replayIntegration()],
|
autoInject: false,
|
||||||
|
})],
|
||||||
|
|
||||||
// To enable offline events caching, use makeBrowserOfflineTransport to wrap
|
// To enable offline events caching, use makeBrowserOfflineTransport to wrap
|
||||||
// existing transports and queue events using the browsers' IndexedDB storage
|
// existing transports and queue events using the browsers' IndexedDB storage
|
||||||
|
|||||||
@@ -33,6 +33,11 @@
|
|||||||
--code-background-color: #0d1117;
|
--code-background-color: #0d1117;
|
||||||
--code-color: #fff;
|
--code-color: #fff;
|
||||||
|
|
||||||
|
--color-primary: hsl(230, 50%, 90%);
|
||||||
|
--color-secondary: hsl(230, 50%, 10%);
|
||||||
|
--color-tertiary: hsl(290, 80%, 20%);
|
||||||
|
--color-accent: hsl(227, 80%, 20%);
|
||||||
|
|
||||||
--color-red: #e93147;
|
--color-red: #e93147;
|
||||||
--color-orange: #ec7500;
|
--color-orange: #ec7500;
|
||||||
--color-yellow: #e0ac00;
|
--color-yellow: #e0ac00;
|
||||||
@@ -60,6 +65,11 @@
|
|||||||
--font-color: rgba(255, 255, 255, .87);
|
--font-color: rgba(255, 255, 255, .87);
|
||||||
--font-color-contrast: rgba(0, 0, 0, .87);
|
--font-color-contrast: rgba(0, 0, 0, .87);
|
||||||
--font-color-secondary: rgba(255, 255, 255, .6);
|
--font-color-secondary: rgba(255, 255, 255, .6);
|
||||||
|
|
||||||
|
--color-primary: hsl(230, 50%, 10%);
|
||||||
|
--color-secondary: hsl(230, 50%, 90%);
|
||||||
|
--color-tertiary: hsl(290, 80%, 80%);
|
||||||
|
--color-accent: hsl(195, 80%, 80%);
|
||||||
|
|
||||||
--color-red: #fb464c;
|
--color-red: #fb464c;
|
||||||
--color-orange: #e9973f;
|
--color-orange: #e9973f;
|
||||||
@@ -109,7 +119,8 @@ html {
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe,
|
iframe,
|
||||||
@@ -125,6 +136,13 @@ svg {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: var(--color-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
--container-max-width: var(--page-width);
|
--container-max-width: var(--page-width);
|
||||||
--padding-x: var(--spacing);
|
--padding-x: var(--spacing);
|
||||||
@@ -176,3 +194,18 @@ svg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: inline-block;
|
||||||
|
color: var(--color-primary);
|
||||||
|
background: var(--color-accent);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 8px 8px 8px 0px;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border: solid 2px var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary {
|
||||||
|
border: solid 2px var(--color-accent);
|
||||||
|
color: var(--color-accent);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
import { bookmarkify, parseMeta } from "./bookmarklets";
|
import { bookmarkify, parseMeta } from "./bookmarklets";
|
||||||
import type { Config } from "./config";
|
import type { Config } from "./config";
|
||||||
import { init } from "$lib/workers/terser";
|
import { init } from "$lib/workers/terser";
|
||||||
import { SITE_URL } from '$lib/metadata';
|
import { SITE_URL } from "$lib/metadata";
|
||||||
|
|
||||||
/** @type {import('./$types').Snapshot<string>} */
|
/** @type {import('./$types').Snapshot<string>} */
|
||||||
export const snapshot = {
|
export const snapshot = {
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
restore: (v: string) => (value = v),
|
restore: (v: string) => (value = v),
|
||||||
};
|
};
|
||||||
|
|
||||||
let minify = init().minify
|
let minify = init().minify;
|
||||||
|
|
||||||
let value = "";
|
let value = "";
|
||||||
let output = "";
|
let output = "";
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let contentAttributes = {"aria-label": "Bookmarklet editor"}
|
let contentAttributes = { "aria-label": "Bookmarklet editor" };
|
||||||
|
|
||||||
$: progress = process(value);
|
$: progress = process(value);
|
||||||
</script>
|
</script>
|
||||||
@@ -36,34 +36,45 @@
|
|||||||
description="Make booklets in your browser with this tool. Make handy shortcuts to save time."
|
description="Make booklets in your browser with this tool. Make handy shortcuts to save time."
|
||||||
canonical={SITE_URL + "/bookmarklets"}
|
canonical={SITE_URL + "/bookmarklets"}
|
||||||
/>
|
/>
|
||||||
<h1>Bookmarklet Maker</h1>
|
|
||||||
<Editor
|
|
||||||
{value}
|
|
||||||
on:change={(e) => (value = e.detail)}
|
|
||||||
lang={javascript()}
|
|
||||||
{contentAttributes}
|
|
||||||
>
|
|
||||||
<div slot="header" class="code-header">Input</div>
|
|
||||||
</Editor>
|
|
||||||
|
|
||||||
<h2>Output</h2>
|
<main class="main container" id="page-content">
|
||||||
{#await progress}
|
<h1>Bookmarklet Maker</h1>
|
||||||
<p>...waiting</p>
|
<Editor
|
||||||
{:catch error}
|
{value}
|
||||||
<p style="color: red">{error.message}</p>
|
on:change={(e) => (value = e.detail)}
|
||||||
{/await}
|
lang={javascript()}
|
||||||
<label for="output">Bookmarklet code</label>
|
{contentAttributes}
|
||||||
<textarea name="output" id="output" class="output card" rows="1" value={output} readonly
|
>
|
||||||
></textarea>
|
<div slot="header" class="code-header">Input</div>
|
||||||
|
</Editor>
|
||||||
|
|
||||||
<!-- <Editor readonly={true} /> -->
|
<h2>Output</h2>
|
||||||
<p>
|
{#await progress}
|
||||||
Bookmark this link: <a href={output}>{options.name || "My Bookmarklet"}</a>
|
<p>...waiting</p>
|
||||||
</p>
|
{:catch error}
|
||||||
<p>
|
<p style="color: red">{error.message}</p>
|
||||||
Either drag the link to your bookmarlets bar or, on FireFox, right click and
|
{/await}
|
||||||
select "Bookmark Link".
|
<label for="output">Bookmarklet code</label>
|
||||||
</p>
|
<textarea
|
||||||
|
name="output"
|
||||||
|
id="output"
|
||||||
|
class="output card"
|
||||||
|
rows="1"
|
||||||
|
value={output}
|
||||||
|
readonly
|
||||||
|
></textarea>
|
||||||
|
|
||||||
|
<!-- <Editor readonly={true} /> -->
|
||||||
|
<p>
|
||||||
|
Bookmark this link: <a href={output}
|
||||||
|
>{options.name || "My Bookmarklet"}</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Either drag the link to your bookmarlets bar or, on FireFox, right click
|
||||||
|
and select "Bookmark Link".
|
||||||
|
</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.code-header {
|
.code-header {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { javascript } from "@codemirror/lang-javascript";
|
import { javascript } from "@codemirror/lang-javascript";
|
||||||
import SvelteSeo from "svelte-seo";
|
import SvelteSeo from "svelte-seo";
|
||||||
import { init } from "$lib/workers/terser";
|
import { init } from "$lib/workers/terser";
|
||||||
import { SITE_URL } from '$lib/metadata';
|
import { SITE_URL } from "$lib/metadata";
|
||||||
|
|
||||||
/** @type {import('./$types').Snapshot<string>} */
|
/** @type {import('./$types').Snapshot<string>} */
|
||||||
export const snapshot = {
|
export const snapshot = {
|
||||||
@@ -11,24 +11,24 @@
|
|||||||
restore: (v: string) => (value = v),
|
restore: (v: string) => (value = v),
|
||||||
};
|
};
|
||||||
|
|
||||||
let minify = init().minify
|
let minify = init().minify;
|
||||||
|
|
||||||
let value = "";
|
let value = "";
|
||||||
let output = "";
|
let output = "";
|
||||||
async function process(str: string) {
|
async function process(str: string) {
|
||||||
if (value === "") {
|
if (value === "") {
|
||||||
output = "";
|
output = "";
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
let result = await minify(str)
|
let result = await minify(str);
|
||||||
if (typeof result.code == "string") {
|
if (typeof result.code == "string") {
|
||||||
output = result.code
|
output = result.code;
|
||||||
} else {
|
} else {
|
||||||
console.error(result)
|
console.error(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let contentAttributes = {"aria-label": "Javascript editor"}
|
let contentAttributes = { "aria-label": "Javascript editor" };
|
||||||
|
|
||||||
$: progress = process(value);
|
$: progress = process(value);
|
||||||
</script>
|
</script>
|
||||||
@@ -38,26 +38,34 @@
|
|||||||
description="Reduce JavaScript code size with this handy online tool. It's easy to minify your JavaScript code."
|
description="Reduce JavaScript code size with this handy online tool. It's easy to minify your JavaScript code."
|
||||||
canonical={SITE_URL + "/javascript-minifier"}
|
canonical={SITE_URL + "/javascript-minifier"}
|
||||||
/>
|
/>
|
||||||
<h1>Javascript Minifier</h1>
|
|
||||||
<Editor
|
|
||||||
{value}
|
|
||||||
on:change={(e) => (value = e.detail)}
|
|
||||||
lang={javascript()}
|
|
||||||
{contentAttributes}
|
|
||||||
>
|
|
||||||
<div slot="header" class="code-header">Input</div>
|
|
||||||
</Editor>
|
|
||||||
|
|
||||||
<h2>Output</h2>
|
<main class="main container" id="page-content">
|
||||||
{#await progress}
|
<h1>Javascript Minifier</h1>
|
||||||
<p>...waiting</p>
|
<Editor
|
||||||
{:catch error}
|
{value}
|
||||||
<p style="color: red">{error.message}</p>
|
on:change={(e) => (value = e.detail)}
|
||||||
{/await}
|
lang={javascript()}
|
||||||
<label for="output">Minified code</label>
|
{contentAttributes}
|
||||||
<textarea name="output" id="output" class="output card" rows="1" value={output} readonly
|
>
|
||||||
></textarea>
|
<div slot="header" class="code-header">Input</div>
|
||||||
|
</Editor>
|
||||||
|
|
||||||
|
<h2>Output</h2>
|
||||||
|
{#await progress}
|
||||||
|
<p>...waiting</p>
|
||||||
|
{:catch error}
|
||||||
|
<p style="color: red">{error.message}</p>
|
||||||
|
{/await}
|
||||||
|
<label for="output">Minified code</label>
|
||||||
|
<textarea
|
||||||
|
name="output"
|
||||||
|
id="output"
|
||||||
|
class="output card"
|
||||||
|
rows="1"
|
||||||
|
value={output}
|
||||||
|
readonly
|
||||||
|
></textarea>
|
||||||
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.code-header {
|
.code-header {
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { page } from "$app/stores";
|
||||||
|
import * as Sentry from "@sentry/sveltekit";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import SvelteSeo from "svelte-seo";
|
||||||
|
|
||||||
|
const { status, error } = $page;
|
||||||
|
const message = error?.message || "Hmm";
|
||||||
|
const title = `${status}: ${message}`;
|
||||||
|
let sentryElement: HTMLDivElement;
|
||||||
|
let openForm = () => {};
|
||||||
|
onMount(async () => {
|
||||||
|
const feedback = Sentry.getFeedback({
|
||||||
|
el: sentryElement,
|
||||||
|
});
|
||||||
|
if (!feedback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// console.log("feedback", feedback);
|
||||||
|
const form = await feedback.createForm({});
|
||||||
|
form.appendToDom();
|
||||||
|
form.open();
|
||||||
|
openForm = async () => {
|
||||||
|
form.open();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SvelteSeo {title} />
|
||||||
|
|
||||||
|
<main class="main container" id="page-content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<div bind:this={sentryElement} class="feedback"></div>
|
||||||
|
<button on:click={openForm}>Send Feedback</button>
|
||||||
|
<button class="secondary" on:click={()=> window.location.reload()}>Reload</button>
|
||||||
|
<!-- <div role="doc-subtitle">{status}</div> -->
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
flex-grow: 2;
|
||||||
|
width: 40vw;
|
||||||
|
max-width: 500px;
|
||||||
|
margin: 0 auto;
|
||||||
|
/* display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing);
|
||||||
|
margin: 48px auto;
|
||||||
|
max-width: 320px;
|
||||||
|
padding: 3rem 0.5rem; */
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 4em;
|
||||||
|
/* font-weight: 100; */
|
||||||
|
}
|
||||||
|
/* [role="doc-subtitle"] {
|
||||||
|
padding-block-start: 0;
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: 600;
|
||||||
|
} */
|
||||||
|
:global(#sentry-feedback) {
|
||||||
|
--dialog-inset: auto auto 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
width: 95%;
|
||||||
|
font-size: 1.5em;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -11,7 +11,4 @@
|
|||||||
<meta property="og:site_name" content={SITE_TITLE}>
|
<meta property="og:site_name" content={SITE_TITLE}>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
<Nav />
|
<Nav />
|
||||||
<main class="main container" id="page-content">
|
<slot />
|
||||||
<slot />
|
|
||||||
|
|
||||||
</main>
|
|
||||||
@@ -6,15 +6,27 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<link rel="alternate" type="application/rss+xml" title={SITE_TITLE} href={SITE_URL + "/blog/rss.xml"}>
|
<link
|
||||||
<link rel="alternate" type="application/feed+json" title={SITE_TITLE} href={SITE_URL + "/blog/feed.json"}>
|
rel="alternate"
|
||||||
|
type="application/rss+xml"
|
||||||
|
title={SITE_TITLE}
|
||||||
|
href={SITE_URL + "/blog/rss.xml"}
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="alternate"
|
||||||
|
type="application/feed+json"
|
||||||
|
title={SITE_TITLE}
|
||||||
|
href={SITE_URL + "/blog/feed.json"}
|
||||||
|
/>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<SvelteSeo
|
<SvelteSeo
|
||||||
title="Jade Ellis"
|
title="Jade Ellis"
|
||||||
description="Student, Creative & Computer Scientist. See what I'm doing."
|
description="Student, Creative & Computer Scientist. See what I'm doing."
|
||||||
canonical="https://jade.ellis.link"
|
canonical="https://jade.ellis.link"
|
||||||
/>
|
/>
|
||||||
<Hero />
|
|
||||||
|
|
||||||
<Homepage />
|
<main class="main container" id="page-content">
|
||||||
|
<Hero />
|
||||||
|
<Homepage />
|
||||||
|
</main>
|
||||||
|
|||||||
@@ -53,44 +53,46 @@
|
|||||||
|
|
||||||
<SvelteSeo title="Jade's Blog - Posts" canonical={SITE_URL + "/blog"} />
|
<SvelteSeo title="Jade's Blog - Posts" canonical={SITE_URL + "/blog"} />
|
||||||
|
|
||||||
<section role="feed" class="h-feed" id="feed">
|
<main class="main container" id="page-content">
|
||||||
<h1 class="p-name">
|
<section role="feed" class="h-feed" id="feed">
|
||||||
<a
|
<h1 class="p-name">
|
||||||
aria-hidden="true"
|
<a
|
||||||
tabindex="-1"
|
aria-hidden="true"
|
||||||
class="u-url permalink"
|
tabindex="-1"
|
||||||
href={SITE_URL + "/blog#feed"}>#</a
|
class="u-url permalink"
|
||||||
>Jade's Blog - Posts
|
href={SITE_URL + "/blog#feed"}>#</a
|
||||||
</h1>
|
>Jade's Blog - Posts
|
||||||
{#each pages as post, index}
|
</h1>
|
||||||
<article
|
{#each pages as post, index}
|
||||||
aria-posinset={index + 1}
|
<article
|
||||||
aria-setsize={pages.length}
|
aria-posinset={index + 1}
|
||||||
class="h-entry"
|
aria-setsize={pages.length}
|
||||||
>
|
class="h-entry"
|
||||||
<div class="content" data-sveltekit-preload-data="hover">
|
>
|
||||||
<h2>
|
<div class="content" data-sveltekit-preload-data="hover">
|
||||||
<a class="u-url p-name" href="/blog/{post.canonical}">
|
<h2>
|
||||||
{post.title}
|
<a class="u-url p-name" href="/blog/{post.canonical}">
|
||||||
</a>
|
{post.title}
|
||||||
</h2>
|
</a>
|
||||||
<span class="quiet"
|
</h2>
|
||||||
><time class="dt-published" datetime={post.date}
|
<span class="quiet"
|
||||||
>{new Date(post.date).toLocaleDateString()}</time
|
><time class="dt-published" datetime={post.date}
|
||||||
></span
|
>{new Date(post.date).toLocaleDateString()}</time
|
||||||
>
|
></span
|
||||||
{#if post.description}
|
>
|
||||||
<p class="p-summary">{post.description}</p>
|
{#if post.description}
|
||||||
{/if}
|
<p class="p-summary">{post.description}</p>
|
||||||
</div>
|
{/if}
|
||||||
</article>
|
</div>
|
||||||
{:else}
|
</article>
|
||||||
<p>No posts yet!</p>
|
{:else}
|
||||||
{/each}
|
<p>No posts yet!</p>
|
||||||
<!-- {#if showPosts < postCount}
|
{/each}
|
||||||
|
<!-- {#if showPosts < postCount}
|
||||||
<button type="submit" on:click={handleClick}>See more {H_ELLIPSIS_ENTITY}</button>
|
<button type="submit" on:click={handleClick}>See more {H_ELLIPSIS_ENTITY}</button>
|
||||||
{/if} -->
|
{/if} -->
|
||||||
</section>
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.permalink {
|
.permalink {
|
||||||
|
|||||||
@@ -48,11 +48,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
gtag("event", "share", {
|
gtag("event", "share", {
|
||||||
"share_url": url.href,
|
share_url: url.href,
|
||||||
"share_title": data.post.title,
|
share_title: data.post.title,
|
||||||
"share_button": "article_top",
|
share_button: "article_top",
|
||||||
"method": "navigator_share",
|
method: "navigator_share",
|
||||||
"content_type": "article",
|
content_type: "article",
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error.toString().includes("AbortError")) {
|
if (error.toString().includes("AbortError")) {
|
||||||
@@ -176,42 +176,44 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<article class="h-entry">
|
<main class="main container" id="page-content">
|
||||||
<h1 id="title" class="p-name">{data.post.title}</h1>
|
<article class="h-entry">
|
||||||
<aside>
|
<h1 id="title" class="p-name">{data.post.title}</h1>
|
||||||
<a class="u-url ib" href={canonical}
|
<aside>
|
||||||
>Published on <time
|
<a class="u-url ib" href={canonical}
|
||||||
class="dt-published ib"
|
>Published on <time
|
||||||
datetime={data.post.date}
|
class="dt-published ib"
|
||||||
>{new Date(data.post.date).toLocaleDateString()}</time
|
datetime={data.post.date}
|
||||||
></a
|
>{new Date(data.post.date).toLocaleDateString()}</time
|
||||||
>
|
></a
|
||||||
<span class="author p-author h-card vcard ib">
|
>
|
||||||
by <img
|
<span class="author p-author h-card vcard ib">
|
||||||
loading="lazy"
|
by <img
|
||||||
style="display: none;"
|
loading="lazy"
|
||||||
src={defaultAuthor.image}
|
style="display: none;"
|
||||||
class="avatar avatar-96 photo u-photo"
|
src={defaultAuthor.image}
|
||||||
/><a class="u-url url fn n p-name" href={defaultAuthor.url}
|
class="avatar avatar-96 photo u-photo"
|
||||||
>{defaultAuthor.name}</a
|
/><a class="u-url url fn n p-name" href={defaultAuthor.url}
|
||||||
></span
|
>{defaultAuthor.name}</a
|
||||||
>
|
></span
|
||||||
· <span class="reading-time ib">{data.post.readingTime.text}</span>
|
>
|
||||||
{#if webShareAPISupported}
|
· <span class="reading-time ib">{data.post.readingTime.text}</span>
|
||||||
· <button class="link" on:click={handleWebShare}>Share</button>
|
{#if webShareAPISupported}
|
||||||
{/if}
|
· <button class="link" on:click={handleWebShare}>Share</button>
|
||||||
</aside>
|
{/if}
|
||||||
<Toc headings={data.post.headings} />
|
</aside>
|
||||||
<!-- {#await GhReleasesDownload}
|
<Toc headings={data.post.headings} />
|
||||||
|
<!-- {#await GhReleasesDownload}
|
||||||
|
|
||||||
{:then component}
|
{:then component}
|
||||||
<svelte:component this={component} releaseData={data.ghReleaseData} />
|
<svelte:component this={component} releaseData={data.ghReleaseData} />
|
||||||
{/await} -->
|
{/await} -->
|
||||||
|
|
||||||
<div class="e-content">
|
<div class="e-content">
|
||||||
<svelte:component this={data.component} />
|
<svelte:component this={data.component} />
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
aside {
|
aside {
|
||||||
|
|||||||
@@ -18,15 +18,18 @@
|
|||||||
description={data.post.description}
|
description={data.post.description}
|
||||||
canonical={SITE_URL + "/projects/" + data.post.slug}
|
canonical={SITE_URL + "/projects/" + data.post.slug}
|
||||||
/>
|
/>
|
||||||
<h1>{data.post.title}</h1>
|
|
||||||
<!-- {#await GhReleasesDownload}
|
<main class="main container" id="page-content">
|
||||||
|
<h1>{data.post.title}</h1>
|
||||||
|
<!-- {#await GhReleasesDownload}
|
||||||
|
|
||||||
{:then component}
|
{:then component}
|
||||||
<svelte:component this={component} releaseData={data.ghReleaseData} />
|
<svelte:component this={component} releaseData={data.ghReleaseData} />
|
||||||
{/await} -->
|
{/await} -->
|
||||||
|
|
||||||
{#if data.ghReleaseData}
|
{#if data.ghReleaseData}
|
||||||
<GhReleasesDownload releaseData={data.ghReleaseData} />
|
<GhReleasesDownload releaseData={data.ghReleaseData} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<svelte:component this={data.component} />
|
<svelte:component this={data.component} />
|
||||||
|
</main>
|
||||||
|
|||||||
Reference in New Issue
Block a user