add share
This commit is contained in:
1070
package-lock.json
generated
1070
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "code-next",
|
"name": "code-next",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
@@ -11,24 +11,25 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-cpp": "^6.0.2",
|
"@codemirror/lang-cpp": "^6.0.2",
|
||||||
"@codemirror/lang-python": "^6.1.4",
|
"@codemirror/lang-python": "^6.1.4",
|
||||||
"@vueuse/core": "^10.8.0",
|
"@vueuse/core": "^10.9.0",
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.7",
|
||||||
"client-zip": "1.6.3",
|
"client-zip": "1.6.3",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"copy-text-to-clipboard": "^3.2.0",
|
"copy-text-to-clipboard": "^3.2.0",
|
||||||
|
"fflate": "^0.8.2",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"naive-ui": "^2.38.0",
|
"naive-ui": "^2.38.1",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"query-string": "^8.2.0",
|
"query-string": "^9.0.0",
|
||||||
"vue": "^3.4.19",
|
"vue": "^3.4.21",
|
||||||
"vue-codemirror": "^6.1.1"
|
"vue-codemirror": "^6.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/file-saver": "^2.0.7",
|
"@types/file-saver": "^2.0.7",
|
||||||
"@vitejs/plugin-legacy": "^5.3.1",
|
"@vitejs/plugin-legacy": "^5.3.2",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"terser": "^5.27.2",
|
"terser": "^5.29.1",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.1.4",
|
"vite": "^5.1.4",
|
||||||
"vue-tsc": "^1.8.27"
|
"vue-tsc": "^1.8.27"
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import { sources } from "../templates"
|
|||||||
import { submit } from "../api"
|
import { submit } from "../api"
|
||||||
import { useStorage } from "@vueuse/core"
|
import { useStorage } from "@vueuse/core"
|
||||||
import { isMobile } from "./breakpoints"
|
import { isMobile } from "./breakpoints"
|
||||||
|
import { atou, utoa } from "../utils"
|
||||||
|
import copyTextToClipboard from "copy-text-to-clipboard"
|
||||||
|
import queryString from "query-string"
|
||||||
|
|
||||||
const defaultLanguage = "python"
|
const defaultLanguage = "python"
|
||||||
|
|
||||||
@@ -18,14 +21,14 @@ const cache: Cache = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const code = reactive<Code>({
|
export const code = reactive<Code>({
|
||||||
value: cache.code[defaultLanguage].value,
|
value: sources[defaultLanguage],
|
||||||
language: cache.language.value,
|
language: defaultLanguage,
|
||||||
})
|
})
|
||||||
export const input = ref(cache.input.value)
|
export const input = ref("")
|
||||||
export const output = ref("")
|
export const output = ref("")
|
||||||
export const status = ref(Status.NotStarted)
|
export const status = ref(Status.NotStarted)
|
||||||
export const loading = ref(!code.value)
|
export const loading = ref(false)
|
||||||
export const size = ref(cache.fontsize)
|
export const size = ref(0)
|
||||||
|
|
||||||
watch(size, (value: number) => {
|
watch(size, (value: number) => {
|
||||||
cache.fontsize.value = value
|
cache.fontsize.value = value
|
||||||
@@ -59,6 +62,16 @@ export function init() {
|
|||||||
input.value = cache.input.value
|
input.value = cache.input.value
|
||||||
size.value = cache.fontsize.value
|
size.value = cache.fontsize.value
|
||||||
status.value = Status.NotStarted
|
status.value = Status.NotStarted
|
||||||
|
|
||||||
|
const parsed = queryString.parse(location.search)
|
||||||
|
const base64 = parsed.share as string
|
||||||
|
if (!base64) return
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(atou(base64))
|
||||||
|
code.language = data.lang
|
||||||
|
code.value = data.code
|
||||||
|
input.value = data.input
|
||||||
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearInput() {
|
export function clearInput() {
|
||||||
@@ -86,3 +99,15 @@ export async function run() {
|
|||||||
status.value = result.status
|
status.value = result.status
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function share() {
|
||||||
|
const data = {
|
||||||
|
lang: code.language,
|
||||||
|
code: code.value,
|
||||||
|
input: input.value,
|
||||||
|
}
|
||||||
|
const base64 = utoa(JSON.stringify(data))
|
||||||
|
copyTextToClipboard(
|
||||||
|
queryString.stringifyUrl({ url: location.href, query: { share: base64 } }),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { size, run, loading } from "../composables/code"
|
import { size, run, loading, share } from "../composables/code"
|
||||||
import ThemeButton from "../components/ThemeButton.vue"
|
import ThemeButton from "../components/ThemeButton.vue"
|
||||||
import SelectLanguage from "../components/SelectLanguage.vue"
|
import SelectLanguage from "../components/SelectLanguage.vue"
|
||||||
|
import { useMessage } from "naive-ui"
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
function handleShare() {
|
||||||
|
share()
|
||||||
|
message.success("分享链接已复制")
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -9,6 +17,7 @@ import SelectLanguage from "../components/SelectLanguage.vue"
|
|||||||
<n-flex justify="space-between" align="center">
|
<n-flex justify="space-between" align="center">
|
||||||
<div class="title">徐越的自测猫</div>
|
<div class="title">徐越的自测猫</div>
|
||||||
<n-flex>
|
<n-flex>
|
||||||
|
<n-button @click="handleShare">分享</n-button>
|
||||||
<ThemeButton />
|
<ThemeButton />
|
||||||
<n-input-number
|
<n-input-number
|
||||||
v-model:value="size"
|
v-model:value="size"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useMessage, type DropdownOption } from "naive-ui"
|
import { useMessage, type DropdownOption } from "naive-ui"
|
||||||
import { code, loading, reset, run } from "../composables/code"
|
import { code, loading, reset, run, share } from "../composables/code"
|
||||||
import { tab } from "../composables/tab"
|
import { tab } from "../composables/tab"
|
||||||
import copyTextToClipboard from "copy-text-to-clipboard"
|
import copyTextToClipboard from "copy-text-to-clipboard"
|
||||||
|
|
||||||
@@ -15,9 +15,15 @@ function copy() {
|
|||||||
message.success("已经复制好了")
|
message.success("已经复制好了")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleShare() {
|
||||||
|
share()
|
||||||
|
message.success("分享链接已复制")
|
||||||
|
}
|
||||||
|
|
||||||
const menu: DropdownOption[] = [
|
const menu: DropdownOption[] = [
|
||||||
{ label: "复制", key: "copy", props: { onClick: copy } },
|
{ label: "复制", key: "copy", props: { onClick: copy } },
|
||||||
{ label: "重置", key: "reset", props: { onClick: reset } },
|
{ label: "重置", key: "reset", props: { onClick: reset } },
|
||||||
|
{ label: "分享", key: "share", props: { onClick: handleShare } },
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
15
src/utils.ts
Normal file
15
src/utils.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { strFromU8, strToU8, unzlibSync, zlibSync } from "fflate"
|
||||||
|
|
||||||
|
export function utoa(data: string): string {
|
||||||
|
const buffer = strToU8(data)
|
||||||
|
const zipped = zlibSync(buffer, { level: 9 })
|
||||||
|
const binary = strFromU8(zipped, true)
|
||||||
|
return btoa(binary)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function atou(base64: string): string {
|
||||||
|
const binary = atob(base64)
|
||||||
|
const buffer = strToU8(binary, true)
|
||||||
|
const unzipped = unzlibSync(buffer)
|
||||||
|
return strFromU8(unzipped)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user