add share

This commit is contained in:
2024-03-12 22:33:27 +08:00
parent 8893550568
commit a51407c856
6 changed files with 288 additions and 866 deletions

1070
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -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"

View File

@@ -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 } }),
)
}

View File

@@ -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"

View File

@@ -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
View 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)
}