Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6 change ways to exportcopy codes #7

Merged
merged 8 commits into from
May 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,20 @@ input,
select {
@apply px-4 py-2 rounded-lg border placeholder-gray-300 transition focus:outline-blue-500;
}

.hljs-tag,
.hljs-name,
.hljs-punctuation,
.hljs-attr {
@apply !text-gray-400;
}

.Vue-Toastification__container {
@apply !mt-4 md:!mt-0 !px-4;
}
.Vue-Toastification__toast {
@apply !rounded-xl;
}
.Vue-Toastification__toast--success {
@apply !bg-blue-500;
}
35 changes: 35 additions & 0 deletions components/Modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { onClickOutside } from "@vueuse/core"
const prop = defineProps({
open: Boolean,
})
const emit = defineEmits(["close"])

const target = ref()
onClickOutside(target, (e) => {
emit("close")
})

watch(
() => prop.open,
(n) => {
n ? document.body.classList.add("overflow-hidden") : document.body.classList.remove("overflow-hidden")
}
)
</script>

<template>
<Teleport to="body">
<div
v-if="open"
class="w-screen h-screen fixed flex justify-center items-center top-0 left-0 bg-light-100 bg-opacity-25 p-4 md:p-8"
>
<div
ref="target"
class="overflow-y-scroll bg-white w-full max-w-screen-md h-full max-h-screen-md rounded-2xl border flex flex-col"
>
<slot></slot>
</div>
</div>
</Teleport>
</template>
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"dependencies": {
"@vueuse/core": "^8.4.2",
"@yeger/vue-masonry-wall": "^3.0.30",
"json-format-highlight": "^1.0.4",
"node-html-parser": "^5.3.3"
"highlight.js": "^11.5.1",
"node-html-parser": "^5.3.3",
"vue-toastification": "^2.0.0-rc.5"
}
}
59 changes: 50 additions & 9 deletions pages/create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import { useStorage } from "@vueuse/core"
import { useClipboard } from "@vueuse/core"
import { obtainCss } from "~~/function"
import { useToast } from "vue-toastification"

const toast = useToast()
const tweetsInput = useStorage("tweets", ["", "", "", "", ""])
const tweetsOptions = useStorage("tweets-options", { layout: "", css: "" })
const exportOptions = useStorage("export-options", {})
Expand All @@ -11,20 +13,36 @@ const computedInput = computed(() => tweetsInput.value.filter((i) => i != ""))
const contentRef = ref()
const tweetsRef = ref([])

const tweetsCode = ref()
const getTweetsHTML = () => {
let tweets = document.querySelectorAll(".tweet-container")
let innerHTML = ""
let innerHTMLs = ""
tweets.forEach((i) => {
innerHTML += i.innerHTML
innerHTMLs += i.innerHTML
})
return innerHTML
return innerHTMLs
}

const { copy } = useClipboard()
const copyAll = () => {
const { copy, copied } = useClipboard()
const copyTweet = async (index: number) => {
let tweets = document.querySelectorAll(".tweet-container")
let text = tweets[index]?.innerHTML
try {
await copy(text)
toast.success("Copied Static Tweet")
} catch (err) {
toast.error("Something wrong...")
}
}
const copyAll = async () => {
let text = getTweetsHTML() + obtainCss(tweetsOptions.value)
if (!text.length) return
copy(text)
try {
await copy(text)
toast.success("Copied All Static Tweets")
} catch (err) {
toast.error("Something wrong...")
}
}

const downloadAll = () => {
Expand All @@ -43,6 +61,12 @@ onMounted(() => {
isMounted.value = "true"
}, 500)
})

const isModalOpen = ref(false)
const openModal = () => {
isModalOpen.value = true
tweetsCode.value = getTweetsHTML()
}
useCustomHead("Tweetic | Create now!", "Create your own static tweets now!")
</script>

Expand Down Expand Up @@ -88,8 +112,7 @@ useCustomHead("Tweetic | Create now!", "Create your own static tweets now!")

<div class="mt-20 flex flex-col">
<div class="mt-2 flex space-x-2">
<button @click="copyAll" class="btn btn-primary">Copy</button>
<button @click="downloadAll" class="btn btn-primary">Download</button>
<button @click="openModal" class="btn btn-primary">Preview Code</button>
</div>
</div>
</div>
Expand All @@ -108,9 +131,27 @@ useCustomHead("Tweetic | Create now!", "Create your own static tweets now!")
:gap="10"
>
<template #default="{ item, index }">
<Tweet ref="tweetsRef" class="tweet-container" :url="item" v-bind="tweetsOptions"></Tweet>
<div
@click="copyTweet(index)"
class="ring-0 hover:ring-2 ring-light-700 transition rounded-2xl cursor-pointer"
>
<Tweet ref="tweetsRef" class="tweet-container" :url="item" v-bind="tweetsOptions"></Tweet>
</div>
</template>
</MasonryWall>

<Modal :open="isModalOpen" @close="isModalOpen = $event">
<div class="p-4 md:p-8 !pb-0 flex items-center justify-between">
<h2 class="text-2xl md:text-4xl font-bold text-gray-300">Export</h2>
<button @click="copyAll" class="btn btn-primary">{{ copied ? "Copied" : "Copy All" }}</button>
</div>
<div class="p-4 md:p-8 !pt-4 w-full h-full">
<pre
class="overflow-x-auto text-sm p-2 rounded-xl bg-light-400"
v-html="$hljs.highlight(tweetsCode, { language: 'html' }).value"
></pre>
</div>
</Modal>
</ClientOnly>
</div>
</template>
8 changes: 5 additions & 3 deletions pages/docs.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<script setup lang="ts">
import formatHighlight from "json-format-highlight"

