Skip to content

Commit

Permalink
feat(labels): added ability to add labels to text section
Browse files Browse the repository at this point in the history
  • Loading branch information
technikhil314 committed May 30, 2022
1 parent 72e23b4 commit fc86793
Show file tree
Hide file tree
Showing 3 changed files with 304 additions and 33 deletions.
3 changes: 0 additions & 3 deletions pages/diff.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ export default {
copied: false,
}
},
asyncData() {
return { name: 'World' }
},
mounted() {
const _diff = this.$route.hash
const gunzip = pako.ungzip(Buffer.from(undoUrlSafeBase64(_diff), 'base64'))
Expand Down
86 changes: 56 additions & 30 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,47 @@
</h2>
</header>
</section>
<form class="w-full" @submit="checkForm">
<div class="flex flex-wrap w-full gap-4">
<textarea
rows="28"
id="lhs"
class="flex-1 bg-transparent rounded-md resize-none form-textarea"
></textarea>
<textarea
id="rhs"
rows="28"
class="flex-1 bg-transparent rounded-md resize-none form-textarea"
></textarea>
<div class="self-end flex-grow-0 w-full text-center">
<button
class="inline-flex items-center justify-center w-48 px-4 py-2 transition-transform transform bg-blue-600 rounded-md shadow-lg outline-none text-gray-50 focus:ring-4 active:scale-y-75"
>
Compare
</button>
<form class="flex flex-col w-full gap-4" @submit="checkForm">
<section class="flex w-full gap-4">
<div class="flex flex-col flex-wrap w-1/2 gap-4">
<label for="lhsLabel" class="relative">
<input
id="lhsLabel"
name="lhsLabel"
type="text"
class="flex-1 flex-grow-0 w-full bg-transparent rounded-md material-input"
placeholder="Add label to this text block"
/>
</label>
<textarea
id="lhs"
rows="28"
name="lhs"
class="flex-1 w-full bg-transparent rounded-md resize-none form-textarea"
></textarea>
</div>
<div class="flex flex-col flex-wrap w-1/2 gap-4">
<input
id="rhsLabel"
name="rhsLabel"
type="text"
class="flex-1 flex-grow-0 w-full bg-transparent rounded-md material-input"
placeholder="Add label to this text block"
/>
<textarea
id="rhs"
rows="28"
name="rhs"
class="flex-1 w-full bg-transparent rounded-md resize-none form-textarea"
></textarea>
</div>
</section>
<div class="self-end flex-grow-0 w-full text-center">
<button
class="inline-flex items-center justify-center w-48 px-4 py-2 transition-transform transform bg-blue-600 rounded-md shadow-lg outline-none text-gray-50 focus:ring-4 active:scale-y-75"
>
Compare
</button>
</div>
</form>
</main>
Expand All @@ -49,14 +71,12 @@ export default Vue.extend({
methods: {
checkForm(e: Event) {
e.preventDefault()
const lhsTextArea: HTMLTextAreaElement = document.getElementById(
'lhs'
) as HTMLTextAreaElement
const lhs: string = lhsTextArea?.value || ''
const rhsTextArea: HTMLTextAreaElement = document.getElementById(
'rhs'
) as HTMLTextAreaElement
const rhs: string = rhsTextArea?.value || ''
const formData = new FormData(e.currentTarget as HTMLFormElement)
// const formDataJson = Object.fromEntries(formData.entries())
const lhs = formData.get('lhs')
const rhs = formData.get('rhs')
const lhsLabel = formData.get('lhsLabel')
const rhsLabel = formData.get('rhsLabel')
if (!lhs || !rhs) {
this.$store.commit('toast/show', {
show: true,
Expand Down Expand Up @@ -84,11 +104,17 @@ export default Vue.extend({
const originalLhs = lhs
const originalRhs = rhs
const diff = dmp.diff_main(originalLhs, originalRhs)
const gzip = Buffer.from(pako.gzip(JSON.stringify(diff))).toString(
'base64'
)
const gzip = Buffer.from(
pako.gzip(
JSON.stringify({
diff,
lhsLabel,
rhsLabel,
})
)
).toString('base64')
this.$router.push({
path: '/diff',
path: '/v1/diff',
hash: `#${doUrlSafeBase64(gzip)}`,
})
},
Expand Down
248 changes: 248 additions & 0 deletions pages/v1/diff.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
<template>
<div class="page-contents">
<Navbar :show-back-button="true">
<template #right>
<button
type="button"
class="inline-flex justify-center px-4 py-2 transition-transform transform rounded-md shadow outline-none copy-uri-button align-center focus:ring-4 active:scale-y-75"
:class="{
'bg-blue-500 text-white': !copied,
'bg-green-500 text-gray-800': copied,
}"
@click="copyUrlToClipboard"
>
<span v-show="copied" class="inline-flex justify-center">
<svg
class="inline-block w-6 h-6 ml-[-4px]"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
></path>
</svg>
<span class="hidden ml-2 md:inline-block">Copied</span>
</span>
<span v-show="!copied" class="inline-flex justify-center">
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
></path>
</svg>
<span class="hidden ml-2 md:inline-block">Copy link</span>
</span>
</button>
</template>
</Navbar>
<main>
<section
class="flex items-stretch w-full gap-4 font-mono text-gray-800 dark:text-gray-50"
>
<div class="flex flex-col w-1/2 gap-2">
<p class="flex-grow-0 text-lg">{{ lhsLabel }}</p>
<div
class="relative flex-1 px-4 py-2 overflow-y-auto border-2 rounded-md dark:border-gray-500 max-h-screen--nav line-number-gutter min-h-80"
>
<RTStickyCopyButton :click-handler="copyTextToClipboard" />
<div
v-for="(lineDiff, index) in lhsDiff"
:key="index"
:class="{
'bg-red-100 dark:bg-yellow-700':
lineDiff.includes('isModified'),
}"
>
<p class="break-all whitespace-pre-wrap" v-html="lineDiff"></p>
</div>
</div>
</div>

<div class="flex flex-col w-1/2 gap-2">
<p class="flex-grow-0 text-lg">{{ rhsLabel }}</p>
<div
class="relative flex-1 px-4 py-2 overflow-y-auto border-2 rounded-md dark:border-gray-500 min-h-80 line-number-gutter max-h-screen--nav"
>
<RTStickyCopyButton :click-handler="copyTextToClipboard" />
<div
v-for="(lineDiff, index) in rhsDiff"
:key="index"
:class="{
'bg-green-100 dark:bg-green-700':
lineDiff.includes('isModified'),
}"
>
<p class="break-all whitespace-pre-wrap" v-html="lineDiff"></p>
</div>
</div>
</div>
</section>
</main>
<Footer />
</div>
</template>

<script>
import pako from 'pako'
import { undoUrlSafeBase64, escapeHtml } from '../../helpers/utils'
import footer from '~/components/footer.vue'
export default {
components: { footer },
layout: 'main',
data() {
return {
lhsDiff: this.lhsDiff,
rhsDiff: this.rhsDiff,
rhsLabel: this.rhsLabel,
lhsLabel: this.lhsLabel,
copied: false,
}
},
mounted() {
const _diff = this.$route.hash
const gunzip = pako.ungzip(Buffer.from(undoUrlSafeBase64(_diff), 'base64'))
const diffData = JSON.parse(Buffer.from(gunzip).toString('utf8'))
const { diff, lhsLabel, rhsLabel } = diffData
this.lhsLabel = lhsLabel
this.rhsLabel = rhsLabel
this.lhsDiff = diff
.map((item) => {
const hunkState = item[0]
if (hunkState === -1 || hunkState === 0) {
const className =
hunkState === -1 ? 'isModified bg-red-300 dark:bg-yellow-900' : ''
return `<span class="break-all inline p-0 m-0 ${className}">${escapeHtml(
item[1]
)}</span>`
}
return false
})
.filter(Boolean)
.join('')
.split('\n')
this.rhsDiff = diff
.map((item) => {
const hunkState = item[0]
if (hunkState === 1 || hunkState === 0) {
const className =
hunkState === 1 ? 'isModified bg-green-300 dark:bg-green-900' : ''
return `<span class="break-all inline p-0 m-0 ${className}">${escapeHtml(
item[1]
)}</span>`
}
return false
})
.filter(Boolean)
.join('')
.split('\n')
const maxLineCount =
this.lhsDiff.length > this.rhsDiff.length
? this.lhsDiff.length
: this.rhsDiff.length
document.documentElement.style.setProperty(
'--max-line-number-characher',
`${`${maxLineCount}`.split('').length}ch`
)
},
methods: {
putToClipboard(textToPut, toastContent) {
navigator.clipboard.writeText(textToPut)
this.$store.commit('toast/show', {
show: true,
content: toastContent,
iconHTML: `
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
></path>
</svg>
`,
theme: 'success',
})
},
copyUrlToClipboard() {
this.putToClipboard(window.location.href, 'Link copied to your clipboard')
this.copied = true
setTimeout(() => {
this.copied = false
}, 5000)
},
copyTextToClipboard(e) {
this.putToClipboard(
e.currentTarget.parentNode.parentNode.innerText
.split('\n\n')
.join('\n'),
'Text copied to your clipboard'
)
},
},
}
</script>

<style lang="scss">
.copy-uri-button:hover {
@apply shadow-lg;
svg {
@apply scale-110 rotate-12;
}
}
/* line numbers in diff view */
.line-number-gutter {
counter-reset: line-numbers;
--line-number-gutter-width: calc(var(--max-line-number-characher) + 10px);
&::before {
content: '';
width: var(--line-number-gutter-width);
@apply bg-gray-200 dark:bg-gray-700 inline-block left-0 top-0 bottom-0 absolute text-sm;
}
@apply relative;
p {
padding-left: calc(var(--line-number-gutter-width) - 10px);
line-height: 1.65;
@apply relative;
&:hover {
@apply bg-gray-200 dark:bg-gray-700;
}
&::before {
counter-increment: line-numbers;
content: counter(line-numbers);
width: var(--line-number-gutter-width);
@apply absolute left-0 top-0 -mx-4 bottom-0 text-center bg-gray-200 dark:bg-gray-700 dark:text-gray-50 text-gray-500 flex justify-center text-sm;
}
&:first-of-type {
&::before {
@apply -mt-2 pt-2;
}
}
&:last-of-type {
&::before {
@apply -mb-2 pb-2;
}
}
}
}
</style>

0 comments on commit fc86793

Please sign in to comment.