Compare commits

...

3 Commits

Author SHA1 Message Date
b700ef73ad Fixed hard redirection 2023-11-26 18:29:16 +01:00
0598e0c6bd Formatting 2023-11-26 17:24:21 +01:00
30e4d5c87e iframe layout 2023-11-26 17:19:01 +01:00
14 changed files with 145 additions and 78 deletions

View File

@ -1,10 +1,11 @@
{ {
"useTabs": false, "useTabs": false,
"singleQuote": true, "bracketSameLine": true,
"trailingComma": "es5", "singleQuote": true,
"printWidth": 100, "trailingComma": "es5",
"plugins": ["prettier-plugin-svelte"], "printWidth": 100,
"pluginSearchDirs": ["."], "plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"semi": false, "semi": false,
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
} }

14
src/app.d.ts vendored
View File

@ -1,12 +1,12 @@
// See https://kit.svelte.dev/docs/types#app // See https://kit.svelte.dev/docs/types#app
// for information about these interfaces // for information about these interfaces
declare global { declare global {
namespace App { namespace App {
// interface Error {} // interface Error {}
// interface Locals {} // interface Locals {}
// interface PageData {} // interface PageData {}
// interface Platform {} // interface Platform {}
} }
} }
export {}; export {}

View File

@ -23,7 +23,7 @@ npm/codemirror@5.65.16/theme/nord.min.css"
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="Paste - No-database paste service" /> <meta property="og:title" content="Paste - No-database paste service" />
<meta property="og:url" content="https://paste.scambier.xyz" /> <meta property="og:url" content="https://paste.scambier.xyz" />
<meta property="og:type" content="article" /> <meta property="og:type" content="website" />
<meta <meta
name="description" name="description"
property="og:description" property="og:description"

View File