const params = ref({
url: "https://twitter.com/zernonia/status/1524620865987506176",
layout: "supabase",
css: "tailwind",
})

const { $hljs } = useNuxtApp()
const tweetRef = ref()
const highlightResponse = computed(() =>
tweetRef.value?.data ? formatHighlight(tweetRef.value.data).replaceAll("white-space:pre-wrap;", "") : ""
tweetRef.value?.data
? $hljs.highlight(JSON.stringify(tweetRef.value.data, null, " "), { language: "json", ignoreIllegals: false })
.value
: ""
)
</script>

Expand Down
15 changes: 15 additions & 0 deletions plugins/highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import hljs from "highlight.js/lib/core"
import json from "highlight.js/lib/languages/json"
import html from "highlight.js/lib/languages/xml"
import "highlight.js/styles/base16/github.css"

export default defineNuxtPlugin(() => {
hljs.registerLanguage("json", json)
hljs.registerLanguage("html", html)

return {
provide: {
hljs,
},
}
})
13 changes: 13 additions & 0 deletions plugins/toast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Toast, { PluginOptions, POSITION } from "vue-toastification"
import "vue-toastification/dist/index.css"

const options: PluginOptions = {
position: POSITION.TOP_CENTER,
maxToasts: 1,
timeout: 2000,
transition: "Vue-Toastification__fade",
}

export default defineNuxtPlugin((nuxt) => {
nuxt.vueApp.use(Toast, options)
})
45 changes: 19 additions & 26 deletions server/_lib/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,30 @@ export const constructHtml = (oembed: TweetOembed, options: TweetOptions) => {
<div class="${mapClassOptions("tweet-header")}">
${
options.layout == "supabase"
? `
<div class="${mapClassOptions("tweet-author")}">
<svg class="${mapClassOptions(
"tweet-logo"
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23Z"></path></svg>

<img class="${mapClassOptions("tweet-author-image")}" src="${author_image}" >
<div class="${mapClassOptions("tweet-author-info")}">
<p class="${mapClassOptions("tweet-author-name")}"></p>
<a class="${mapClassOptions("tweet-author-handler")}" target="_blank" href="${
? `<div class="${mapClassOptions("tweet-author")}">
<svg class="${mapClassOptions(
"tweet-logo"
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23Z"></path></svg>
<img class="${mapClassOptions("tweet-author-image")}" src="${author_image}" >
<div class="${mapClassOptions("tweet-author-info")}">
<p class="${mapClassOptions("tweet-author-name")}"></p>
<a class="${mapClassOptions("tweet-author-handler")}" target="_blank" href="${
oembed.author_url
}">${author_handler}</a>
</div>
</div>

`
: `
<div class="${mapClassOptions("tweet-author")}">
<img class="${mapClassOptions("tweet-author-image")}" src="${author_image}" >
<div class="${mapClassOptions("tweet-author-info")}">
<p class="${mapClassOptions("tweet-author-name")}">${author_name}</p>
<a class="${mapClassOptions("tweet-author-handler")}" target="_blank" href="${
</div>`
: `<div class="${mapClassOptions("tweet-author")}">
<img class="${mapClassOptions("tweet-author-image")}" src="${author_image}" >
<div class="${mapClassOptions("tweet-author-info")}">
<p class="${mapClassOptions("tweet-author-name")}">${author_name}</p>
<a class="${mapClassOptions("tweet-author-handler")}" target="_blank" href="${
oembed.author_url
}">${author_handler}</a>
</div>
</div>

<svg class="${mapClassOptions(
"tweet-logo"
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23Z"></path></svg>
`
</div>
</div>
<svg class="${mapClassOptions(
"tweet-logo"
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23Z"></path></svg>`
}
</div>

Expand Down
15 changes: 10 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==

highlight.js@^11.5.1:
version "11.5.1"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.5.1.tgz#027c24e4509e2f4dcd00b4a6dda542ce0a1f7aea"
integrity sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==

hookable@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.1.1.tgz#8e4cf052da4382ee232138cd9425369b9d5b280e"
Expand Down Expand Up @@ -2529,11 +2534,6 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==

json-format-highlight@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/json-format-highlight/-/json-format-highlight-1.0.4.tgz#2e44277edabcec79a3d2c84e984c62e2258037b9"
integrity sha512-RqenIjKr1I99XfXPAml9G7YlEZg/GnsH7emWyWJh2yuGXqHW8spN7qx6/ME+MoIBb35/fxrMC9Jauj6nvGe4Mg==

json-schema-traverse@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
Expand Down Expand Up @@ -4599,6 +4599,11 @@ vue-router@^4.0.15:
dependencies:
"@vue/devtools-api" "^6.0.0"

vue-toastification@^2.0.0-rc.5:
version "2.0.0-rc.5"
resolved "https://registry.yarnpkg.com/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz#92798604d806ae473cfb76ed776fae294280f8f8"
integrity sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==

vue@^3.2.33:
version "3.2.33"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.33.tgz#7867eb16a3293a28c4d190a837bc447878bd64c2"
Expand Down