feat: share and support modals
This commit is contained in:
1
assets/icons/email.svg
Normal file
1
assets/icons/email.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" ><path fill="currentColor" d="M12 .02c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zM18.99 7L12 12.666 5.009 7H18.99zM19 17H5V8.495l7 5.673 7-5.672V17z"/></svg>
|
||||
|
After Width: | Height: | Size: 224 B |
1
assets/icons/facebook.svg
Normal file
1
assets/icons/facebook.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" ><path fill="currentColor" d="M22.675 0H1.325C.593 0 0 .593 0 1.325v21.351C0 23.407.593 24 1.325 24H12.82v-9.294H9.692v-3.622h3.128V8.413c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.795.143v3.24l-1.918.001c-1.504 0-1.795.715-1.795 1.763v2.313h3.587l-.467 3.622h-3.12V24h6.116c.73 0 1.323-.593 1.323-1.325V1.325C24 .593 23.407 0 22.675 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 393 B |
1
assets/icons/linkedin.svg
Normal file
1
assets/icons/linkedin.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" ><path fill="currentColor" d="M19 0H5a5 5 0 00-5 5v14a5 5 0 005 5h14a5 5 0 005-5V5a5 5 0 00-5-5zM8 19H5V8h3v11zM6.5 6.732c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zM20 19h-3v-5.604c0-3.368-4-3.113-4 0V19h-3V8h3v1.765c1.396-2.586 7-2.777 7 2.476V19z"/></svg>
|
||||
|
After Width: | Height: | Size: 347 B |
1
assets/icons/reddit.svg
Normal file
1
assets/icons/reddit.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="currentColor" d="M24 11.779a2.654 2.654 0 00-4.497-1.899c-1.81-1.191-4.259-1.949-6.971-2.046l1.483-4.669 4.016.941-.006.058a2.17 2.17 0 002.174 2.163c1.198 0 2.172-.97 2.172-2.163a2.171 2.171 0 00-4.193-.785l-4.329-1.015a.37.37 0 00-.44.249L11.755 7.82c-2.838.034-5.409.798-7.3 2.025a2.643 2.643 0 00-1.799-.712A2.654 2.654 0 000 11.779c0 .97.533 1.811 1.317 2.271a4.716 4.716 0 00-.086.857C1.231 18.818 6.039 22 11.95 22s10.72-3.182 10.72-7.093c0-.274-.029-.544-.075-.81A2.633 2.633 0 0024 11.779zM6.776 13.595c0-.868.71-1.575 1.582-1.575.872 0 1.581.707 1.581 1.575s-.709 1.574-1.581 1.574-1.582-.706-1.582-1.574zm9.061 4.669c-.797.793-2.048 1.179-3.824 1.179L12 19.44l-.013.003c-1.777 0-3.028-.386-3.824-1.179a.369.369 0 010-.523.372.372 0 01.526 0c.65.647 1.729.961 3.298.961l.013.003.013-.003c1.569 0 2.648-.315 3.298-.962a.373.373 0 01.526 0 .37.37 0 010 .524zm-.189-3.095a1.58 1.58 0 01-1.581-1.574c0-.868.709-1.575 1.581-1.575s1.581.707 1.581 1.575-.709 1.574-1.581 1.574z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1 +1 @@
|
||||
<svg clip-rule="evenodd" fill-rule="evenodd" height="1684" stroke-linejoin="round" stroke-miterlimit="2" viewBox="-89.00934757 -46.8841404 643.93723344 446.8841404" width="2500" xmlns="http://www.w3.org/2000/svg"><path d="m154.729 400c185.669 0 287.205-153.876 287.205-287.312 0-4.37-.089-8.72-.286-13.052a205.304 205.304 0 0 0 50.352-52.29c-18.087 8.044-37.55 13.458-57.968 15.899 20.841-12.501 36.84-32.278 44.389-55.852a202.42 202.42 0 0 1 -64.098 24.511c-18.42-19.628-44.644-31.904-73.682-31.904-55.744 0-100.948 45.222-100.948 100.965 0 7.925.887 15.631 2.619 23.025-83.895-4.223-158.287-44.405-208.074-105.504a100.739 100.739 0 0 0 -13.668 50.754c0 35.034 17.82 65.961 44.92 84.055a100.172 100.172 0 0 1 -45.716-12.63c-.015.424-.015.837-.015 1.29 0 48.903 34.794 89.734 80.982 98.986a101.036 101.036 0 0 1 -26.617 3.553c-6.493 0-12.821-.639-18.971-1.82 12.851 40.122 50.115 69.319 94.296 70.135-34.549 27.089-78.07 43.224-125.371 43.224a204.9 204.9 0 0 1 -24.078-1.399c44.674 28.645 97.72 45.359 154.734 45.359" fill="#1da1f2" fill-rule="nonzero"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 628 B |
@@ -111,16 +111,14 @@ a {
|
||||
@apply py-1 px-2;
|
||||
@apply shadow;
|
||||
|
||||
font-size: var(--body-font-size);
|
||||
font-size: 88%;
|
||||
line-height: var(--body-line-height);
|
||||
|
||||
kbd {
|
||||
@apply first:ml-2;
|
||||
@apply last:-mr-1;
|
||||
@apply font-sans;
|
||||
@apply bg-secondaryDark;
|
||||
@apply text-primaryDark;
|
||||
@apply rounded;
|
||||
@apply rounded-sm;
|
||||
@apply px-1;
|
||||
@apply ml-1;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,13 @@
|
||||
blank
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
:label="$t('app.chat_with_us')"
|
||||
@click.native="
|
||||
chatWithUs()
|
||||
$refs.options.tippy().hide()
|
||||
"
|
||||
/>
|
||||
<hr />
|
||||
<SmartItem
|
||||
:label="$t('app.twitter')"
|
||||
@@ -109,6 +116,7 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "@nuxtjs/composition-api"
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
import { showChat } from "~/helpers/support"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
|
||||
export default defineComponent({
|
||||
@@ -149,6 +157,9 @@ export default defineComponent({
|
||||
// fallback
|
||||
}
|
||||
},
|
||||
chatWithUs() {
|
||||
showChat()
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
123
components/app/Share.vue
Normal file
123
components/app/Share.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<SmartModal
|
||||
v-if="show"
|
||||
:title="$t('app.invite_your_friends')"
|
||||
@close="$emit('hide-modal')"
|
||||
>
|
||||
<template #body>
|
||||
<p class="text-secondaryLight mb-8 px-2">
|
||||
{{ $t("app.invite_description") }}
|
||||
</p>
|
||||
<div class="flex flex-col space-y-2 px-2">
|
||||
<div class="grid gap-4 grid-cols-3">
|
||||
<a
|
||||
v-for="(platform, index) in platforms"
|
||||
:key="`platform-${index}`"
|
||||
:href="platform.link"
|
||||
target="_blank"
|
||||
class="share-link"
|
||||
>
|
||||
<SmartIcon :name="platform.icon" class="h-6 w-6" />
|
||||
<span class="mt-3">
|
||||
{{ platform.name }}
|
||||
</span>
|
||||
</a>
|
||||
<button class="share-link" @click="copyAppLink">
|
||||
<span class="font-icon h-6 text-xl w-6">{{ copyIcon }}</span>
|
||||
<span class="font-medium mt-3">
|
||||
{{ $t("app.copy") }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
data() {
|
||||
const url = "https://hoppscotch.io"
|
||||
const text = "Hoppscotch - Open source API development ecosystem."
|
||||
const description =
|
||||
"Helps you create requests faster, saving precious time on development."
|
||||
const subject =
|
||||
"Checkout Hoppscotch - an open source API development ecosystem"
|
||||
const summary = `Hi there!%0D%0A%0D%0AI thought you’ll like this new platform that I joined called Hoppscotch - https://hoppscotch.io.%0D%0AIt is a simple and intuitive interface for creating and managing your APIs. You can build, test, document, and share your APIs.%0D%0A%0D%0AThe best part about Hoppscotch is that it is open source and free to get started.%0D%0A%0D%0A`
|
||||
const twitter = "hoppscotch_io"
|
||||
|
||||
return {
|
||||
url: "https://hoppscotch.io",
|
||||
copyIcon: "content_copy",
|
||||
platforms: [
|
||||
{
|
||||
name: "Email",
|
||||
icon: "email",
|
||||
link: `mailto:?subject=${subject}&body=${summary}`,
|
||||
},
|
||||
{
|
||||
name: "Twitter",
|
||||
icon: "twitter",
|
||||
link: `https://twitter.com/intent/tweet?text=${text} ${description}&url=${url}&via=${twitter}`,
|
||||
},
|
||||
{
|
||||
name: "Facebook",
|
||||
icon: "facebook",
|
||||
link: `https://www.facebook.com/sharer/sharer.php?u=${url}`,
|
||||
},
|
||||
{
|
||||
name: "Reddit",
|
||||
icon: "reddit",
|
||||
link: `https://www.reddit.com/submit?url=${url}&title=${text}`,
|
||||
},
|
||||
{
|
||||
name: "LinkedIn",
|
||||
icon: "linkedin",
|
||||
link: `https://www.linkedin.com/sharing/share-offsite/?url=${url}`,
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyAppLink() {
|
||||
copyToClipboard(this.url)
|
||||
this.copyIcon = "done"
|
||||
this.$toast.success(this.$t("copied_to_clipboard").toString(), {
|
||||
icon: "done",
|
||||
})
|
||||
setTimeout(() => (this.copyIcon = "content_copy"), 1000)
|
||||
},
|
||||
hideModal() {
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.share-link {
|
||||
@apply border border-dividerLight;
|
||||
@apply rounded;
|
||||
@apply flex-col flex;
|
||||
@apply p-4;
|
||||
@apply transition;
|
||||
@apply items-center;
|
||||
@apply justify-center;
|
||||
@apply hover:(bg-primaryLight text-secondaryDark);
|
||||
@apply focus:(border-divider outline-none);
|
||||
|
||||
svg {
|
||||
@apply opacity-80;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
@apply opacity-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -86,7 +86,19 @@ export default {
|
||||
shortcuts: [
|
||||
{
|
||||
keys: ["?"],
|
||||
label: this.$t("shortcut.show_all"),
|
||||
label: this.$t("shortcut.general.help_menu"),
|
||||
},
|
||||
{
|
||||
keys: ["/"],
|
||||
label: this.$t("shortcut.general.show_all"),
|
||||
},
|
||||
{
|
||||
keys: [getPlatformSpecialKey(), "K"],
|
||||
label: this.$t("shortcut.general.command_menu"),
|
||||
},
|
||||
{
|
||||
keys: ["Esc"],
|
||||
label: this.$t("shortcut.general.close_current_menu"),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<aside>
|
||||
<aside class="flex h-full justify-between md:flex-col">
|
||||
<nav class="flex flex-nowrap md:flex-col">
|
||||
<nuxt-link
|
||||
<NuxtLink
|
||||
v-for="(navigation, index) in primaryNavigation"
|
||||
:key="`navigation-${index}`"
|
||||
:to="localePath(navigation.target)"
|
||||
@@ -14,13 +14,58 @@
|
||||
<SmartIcon :name="navigation.svg" class="svg-icons" />
|
||||
</div>
|
||||
<span>{{ navigation.title }}</span>
|
||||
</nuxt-link>
|
||||
</NuxtLink>
|
||||
</nav>
|
||||
<nav
|
||||
class="
|
||||
flex flex-nowrap
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
md:(flex-col
|
||||
space-x-0 space-y-2)
|
||||
"
|
||||
>
|
||||
<TabPrimary
|
||||
v-tippy="{ theme: 'tooltip', placement: 'top' }"
|
||||
:title="$t('app.invite')"
|
||||
icon="person_add_alt"
|
||||
@click.native="showShare = true"
|
||||
/>
|
||||
<TabPrimary
|
||||
v-tippy="{ theme: 'tooltip', placement: 'top' }"
|
||||
:title="`${$t('support.title')} <kbd>?</kbd>`"
|
||||
icon="support"
|
||||
@click.native="showSupport = true"
|
||||
/>
|
||||
</nav>
|
||||
<AppSupport :show="showSupport" @hide-modal="showSupport = false" />
|
||||
<AppShare :show="showShare" @hide-modal="showShare = false" />
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "@nuxtjs/composition-api"
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const showSupport = ref(false)
|
||||
const showShare = ref(false)
|
||||
|
||||
defineActionHandler("modals.support.toggle", () => {
|
||||
showSupport.value = !showSupport.value
|
||||
})
|
||||
|
||||
defineActionHandler("modals.share.toggle", () => {
|
||||
showShare.value = !showShare.value
|
||||
})
|
||||
|
||||
return {
|
||||
showSupport,
|
||||
showShare,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
primaryNavigation: [
|
||||
@@ -52,7 +97,7 @@ export default {
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
86
components/app/Support.vue
Normal file
86
components/app/Support.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<SmartModal
|
||||
v-if="show"
|
||||
:title="$t('support.title')"
|
||||
@close="$emit('hide-modal')"
|
||||
>
|
||||
<template #body>
|
||||
<div class="flex flex-col space-y-2 px-2">
|
||||
<SmartItem
|
||||
icon="menu_book"
|
||||
:label="$t('app.documentation')"
|
||||
to="https://github.com/hoppscotch/hoppscotch/wiki"
|
||||
:description="$t('support.documentation')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
blank
|
||||
@click.native="hideModal()"
|
||||
/>
|
||||
<SmartItem
|
||||
icon="keyboard"
|
||||
:label="$t('app.keyboard_shortcuts')"
|
||||
:description="$t('support.shortcuts')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="
|
||||
showShortcuts()
|
||||
hideModal()
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
icon="auto_awesome"
|
||||
:label="$t('app.whats_new')"
|
||||
to="https://github.com/hoppscotch/hoppscotch/blob/main/CHANGELOG.md"
|
||||
:description="$t('support.changelog')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
blank
|
||||
@click.native="hideModal()"
|
||||
/>
|
||||
<SmartItem
|
||||
icon="contact_support"
|
||||
:label="$t('app.chat_with_us')"
|
||||
:description="$t('support.chat')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="
|
||||
chatWithUs()
|
||||
hideModal()
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="twitter"
|
||||
:label="$t('app.twitter')"
|
||||
to="https://twitter.com/hoppscotch_io"
|
||||
blank
|
||||
:description="$t('support.twitter')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="hideModal()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { invokeAction } from "~/helpers/actions"
|
||||
import { showChat } from "~/helpers/support"
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
methods: {
|
||||
chatWithUs() {
|
||||
showChat()
|
||||
},
|
||||
showShortcuts() {
|
||||
invokeAction("flyouts.keybinds.toggle")
|
||||
},
|
||||
hideModal() {
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -20,6 +20,7 @@
|
||||
:key="`contentTypeItem-${index}`"
|
||||
:label="contentTypeItem"
|
||||
:info-icon="contentTypeItem === contentType ? 'done' : ''"
|
||||
:active-info-icon="contentTypeItem === contentType"
|
||||
@click.native="
|
||||
contentType = contentTypeItem
|
||||
$refs.contentTypeOptions.tippy().hide()
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
:key="`gen-${index}`"
|
||||
:label="gen.name"
|
||||
:info-icon="gen.id === codegenType ? 'done' : ''"
|
||||
:active-info-icon="gen.id === codegenType"
|
||||
@click.native="
|
||||
codegenType = gen.id
|
||||
$refs.options.tippy().hide()
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
id="send"
|
||||
class="rounded-none min-w-20"
|
||||
:label="!loading ? $t('send') : $t('cancel')"
|
||||
:shortcut="[getSpecialKey(), 'G']"
|
||||
@click.native="!loading ? newSendRequest() : cancelRequest()"
|
||||
/>
|
||||
<span class="inline-flex">
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{{ $t("shortcut.reset_request") }}
|
||||
</span>
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.show_all") }}
|
||||
{{ $t("shortcut.general.show_all") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
}`"
|
||||
/>
|
||||
</template>
|
||||
<nuxt-link
|
||||
<NuxtLink
|
||||
v-for="(locale, index) in $i18n.locales.filter(
|
||||
({ code }) => code !== $i18n.locale
|
||||
)"
|
||||
@@ -23,7 +23,7 @@
|
||||
@click="$refs.language.tippy().hide()"
|
||||
>
|
||||
<SmartItem :label="locale.name" />
|
||||
</nuxt-link>
|
||||
</NuxtLink>
|
||||
</tippy>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
:key="`size-${index}`"
|
||||
:label="size.name"
|
||||
:info-icon="size.code === active.code ? 'done' : ''"
|
||||
:active-info-icon="size.code === active.code"
|
||||
@click.native="
|
||||
setActiveFont(size)
|
||||
$refs.fontSize.tippy().hide()
|
||||
|
||||
@@ -30,10 +30,17 @@
|
||||
:disabled="disabled"
|
||||
:tabindex="loading ? '-1' : '0'"
|
||||
>
|
||||
<span v-if="!loading" class="inline-flex items-center">
|
||||
<span
|
||||
v-if="!loading"
|
||||
class="inline-flex items-center"
|
||||
:class="{ 'self-start': infoIcon }"
|
||||
>
|
||||
<i
|
||||
v-if="icon"
|
||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||
:class="[
|
||||
label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : '',
|
||||
{ 'text-accent': active },
|
||||
]"
|
||||
class="material-icons"
|
||||
>
|
||||
{{ icon }}
|
||||
@@ -41,7 +48,10 @@
|
||||
<SmartIcon
|
||||
v-if="svg"
|
||||
:name="svg"
|
||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||
:class="[
|
||||
label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : '',
|
||||
{ 'text-accent': active },
|
||||
]"
|
||||
class="svg-icons"
|
||||
/>
|
||||
</span>
|
||||
@@ -57,7 +67,11 @@
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<i v-if="infoIcon" class="text-accent ml-6 self-end material-icons">
|
||||
<i
|
||||
v-if="infoIcon"
|
||||
class="ml-6 self-center material-icons items-center"
|
||||
:class="{ 'text-accent': activeInfoIcon }"
|
||||
>
|
||||
{{ infoIcon }}
|
||||
</i>
|
||||
</SmartLink>
|
||||
@@ -110,6 +124,14 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
activeInfoIcon: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
infoIcon: {
|
||||
type: String,
|
||||
default: "",
|
||||
|
||||
@@ -162,6 +162,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
onTransitionLeaveStart() {
|
||||
this.close()
|
||||
this.shouldCleanupDomOnUnmount = false
|
||||
},
|
||||
$getPortal() {
|
||||
|
||||
@@ -17,6 +17,8 @@ export type HoppAction =
|
||||
| "request.method.put" // Select PUT Method
|
||||
| "request.method.delete" // Select DELETE Method
|
||||
| "flyouts.keybinds.toggle" // Shows the keybinds flyout
|
||||
| "modals.support.toggle" // Shows the support modal
|
||||
| "modals.share.toggle" // Shows the share modal
|
||||
|
||||
type BoundActionList = {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
@@ -17,10 +17,49 @@ let keybindingsEnabled = true
|
||||
type ModifierKeys = "ctrl" | "alt"
|
||||
|
||||
/* eslint-disable prettier/prettier */
|
||||
type Key = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k'
|
||||
| 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x'
|
||||
| 'y' | 'z' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
|
||||
| "up" | "down" | "left" | "right" | "?"
|
||||
type Key =
|
||||
| "a"
|
||||
| "b"
|
||||
| "c"
|
||||
| "d"
|
||||
| "e"
|
||||
| "f"
|
||||
| "g"
|
||||
| "h"
|
||||
| "i"
|
||||
| "j"
|
||||
| "k"
|
||||
| "l"
|
||||
| "m"
|
||||
| "n"
|
||||
| "o"
|
||||
| "p"
|
||||
| "q"
|
||||
| "r"
|
||||
| "s"
|
||||
| "t"
|
||||
| "u"
|
||||
| "v"
|
||||
| "w"
|
||||
| "x"
|
||||
| "y"
|
||||
| "z"
|
||||
| "0"
|
||||
| "1"
|
||||
| "2"
|
||||
| "3"
|
||||
| "4"
|
||||
| "5"
|
||||
| "6"
|
||||
| "7"
|
||||
| "8"
|
||||
| "9"
|
||||
| "up"
|
||||
| "down"
|
||||
| "left"
|
||||
| "right"
|
||||
| "/"
|
||||
| "?"
|
||||
/* eslint-enable */
|
||||
|
||||
type ModifierBasedShortcutKey = `${ModifierKeys}-${Key}`
|
||||
@@ -44,7 +83,9 @@ export const bindings: {
|
||||
"alt-p": "request.method.post",
|
||||
"alt-u": "request.method.put",
|
||||
"alt-x": "request.method.delete",
|
||||
"?": "flyouts.keybinds.toggle",
|
||||
"/": "flyouts.keybinds.toggle",
|
||||
"?": "modals.support.toggle",
|
||||
"ctrl-x": "modals.share.toggle",
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,6 +156,9 @@ function getPressedKey(ev: KeyboardEvent): Key | null {
|
||||
// Check if question mark
|
||||
if (val === "?") return "?"
|
||||
|
||||
// Check if question mark
|
||||
if (val === "/") return "/"
|
||||
|
||||
// If no other cases match, this is not a valid key
|
||||
return null
|
||||
}
|
||||
|
||||
4
helpers/support.js
Normal file
4
helpers/support.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export const showChat = () => {
|
||||
$crisp.push(["do", "chat:show"])
|
||||
$crisp.push(["do", "chat:open"])
|
||||
}
|
||||
@@ -64,17 +64,33 @@
|
||||
"more": "Hide more",
|
||||
"preview": "Hide Preview"
|
||||
},
|
||||
"support": {
|
||||
"title": "Support",
|
||||
"documentation": "Read more about Hoppscotch",
|
||||
"changelog": "Read more about latest releases",
|
||||
"twitter": "Follow us on Twitter",
|
||||
"chat": "Questions? Chat with us!",
|
||||
"forum": "Ask questions and get answers",
|
||||
"team": "Get in touch with the team",
|
||||
"shortcuts": "Become more efficient"
|
||||
},
|
||||
"app": {
|
||||
"name": "Hoppscotch",
|
||||
"version": "v2.0",
|
||||
"documentation": "Documentation",
|
||||
"whats_new": "What's new?",
|
||||
"chat_with_us": "Chat with us",
|
||||
"keyboard_shortcuts": "Keyboard shortcuts",
|
||||
"new_version_found": "New version found. Refresh to update.",
|
||||
"twitter": "Twitter",
|
||||
"terms_and_privacy": "Terms and privacy",
|
||||
"status": "Status",
|
||||
"help": "Help, feedback and</br>documentation"
|
||||
"help": "Help, feedback and</br>documentation",
|
||||
"invite": "Invite",
|
||||
"invite_your_friends": "Invite your friends",
|
||||
"invite_description": "In Hoppscotch, we designed a simple and intuitive interface for creating and managing your APIs. Hoppscotch is a tool that helps you build, test, document and share your APIs.",
|
||||
"share": "Share",
|
||||
"copy": "Copy"
|
||||
},
|
||||
"collection": {
|
||||
"save_as": "Save as",
|
||||
@@ -189,7 +205,12 @@
|
||||
"results": "Results"
|
||||
},
|
||||
"shortcut": {
|
||||
"show_all": "Show all Shortcuts",
|
||||
"general": {
|
||||
"help_menu": "Help menu",
|
||||
"show_all": "Keyboard shortcuts",
|
||||
"command_menu": "Command menu",
|
||||
"close_current_menu": "Close current menu"
|
||||
},
|
||||
"send_request": "Send Request",
|
||||
"save_to_collections": "Save to Collections",
|
||||
"copy_request_link": "Copy Request Link",
|
||||
|
||||
@@ -98,6 +98,7 @@ export default {
|
||||
"~/plugins/vuex-persist",
|
||||
"~/plugins/vue-rx",
|
||||
"~/plugins/vue-apollo",
|
||||
"~/plugins/crisp",
|
||||
{ src: "~/plugins/web-worker", ssr: false },
|
||||
],
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@
|
||||
{{ $t("shortcut.reset_request") }}
|
||||
</span>
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.show_all") }}
|
||||
{{ $t("shortcut.general.show_all") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4">
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
svg="firefox"
|
||||
label="Firefox"
|
||||
:info-icon="hasFirefoxExtInstalled ? 'check_circle' : ''"
|
||||
:active-info-icon="hasFirefoxExtInstalled"
|
||||
outline
|
||||
/>
|
||||
</span>
|
||||
@@ -252,6 +253,7 @@
|
||||
svg="chrome"
|
||||
label="Chrome"
|
||||
:info-icon="hasChromeExtInstalled ? 'check_circle' : ''"
|
||||
:active-info-icon="hasChromeExtInstalled"
|
||||
outline
|
||||
/>
|
||||
</span>
|
||||
|
||||
18
plugins/crisp.js
Normal file
18
plugins/crisp.js
Normal file
@@ -0,0 +1,18 @@
|
||||
export default () => {
|
||||
window.$crisp = []
|
||||
window.CRISP_WEBSITE_ID = "3ad30257-c192-4773-955d-fb05a4b41af3"
|
||||
const d = document
|
||||
const s = d.createElement("script")
|
||||
|
||||
s.src = "https://client.crisp.chat/l.js"
|
||||
s.async = 1
|
||||
d.getElementsByTagName("head")[0].appendChild(s)
|
||||
$crisp.push(["do", "chat:hide"])
|
||||
$crisp.push([
|
||||
"on",
|
||||
"chat:closed",
|
||||
() => {
|
||||
$crisp.push(["do", "chat:hide"])
|
||||
},
|
||||
])
|
||||
}
|
||||
Reference in New Issue
Block a user