@ -0,0 +1,22 @@
<script lang="ts">
export let isMarkdown: boolean
export let isPlainText: boolean
export let decompressed: string
export let htmlContent: string
let cssClass = ''
export { cssClass as class }
</script>
<div class={cssClass}>
{#if isMarkdown}
<div class="h-full p-2">
{@html htmlContent}
</div>
{:else if isPlainText}
<div class="whitespace-pre-line h-full">
{decompressed}
</div>
{:else}
<pre class="h-full"><code>{@html htmlContent}</code></pre>
{/if}
</div>

View File

@ -62,12 +62,10 @@
type="text" type="text"
bind:value={filter} bind:value={filter}
bind:this={inputFilter} bind:this={inputFilter}
class={$$restProps.class ?? ''} class={$$restProps.class ?? ''} />
/>
<div <div
class="absolute top-full left-0 w-full bg-gray-700 max-h-[90vh] overflow-y-auto" class="absolute top-full left-0 w-full bg-gray-700 max-h-[90vh] overflow-y-auto"
bind:this={divContainer} bind:this={divContainer}>
>
{#each filteredItems as item} {#each filteredItems as item}
<div class="p-1 hover:bg-gray-600" on:click={() => selectItem(item)}>{item.text}</div> <div class="p-1 hover:bg-gray-600" on:click={() => selectItem(item)}>{item.text}</div>
{/each} {/each}
@ -78,8 +76,7 @@
readonly readonly
value={value?.text ?? ''} value={value?.text ?? ''}
class={$$restProps.class ?? ''} class={$$restProps.class ?? ''}
on:click={showOptions} on:click={showOptions} />
/>
{/if} {/if}
</div> </div>

View File

@ -69,6 +69,25 @@
await updateShareUrl() await updateShareUrl()
isUrlInputVisible = true isUrlInputVisible = true
await tick() await tick()
urlInput.value = $shareUrl
urlInput.select()
}
async function showMarkdownLink() {
await updateShareUrl()
isUrlInputVisible = true
await tick()
urlInput.value = `[Paste snippet](${$shareUrl})`
urlInput.select()
}
async function showIframeCode() {
await updateShareUrl()
isUrlInputVisible = true
await tick()
// @ts-ignore
const height = Math.min(editor['doc'].height * 1.1 + 45, 500)
urlInput.value = `<iframe width="100%" height="${height}" frameborder="0" src="${$shareUrl}"></iframe>`
urlInput.select() urlInput.select()
} }
@ -94,11 +113,13 @@
<input <input
bind:this={urlInput} bind:this={urlInput}
type="text" type="text"
class="border border-gray-300 bg-transparent p-1 grow" class="border border-gray-300 bg-transparent p-1 grow" />
value={$shareUrl} <button class="button" on:click={copyUrl} title="Copy">
/> <Icon class="text-xl" icon="fluent:copy-16-regular" />
<button class="button" on:click={copyUrl}>Copy</button> </button>
<button class="button" on:click={closeUrlInput}>Close</button> <button class="button" on:click={closeUrlInput} title="Close">
<Icon class="text-xl" icon="material-symbols:close" />
</button>
</div> </div>
{:else} {:else}
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
@ -106,11 +127,8 @@
<ComboBox <ComboBox
items={languages} items={languages}
bind:value={selectedLanguage} bind:value={selectedLanguage}
class="bg-gray-700 border border-gray-300 p-1" class="bg-gray-700 border border-gray-300 p-1" />
/>
</div> </div>
<!-- Show link input-->
<button class="button" on:click={showUrlInput}>Get Link</button>
<!-- Toggle text wrap --> <!-- Toggle text wrap -->
<button class="button" title="Toggle text wrap" on:click={() => (textWrap = !textWrap)}> <button class="button" title="Toggle text wrap" on:click={() => (textWrap = !textWrap)}>
@ -121,6 +139,21 @@
{/if} {/if}
</button> </button>
<!-- Show link input -->
<button class="button" on:click={showUrlInput} title="Get sharing link">
<Icon class="text-xl" icon="ph:link-bold" />
</button>
<!-- Show markdown link -->
<button class="button" on:click={showMarkdownLink} title="Get markdown link">
<Icon class="text-xl" icon="simple-icons:markdown" />
</button>
<!-- Show HTML iframe -->
<button class="button" on:click={showIframeCode} title="Get iframe code">
<Icon class="text-xl" icon="fluent:code-24-regular" />
</button>
<!-- Switch to readonly view --> <!-- Switch to readonly view -->
<button class="button" on:click={goToPreview} title="Switch to read-only view"> <button class="button" on:click={goToPreview} title="Switch to read-only view">
<Icon class="text-xl" icon="fluent:eye-12-regular" /> <Icon class="text-xl" icon="fluent:eye-12-regular" />

View File

@ -2,11 +2,10 @@
</script> </script>
<div <div
class="flex flex-wrap justify-between items-center px-3 py-1 text-sm w-full z-10 shadow-md gap-2 font-mono bg-gray-700" class="flex flex-wrap justify-between items-center px-3 py-1 text-sm w-full z-10 shadow-md gap-2 font-mono bg-gray-700">
>
<div class="flex items-center"> <div class="flex items-center">
<h1 class="text-xl"> <h1 class="text-xl">
<a href="/create" title="Create a new note">Paste</a> <a href="/new" title="Create a new note">Paste</a>
</h1> </h1>
<span class="ml-8 text-xs"> <span class="ml-8 text-xs">
<a href="/about">About</a> <a href="/about">About</a>

View File

