diff --git a/new-web/bun.lockb b/new-web/bun.lockb index 57046fa..cbfca21 100755 Binary files a/new-web/bun.lockb and b/new-web/bun.lockb differ diff --git a/new-web/package.json b/new-web/package.json index 496c0df..0d914a2 100644 --- a/new-web/package.json +++ b/new-web/package.json @@ -36,13 +36,16 @@ "type": "module", "dependencies": { "@iconify/svelte": "^4.0.2", + "@iconify/tailwind": "^1.1.3", "bits-ui": "^0.21.16", "copy-to-clipboard": "^3.3.3", "es-toolkit": "^1.26.1", + "mdsvex": "^0.12.3", "medium-zoom": "^1.1.0", + "shiki": "^1.23.1", + "shiki-transformer-copy-button": "^0.0.3", "svelte-bricks": "^0.2.1", "svelte-lazy": "1.2.9", - "svelte-legos": "^0.2.5", - "svelte-markdown": "^0.4.1" + "svelte-legos": "^0.2.5" } } diff --git a/new-web/src/app.css b/new-web/src/app.css index 08ce509..726e780 100644 --- a/new-web/src/app.css +++ b/new-web/src/app.css @@ -85,3 +85,99 @@ html { .medium-zoom-image--opened { z-index: 999; } + +@layer base { + /** + * Shiki + */ + pre.shiki { + counter-reset: line-number; + } + + pre.shiki code { + display: grid; + } + + pre.shiki, + pre.shiki span { + color: var(--shiki-light) !important; + background-color: transparent; + } + + /* html.dark pre.shiki, + html.dark pre.shiki span { + color: var(--shiki-dark) !important; + } */ + + pre.shiki .line { + counter-increment: line-number; + } + + pre.shiki .line:not(:last-of-type)::before { + content: counter(line-number); + color: hsl(240 5.3% 26.1%); + display: inline-block; + text-align: right; + margin-right: 1em; + width: 2ch; + } + + html.dark pre.shiki .line:not(:last-of-type)::before { + color: hsl(240 5% 64.9%); + } + + pre.shiki .diff.add { + background-color: hsla(141.7 76.6% 73.1% / 0.5); + } + pre.shiki .diff.remove { + background-color: hsla(0 93.5% 81.8% / 0.7); + } + + html.dark pre.shiki .diff.add { + background-color: hsla(143.8 61.2% 20.2% / 0.7); + } + html.dark pre.shiki .diff.remove { + background-color: hsla(0 62.8% 30.6% / 0.7); + } +} + +pre:has(code) { + position: relative; +} + +pre button.copy { + position: absolute; + right: 16px; + top: 16px; + height: 20px; + width: 20px; + padding: 0; + display: flex; + + & span { + width: 100%; + aspect-ratio: 1 / 1; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + } + + & .ready { + background-image: url("data:image/svg+xml;utf8,"); + } + + & .success { + display: none; + background-image: url("data:image/svg+xml;utf8,"); + } + + &.copied { + & .success { + display: block; + } + + & .ready { + display: none; + } + } +} diff --git a/new-web/src/lib/components/ui/sonner/sonner.svelte b/new-web/src/lib/components/ui/sonner/sonner.svelte index 7d5b2f1..dcff20b 100644 --- a/new-web/src/lib/components/ui/sonner/sonner.svelte +++ b/new-web/src/lib/components/ui/sonner/sonner.svelte @@ -1,8 +1,16 @@ diff --git a/new-web/src/lib/elements/ArticlePage.svelte b/new-web/src/lib/elements/ArticlePage.svelte index b78f40e..d07b5b6 100644 --- a/new-web/src/lib/elements/ArticlePage.svelte +++ b/new-web/src/lib/elements/ArticlePage.svelte @@ -1,10 +1,10 @@ @@ -89,76 +57,244 @@ Stay tuned for more exciting updates as we continue to revolutionize the world o
-
- {#if data.postImage} - - {/if} -
-

{formatDate(data.date)}

-

{data.title}

-
- -
-

{data.author.name}

-

{data.author.role}

+
+ {#if !contentLoaded} + +
+ + +
+ +
+ + +
-
- -
-
- {#if contentLoaded} - - {:else} -

Loading content...

- {/if} +
+
+ + + +
-
+ {:else} + {#if data.postImage} + + {/if} +
+

{formatDate(data.date)}

+

{data.title}

+
+ +
+

{data.author.name}

+

{data.author.role}

+
+
+
+ +
+
+ {#if contentLoaded} + {#if compiledContent} + + {:else} +

Error loading content

+ {/if} + {:else} +

Loading content...

+ {/if} +
+
+ {/if}
diff --git a/new-web/src/lib/elements/ReportProblem.svelte b/new-web/src/lib/elements/ReportProblem.svelte index a54f2e2..b76ad60 100644 --- a/new-web/src/lib/elements/ReportProblem.svelte +++ b/new-web/src/lib/elements/ReportProblem.svelte @@ -43,7 +43,7 @@ possible.

-
+
Problem Type @@ -111,7 +111,7 @@
-
+
Problem Type diff --git a/new-web/src/lib/test/blog01.md b/new-web/src/lib/test/blog01.md new file mode 100644 index 0000000..33eb71b --- /dev/null +++ b/new-web/src/lib/test/blog01.md @@ -0,0 +1,67 @@ +# V7 Is Here! 🚀 + +> "The best file upload solution just got even better!" - _Tech Weekly_ + +This release has been an absurd amount of work. So proud of the team and what we've built. Huge thanks to [Julius](https://github.com/julius) and [Mark](https://github.com/mark) for making this happen. + +--- + +It is so, so hard to not go straight into the nerdy details, but the whole point of UploadThing is that you don't need to know ANY of those details. With that in mind, here's what's relevant for most y'all: + +- UploadThing is now _way_ faster +- Uploads can be **paused** and _resumed_ seamlessly +- ~~Old limitations removed~~ +- More details... + +## Performance Comparison + +| Feature | V6 | V7 | +| ------------------ | ------ | --------- | +| Upload Speed | 10MB/s | 50MB/s | +| Concurrent Uploads | 100 | Unlimited | +| Max File Size | 2GB | 10GB | + +## Revolutionary Features + +We've completely overhauled our backend infrastructure to bring you unparalleled performance. Our new distributed processing system can handle millions of concurrent uploads without breaking a sweat. + +### Code Example + +```typescript +import { createUploadthing } from 'uploadthing/next'; + +const f = createUploadthing(); + +export const ourFileRouter = { + imageUploader: f({ image: { maxFileSize: '4MB' } }) + .middleware(async () => { + return { userId: 1234 }; + }) + .onUploadComplete(async ({ metadata, file }) => { + console.log('Upload complete for userId:', metadata.userId); + }) +}; +``` + +![Upload Dashboard](https://example.com/dashboard.png) + +### AI-Powered Optimization + +UploadThing now leverages cutting-edge machine learning algorithms to optimize your uploads in real-time. + +
+Technical Details + +- Uses TensorFlow.js for client-side optimizations +- Implements WebAssembly for performance +- Leverages Web Workers for background processing + +
+ +--- + +_For more information, visit our [documentation](https://docs.uploadthing.com)._ + +```js +console.log('Hello, world!'); +``` diff --git a/new-web/svelte.config.js b/new-web/svelte.config.js index 4a82086..58dafd3 100644 --- a/new-web/svelte.config.js +++ b/new-web/svelte.config.js @@ -1,16 +1,64 @@ +import { mdsvex, escapeSvelte } from 'mdsvex'; +import { createHighlighter } from 'shiki'; import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import { h } from 'hastscript'; + +export function addCopyButton(options = {}) { + const toggleMs = options.toggle || 3000; + + return { + name: 'shiki-transformer-copy-button', + pre(node) { + const button = h( + 'button', + { + class: 'copy', + 'data-code': this.source, + onclick: ` + navigator.clipboard.writeText(this.dataset.code); + this.classList.add('copied'); + setTimeout(() => this.classList.remove('copied'), ${toggleMs}); + window.dispatchEvent(new CustomEvent('toast', { detail: { message: 'Copied to clipboard' } })); + ` + }, + [h('span', { class: 'ready' }), h('span', { class: 'success' })] + ); + + node.children.push(button); + } + }; +} + +/** @type {import('mdsvex').MdsvexOptions} */ +const mdsvexOptions = { + extensions: ['.md'], + highlight: { + highlighter: async (code, lang = 'text') => { + const highlighter = await createHighlighter({ + themes: ['poimandres'], + langs: ['javascript', 'typescript'] + }); + await highlighter.loadLanguage('javascript', 'typescript'); + const html = escapeSvelte( + highlighter.codeToHtml(code, { + lang, + theme: 'poimandres', + transformers: [addCopyButton({ toggle: 1200 })] + }) + ); + return `{@html \`${html}\` }`; + } + } +}; + /** @type {import('@sveltejs/kit').Config} */ const config = { - // Consult https://kit.svelte.dev/docs/integrations#preprocessors - // for more information about preprocessors - preprocess: vitePreprocess(), + extensions: ['.svelte', '.md'], + preprocess: [vitePreprocess(), mdsvex(mdsvexOptions)], kit: { - // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. - // If your environment is not supported, or you settled on a specific environment, switch out the adapter. - // See https://kit.svelte.dev/docs/adapters for more information about adapters. adapter: adapter() } };