@ -34,3 +34,6 @@ export function getLangFromUrl() {
export const byId = (id: string) => document.getElementById(id) export const byId = (id: string) => document.getElementById(id)
export function isInIframe(): boolean {
return window !== window.parent
}

View File

@ -2,4 +2,4 @@
import '../app.postcss' import '../app.postcss'
</script> </script>
<slot /> <slot />

View File

@ -1,2 +1,2 @@
export const prerender = true export const prerender = true
export const ssr = false export const ssr = false

View File

@ -8,9 +8,11 @@
import rehypeStringify from 'rehype-stringify' import rehypeStringify from 'rehype-stringify'
import hljs from 'highlight.js' import hljs from 'highlight.js'
import 'highlight.js/styles/nord.min.css' import 'highlight.js/styles/nord.min.css'
import { getLangFromUrl, isInIframe } from '$lib/utils'
import TopBar from '../components/TopBar.svelte' import TopBar from '../components/TopBar.svelte'
import Icon from '@iconify/svelte' import Icon from '@iconify/svelte'
import { getLangFromUrl } from '$lib/utils' import CodeView from '../components/CodeView.svelte'
import { goto } from '$app/navigation'
let decompressed: string let decompressed: string
let htmlContent: string let htmlContent: string
@ -51,7 +53,7 @@
} }
} else { } else {
// Redirect to editor page // Redirect to editor page
window.location.href = '/editor' goto('/editor')
} }
}) })
@ -61,30 +63,42 @@
</script> </script>
<div class="overflow-hidden h-screen flex flex-col"> <div class="overflow-hidden h-screen flex flex-col">
<TopBar> {#if !isInIframe()}
<a <TopBar>
href={'/editor' + getUrlDataPart()} <a
class="p-1 hover:bg-gray-600/50" href={'/editor' + getUrlDataPart()}
title="Edit a copy of this note" class="p-1 hover:bg-gray-600/50"
> title="Edit a copy of this note">
<Icon class="text-xl" icon="fluent:document-edit-16-regular" /> <Icon class="text-xl" icon="fluent:document-edit-16-regular" />
</a> </a>
</TopBar> </TopBar>
{/if}
{#if htmlContent || decompressed} {#if htmlContent || decompressed}
<div class="overflow-y-auto grow"> <div class="overflow-y-auto grow pb-4">
<div class="prose dark:prose-invert lg:py-12 p-[0.5em] md:max-w-3xl md:mx-auto lg:max-w-4xl"> {#if isInIframe()}
{#if isMarkdown} <CodeView
{@html htmlContent} class="prose dark:prose-invert w-full max-w-full h-full"
{:else if isPlainText} {isMarkdown}
<div class="whitespace-pre-line"> {isPlainText}
{decompressed} {decompressed}
</div> {htmlContent} />
{:else} {:else}
<pre><code>{@html htmlContent}</code></pre> <CodeView
{/if} class="prose dark:prose-invert lg:py-12 p-[0.5em] md:max-w-3xl md:mx-auto lg:max-w-4xl"
</div> {isMarkdown}
{isPlainText}
{decompressed}
{htmlContent} />
{/if}
</div> </div>
{/if} {/if}
<footer
class="absolute bottom-0 left-0 w-full bg-gray-700 px-4 py-1 font-mono text-xs"
class:hidden={!isInIframe()}>
<a href={window.location.href} target="_blank">Powered by Paste</a>
</footer>
</div> </div>
<style lang="scss"> <style lang="scss">

View File

@ -66,11 +66,10 @@
editor.setValue(decompressed) editor.setValue(decompressed)
} }
} }
} }
</script> </script>
<svelte:head> <svelte:head>
<script <script
src="https://cdn.jsdelivr.net/combine/ src="https://cdn.jsdelivr.net/combine/
npm/codemirror@5.65.16, npm/codemirror@5.65.16,
@ -80,8 +79,7 @@ npm/codemirror@5.65.16/addon/mode/multiplex.min.js,
npm/codemirror@5.65.16/addon/mode/simple.min.js, npm/codemirror@5.65.16/addon/mode/simple.min.js,
npm/codemirror@5.65.16/addon/scroll/simplescrollbars.js, npm/codemirror@5.65.16/addon/scroll/simplescrollbars.js,
npm/codemirror@5.65.16/mode/meta.min.js" npm/codemirror@5.65.16/mode/meta.min.js"
on:load={initCodeEditor} on:load={initCodeEditor}></script>
></script>
</svelte:head> </svelte:head>
<div class="flex flex-col font-mono h-screen bg-gray-700"> <div class="flex flex-col font-mono h-screen bg-gray-700">

View File

@ -1,17 +1,17 @@
{ {
"extends": "./.svelte-kit/tsconfig.json", "extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"allowJs": true, "allowJs": true,
"checkJs": true, "checkJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"strict": true "strict": true
} }
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// //
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in // from the referenced tsconfig.json - TypeScript does not merge them in
} }