refactor: settings page + ui components
This commit is contained in:
@@ -63,7 +63,7 @@ body {
|
||||
.page-leave-active,
|
||||
.layout-enter-active,
|
||||
.layout-leave-active {
|
||||
@apply transition-opacity;
|
||||
@apply transition;
|
||||
}
|
||||
|
||||
.page-enter,
|
||||
@@ -96,7 +96,6 @@ a {
|
||||
&.link {
|
||||
@apply items-center;
|
||||
@apply text-accent;
|
||||
|
||||
@apply hover:text-accent;
|
||||
@apply focus:text-accent;
|
||||
}
|
||||
@@ -153,22 +152,17 @@ button {
|
||||
@apply items-stretch;
|
||||
}
|
||||
|
||||
hr {
|
||||
@apply border-b;
|
||||
@apply border-divider;
|
||||
}
|
||||
|
||||
.heading {
|
||||
@apply font-bold;
|
||||
@apply text-secondaryDark;
|
||||
@apply text-lg;
|
||||
}
|
||||
|
||||
.info:not(.toasted) {
|
||||
@apply m-4;
|
||||
@apply text-secondaryLight;
|
||||
|
||||
.material-icons {
|
||||
@apply align-middle;
|
||||
@apply mr-2;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
@apply truncate;
|
||||
}
|
||||
|
||||
@@ -7,30 +7,28 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<p class="info">
|
||||
{{ $t("extensions_info1") }}
|
||||
</p>
|
||||
<div class="px-2">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
<div class="flex flex-col px-2 space-y-2">
|
||||
<SmartItem
|
||||
to="https://addons.mozilla.org/en-US/firefox/addon/hoppscotch"
|
||||
blank
|
||||
:title="{ hasFirefoxExtInstalled: $t('installed') }"
|
||||
svg="firefox"
|
||||
label="Firefox"
|
||||
:info-icon="hasFirefoxExtInstalled ? 'check_circle' : ''"
|
||||
/>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
<SmartItem
|
||||
to="https://chrome.google.com/webstore/detail/hoppscotch-browser-extens/amknoiejhlmhancpahfcfcfhllgkpbld"
|
||||
blank
|
||||
:title="{ hasChromeExtInstalled: $t('installed') }"
|
||||
svg="chrome"
|
||||
label="Chrome"
|
||||
:info-icon="hasChromeExtInstalled ? 'check_circle' : ''"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="px-2 text-secondaryLight text-xs">
|
||||
{{ $t("extensions_info1") }}
|
||||
</div>
|
||||
</template>
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
@click.native="showInstallPrompt()"
|
||||
/>
|
||||
<span tabindex="-1">
|
||||
<span v-if="currentUser === null">
|
||||
<ButtonSecondary label="Sign in" @click.native="showLogin = true" />
|
||||
<ButtonPrimary label="Sign up" @click.native="showLogin = true" />
|
||||
</span>
|
||||
<ButtonPrimary
|
||||
v-if="currentUser === null"
|
||||
label="Get Started"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
<tippy v-else tabindex="-1" trigger="click" theme="popover" arrow>
|
||||
<template #trigger>
|
||||
<ProfilePicture
|
||||
@@ -84,13 +85,12 @@
|
||||
</tippy>
|
||||
</span>
|
||||
</div>
|
||||
<AppLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||
<AppExtensions
|
||||
:show="showExtensions"
|
||||
@hide-modal="showExtensions = false"
|
||||
/>
|
||||
<AppShortcuts :show="showShortcuts" @hide-modal="showShortcuts = false" />
|
||||
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
||||
</header>
|
||||
</template>
|
||||
|
||||
@@ -110,7 +110,6 @@ export default {
|
||||
showLogin: false,
|
||||
showExtensions: false,
|
||||
showShortcuts: false,
|
||||
showEmail: false,
|
||||
navigatorShare: navigator.share,
|
||||
}
|
||||
},
|
||||
@@ -222,31 +221,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.logo {
|
||||
@apply text-xl;
|
||||
@apply transition-colors;
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
@apply hover:text-accent;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
0% {
|
||||
@apply opacity-0;
|
||||
@apply -left-4;
|
||||
}
|
||||
|
||||
100% {
|
||||
@apply opacity-100;
|
||||
@apply left-0;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-in {
|
||||
@apply relative;
|
||||
|
||||
animation: slideIn 0.2s forwards ease-in-out;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<template>
|
||||
<SmartModal v-if="show" @close="hideModal">
|
||||
<template #header>
|
||||
<h3 class="heading">{{ $t("login") }}</h3>
|
||||
<div>
|
||||
<ButtonSecondary icon="close" @click.native="hideModal" />
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<FirebaseLogin />
|
||||
</template>
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
methods: {
|
||||
hideModal() {
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -7,15 +7,15 @@
|
||||
:to="localePath(navigation.target)"
|
||||
class="
|
||||
p-4
|
||||
text-xs
|
||||
flex-col flex-1
|
||||
hover:bg-primaryLight
|
||||
hover:bg-primaryDark hover:text-secondaryDark
|
||||
items-center
|
||||
justify-center
|
||||
transition
|
||||
"
|
||||
>
|
||||
<i class="material-icons">{{ navigation.icon }}</i>
|
||||
<span class="mt-2">{{ navigation.title }}</span>
|
||||
<i class="material-icons opacity-75">{{ navigation.icon }}</i>
|
||||
<span class="mt-2 text-xs font-semibold">{{ navigation.title }}</span>
|
||||
</nuxt-link>
|
||||
</nav>
|
||||
</aside>
|
||||
@@ -36,67 +36,11 @@ export default {
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentNavigation() {
|
||||
return this.navigation.filter((item) =>
|
||||
this.$route.name.includes(item.primary)
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener("scroll", () => {
|
||||
const mainNavLinks = document.querySelectorAll("nav.secondary-nav a")
|
||||
const fromTop = window.scrollY
|
||||
mainNavLinks.forEach(({ hash, classList }) => {
|
||||
const section = document.querySelector(hash)
|
||||
if (
|
||||
section &&
|
||||
section.offsetTop <= fromTop &&
|
||||
section.offsetTop + section.offsetHeight > fromTop
|
||||
) {
|
||||
classList.add("current")
|
||||
} else {
|
||||
classList.remove("current")
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
nav.secondary-nav {
|
||||
@apply flex flex-col flex-nowrap;
|
||||
@apply items-center;
|
||||
@apply justify-center;
|
||||
@apply border-t-2 border-dashed border-divider;
|
||||
@apply pt-2;
|
||||
@apply space-y-2;
|
||||
|
||||
a {
|
||||
@apply inline-flex;
|
||||
@apply items-center;
|
||||
@apply justify-center;
|
||||
@apply flex-shrink-0;
|
||||
@apply p-4;
|
||||
@apply rounded-full;
|
||||
@apply bg-primaryDark;
|
||||
@apply text-secondaryLight;
|
||||
@apply fill-current;
|
||||
@apply outline-none;
|
||||
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
|
||||
&:hover {
|
||||
@apply text-secondary;
|
||||
@apply fill-current;
|
||||
}
|
||||
|
||||
&.current {
|
||||
@apply text-accent;
|
||||
@apply fill-current;
|
||||
}
|
||||
}
|
||||
.active {
|
||||
@apply text-accent;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
||||
:class="[{ 'bg-primaryDark': dragging }]"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
||||
:class="[{ 'bg-primaryDark': dragging }]"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
||||
:class="[{ 'bg-primaryDark': dragging }]"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
||||
:class="[{ 'bg-primaryDark': dragging }]"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
||||
:class="[{ 'bg-primaryDark': dragging }]"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
||||
:class="[{ 'bg-primaryDark': dragging }]"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="ease-in-out row-wrapper">
|
||||
<div>
|
||||
<ButtonSecondary @click.native="toggleShowChildren" />
|
||||
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||
>arrow_right</i
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="ease-in-out row-wrapper">
|
||||
<div>
|
||||
<div>
|
||||
<ButtonSecondary @click.native="toggleShowChildren" />
|
||||
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="ease-in-out row-wrapper">
|
||||
<div>
|
||||
<div>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
<template>
|
||||
<SmartModal v-if="show" @close="hideModal">
|
||||
<template #header>
|
||||
<h3 class="heading">{{ $t("login_with") }} {{ $t("email") }}</h3>
|
||||
<ButtonSecondary icon="close" @click.native="hideModal" />
|
||||
</template>
|
||||
<template v-if="mode === 'sign-in'" #body>
|
||||
<label for="email"> E-mail </label>
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
class="input"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="you@mail.com"
|
||||
autocomplete="email"
|
||||
required
|
||||
spellcheck="false"
|
||||
autofocus
|
||||
@keyup.enter="signInWithEmail"
|
||||
/>
|
||||
</template>
|
||||
<template v-else #body>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex justify-center max-w-md p-4 items-center flex-col">
|
||||
<i class="material-icons text-accent" style="font-size: 64px">
|
||||
verified
|
||||
</i>
|
||||
<h3 class="font-bold my-2 text-center text-lg">
|
||||
{{ $t("we_sent_magic_link") }}
|
||||
</h3>
|
||||
<p class="text-center">
|
||||
{{ $t("we_sent_magic_link_description", { email: form.email }) }}
|
||||
</p>
|
||||
<p class="info">{{ $t("check_your_inbox") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="mode === 'sign-in'" #footer>
|
||||
<span></span>
|
||||
<span>
|
||||
<ButtonSPrimary
|
||||
:loading="signingInWithEmail"
|
||||
class="rounded-md button"
|
||||
:disabled="
|
||||
form.email.length !== 0
|
||||
? emailRegex.test(form.email)
|
||||
? false
|
||||
: true
|
||||
: true
|
||||
"
|
||||
type="button"
|
||||
tabindex="-1"
|
||||
:label="$t('send_magic_link')"
|
||||
@click.native="signInWithEmail"
|
||||
/></span>
|
||||
</template>
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { currentUser$, signInWithEmail } from "~/helpers/fb/auth"
|
||||
import { setLocalConfig } from "~/newstore/localpersistence"
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
email: "",
|
||||
},
|
||||
signingInWithEmail: false,
|
||||
emailRegex:
|
||||
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
|
||||
mode: "sign-in",
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$subscribeTo(currentUser$, (user) => {
|
||||
if (user) this.hideModal()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
async signInWithEmail() {
|
||||
this.signingInWithEmail = true
|
||||
const actionCodeSettings = {
|
||||
url: `${process.env.BASE_URL}/enter`,
|
||||
handleCodeInApp: true,
|
||||
}
|
||||
await signInWithEmail(this.form.email, actionCodeSettings)
|
||||
.then(() => {
|
||||
this.mode = "email"
|
||||
setLocalConfig("emailForSignIn", this.form.email)
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$toast.error(error.message, {
|
||||
icon: "error",
|
||||
})
|
||||
this.signingInWithEmail = false
|
||||
})
|
||||
.finally(() => {
|
||||
this.signingInWithEmail = false
|
||||
})
|
||||
},
|
||||
hideModal() {
|
||||
this.mode = "sign-in"
|
||||
this.$toast.clear()
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,49 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2">
|
||||
<SmartItem
|
||||
svg="google"
|
||||
label="Continue with Google"
|
||||
@click.native="signInWithGoogle"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="github"
|
||||
label="Continue with GitHub"
|
||||
@click.native="signInWithGithub"
|
||||
/>
|
||||
<SmartItem
|
||||
icon="mail"
|
||||
label="Continue with Email"
|
||||
@click.native="mode = 'email'"
|
||||
/>
|
||||
</div>
|
||||
<p v-if="mode === 'sign-in'" class="mx-4 mt-8 text-secondaryLight text-xs">
|
||||
By signing in, you are agreeing to our
|
||||
<SmartAnchor class="link" to="/index" label="Terms of Service" />
|
||||
and
|
||||
<SmartAnchor class="link" to="/index" label="Privacy Policy" />.
|
||||
</p>
|
||||
<div v-if="mode === 'email'" class="flex items-center px-4">
|
||||
<label for="email"> Email </label>
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
class="flex flex-1 ml-4 rounded px-4 py-2 outline-none"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="you@mail.com"
|
||||
autocomplete="email"
|
||||
required
|
||||
spellcheck="false"
|
||||
autofocus
|
||||
@keyup.enter="signInWithEmail"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="mode === 'email'">
|
||||
<div class="flex flex-col">
|
||||
<SmartModal v-if="show" @close="hideModal">
|
||||
<template #header>
|
||||
<h3 class="heading">{{ $t("login_to_hoppscotch") }}</h3>
|
||||
<div>
|
||||
<ButtonSecondary icon="close" @click.native="hideModal" />
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2">
|
||||
<SmartItem
|
||||
:loading="signingInWithGoogle"
|
||||
svg="google"
|
||||
label="Continue with Google"
|
||||
@click.native="signInWithGoogle"
|
||||
/>
|
||||
<SmartItem
|
||||
:loading="signingInWithGitHub"
|
||||
svg="github"
|
||||
label="Continue with GitHub"
|
||||
@click.native="signInWithGithub"
|
||||
/>
|
||||
<SmartItem
|
||||
icon="mail"
|
||||
label="Continue with Email"
|
||||
@click.native="mode = 'email'"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="mode === 'email'" class="flex flex-col space-y-2">
|
||||
<div class="flex items-center">
|
||||
<label for="email" class="flex items-center px-4">
|
||||
<i class="material-icons opacity-75">mail</i>
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
class="flex flex-1 rounded px-4 py-2 outline-none"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="enter your email"
|
||||
autocomplete="email"
|
||||
required
|
||||
spellcheck="false"
|
||||
autofocus
|
||||
@keyup.enter="signInWithEmail"
|
||||
/>
|
||||
</div>
|
||||
<ButtonPrimary
|
||||
:loading="signingInWithEmail"
|
||||
class="mx-4 mt-4"
|
||||
:disabled="
|
||||
form.email.length !== 0
|
||||
? emailRegex.test(form.email)
|
||||
@@ -57,33 +60,45 @@
|
||||
@click.native="signInWithEmail"
|
||||
/>
|
||||
</div>
|
||||
<p class="mx-4 mt-8 text-secondaryLight text-xs">
|
||||
Back to
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
to="#"
|
||||
label="all sign in options"
|
||||
@click.native="mode = 'sign-in'"
|
||||
/>.
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="mode === 'email-sent'">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex justify-center max-w-md p-4 items-center flex-col">
|
||||
<i class="material-icons text-accent" style="font-size: 64px">
|
||||
verified
|
||||
</i>
|
||||
<h3 class="font-bold my-2 text-center text-xl">
|
||||
<div v-if="mode === 'email-sent'" class="flex flex-col px-4">
|
||||
<div class="flex justify-center max-w-md items-center flex-col">
|
||||
<i class="material-icons text-accent text-4xl"> verified </i>
|
||||
<h3 class="font-bold my-2 text-center text-lg">
|
||||
{{ $t("we_sent_magic_link") }}
|
||||
</h3>
|
||||
<p class="text-center">
|
||||
{{ $t("we_sent_magic_link_description", { email: form.email }) }}
|
||||
</p>
|
||||
<p class="mt-4 text-secondaryLight">{{ $t("check_your_inbox") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<p v-if="mode === 'sign-in'" class="text-secondaryLight text-xs">
|
||||
By signing in, you are agreeing to our
|
||||
<SmartAnchor class="link" to="/index" label="Terms of Service" />
|
||||
and
|
||||
<SmartAnchor class="link" to="/index" label="Privacy Policy" />.
|
||||
</p>
|
||||
<p v-if="mode === 'email'" class="text-secondaryLight text-xs">
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
label="← All sign in options"
|
||||
@click.native="mode = 'sign-in'"
|
||||
/>
|
||||
</p>
|
||||
<p
|
||||
v-if="mode === 'email-sent'"
|
||||
class="flex flex-1 justify-between text-secondaryLight text-xs"
|
||||
>
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
label="← Re-enter email"
|
||||
@click.native="mode = 'email'"
|
||||
/>
|
||||
<SmartAnchor class="link" label="Dismiss" @click.native="hideModal" />
|
||||
</p>
|
||||
</template>
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -100,11 +115,16 @@ import {
|
||||
import { setLocalConfig } from "~/newstore/localpersistence"
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
email: "",
|
||||
},
|
||||
signingInWithGoogle: false,
|
||||
signingInWithGitHub: false,
|
||||
signingInWithEmail: false,
|
||||
emailRegex:
|
||||
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
|
||||
@@ -123,6 +143,8 @@ export default {
|
||||
})
|
||||
},
|
||||
async signInWithGoogle() {
|
||||
this.signingInWithGoogle = true
|
||||
|
||||
try {
|
||||
const { additionalUserInfo } = await signInUserWithGoogle()
|
||||
|
||||
@@ -191,8 +213,12 @@ export default {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.signingInWithGoogle = false
|
||||
},
|
||||
async signInWithGithub() {
|
||||
this.signingInWithGitHub = true
|
||||
|
||||
try {
|
||||
const { credential, additionalUserInfo } = await signInUserWithGithub()
|
||||
|
||||
@@ -264,9 +290,12 @@ export default {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.signingInWithGitHub = false
|
||||
},
|
||||
async signInWithEmail() {
|
||||
this.signingInWithEmail = true
|
||||
|
||||
const actionCodeSettings = {
|
||||
url: `${process.env.BASE_URL}/enter`,
|
||||
handleCodeInApp: true,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<script>
|
||||
import ThreeGlobe from "three-globe"
|
||||
import * as THREE from "three"
|
||||
import TrackballControls from "three-trackballcontrols"
|
||||
import geojson from "~/assets/geojson/ne_110m_admin_0_countries.geojson"
|
||||
import texture from "~/assets/images/texture.png"
|
||||
|
||||
@@ -15,6 +16,7 @@ export default {
|
||||
renderer: null,
|
||||
scene: null,
|
||||
camera: null,
|
||||
tbControls: null,
|
||||
arcsData: [...Array(20).keys()].map(() => ({
|
||||
startLat: (Math.random() - 0.5) * 180,
|
||||
startLng: (Math.random() - 0.5) * 360,
|
||||
@@ -32,26 +34,26 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// computed: {
|
||||
// labelsData() {
|
||||
// const labelsData = []
|
||||
// this.arcsData.forEach(
|
||||
// ({ startLat, startLng, endLat, endLng, color }, linkIdx) =>
|
||||
// [
|
||||
// [startLat, startLng],
|
||||
// [endLat, endLng],
|
||||
// ].forEach(([lat, lng], edgeIdx) =>
|
||||
// labelsData.push({
|
||||
// lat,
|
||||
// lng,
|
||||
// color: color[edgeIdx],
|
||||
// text: `${linkIdx} ${edgeIdx ? "tgt" : "src"}`,
|
||||
// })
|
||||
// )
|
||||
// )
|
||||
// return labelsData
|
||||
// },
|
||||
// },
|
||||
computed: {
|
||||
labelsData() {
|
||||
const labelsData = []
|
||||
this.arcsData.forEach(
|
||||
({ startLat, startLng, endLat, endLng, color }, linkIdx) =>
|
||||
[
|
||||
[startLat, startLng],
|
||||
[endLat, endLng],
|
||||
].forEach(([lat, lng], edgeIdx) =>
|
||||
labelsData.push({
|
||||
lat,
|
||||
lng,
|
||||
color: color[edgeIdx],
|
||||
text: `${linkIdx} ${edgeIdx ? "tgt" : "src"}`,
|
||||
})
|
||||
)
|
||||
)
|
||||
return labelsData
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.init()
|
||||
@@ -76,28 +78,32 @@ export default {
|
||||
this.globe = new ThreeGlobe()
|
||||
.globeImageUrl(texture)
|
||||
.atmosphereColor("#aaaaaa")
|
||||
|
||||
// arcs layer
|
||||
.arcsData(this.arcsData)
|
||||
.arcColor("color")
|
||||
.arcDashLength(1)
|
||||
.arcDashGap(() => Math.random())
|
||||
.arcStroke(1)
|
||||
.arcStroke(0.6)
|
||||
.arcDashInitialGap(() => Math.random() * 5)
|
||||
.arcDashAnimateTime(2000)
|
||||
|
||||
// hex layer
|
||||
.hexPolygonsData(geojson.features)
|
||||
.hexPolygonResolution(3)
|
||||
.hexPolygonMargin(0.5)
|
||||
.hexPolygonColor(() => `#aaaaaa`)
|
||||
// labels layer
|
||||
// .labelsData(this.labelsData)
|
||||
// .labelLat("lat")
|
||||
// .labelLng("lng")
|
||||
// .labelText("text")
|
||||
// .labelColor("color")
|
||||
// .labelSize(1.5)
|
||||
// .labelDotRadius(0.5)
|
||||
|
||||
// labels layer
|
||||
.labelsData(this.labelsData)
|
||||
.labelLat("lat")
|
||||
.labelLng("lng")
|
||||
.labelText("text")
|
||||
.labelColor("color")
|
||||
.labelSize(1.2)
|
||||
.labelDotRadius(0.8)
|
||||
|
||||
// Setup renderer
|
||||
this.renderer = new THREE.WebGLRenderer({
|
||||
alpha: true,
|
||||
})
|
||||
@@ -105,26 +111,37 @@ export default {
|
||||
this.$refs.globe.clientWidth,
|
||||
this.$refs.globe.clientHeight
|
||||
)
|
||||
|
||||
this.$refs.globe.appendChild(this.renderer.domElement)
|
||||
|
||||
// Setup scene
|
||||
this.scene = new THREE.Scene()
|
||||
this.scene.background = null
|
||||
this.scene.add(this.globe)
|
||||
this.scene.add(new THREE.AmbientLight(0xffffff))
|
||||
this.scene.add(new THREE.DirectionalLight(0xffffff, 0.8))
|
||||
this.scene.add(new THREE.DirectionalLight(0xffffff, 0.6))
|
||||
|
||||
// Setup camera
|
||||
this.camera = new THREE.PerspectiveCamera()
|
||||
this.camera.aspect =
|
||||
this.$refs.globe.clientWidth / this.$refs.globe.clientHeight
|
||||
this.camera.updateProjectionMatrix()
|
||||
this.camera.position.z = 300
|
||||
|
||||
// Add camera controls
|
||||
this.tbControls = new TrackballControls(
|
||||
this.camera,
|
||||
this.renderer.domElement
|
||||
)
|
||||
this.tbControls.rotateSpeed = 5
|
||||
this.tbControls.noZoom = true
|
||||
this.tbControls.noPan = true
|
||||
},
|
||||
|
||||
animate() {
|
||||
this.renderer.render(this.scene, this.camera)
|
||||
this.tbControls.update()
|
||||
requestAnimationFrame(this.animate)
|
||||
this.globe.rotation.y -= 0.005
|
||||
this.globe.rotation.y -= 0.0025
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("color") }}: {{ capitalized(active) }}</label>
|
||||
<div>
|
||||
<!-- text-blue-400 -->
|
||||
<!-- text-green-400 -->
|
||||
<!-- text-teal-400 -->
|
||||
<!-- text-indigo-400 -->
|
||||
<!-- text-purple-400 -->
|
||||
<!-- text-orange-400 -->
|
||||
<!-- text-pink-400 -->
|
||||
<!-- text-red-400 -->
|
||||
<!-- text-yellow-400 -->
|
||||
<ButtonSecondary
|
||||
v-for="(color, index) of accentColors"
|
||||
:key="`color-${index}`"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="capitalized(color)"
|
||||
:class="[`text-${color}-400`, { 'bg-primary': color === active }]"
|
||||
icon="lens"
|
||||
@click.native="setActiveColor(color)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<!-- text-blue-400 -->
|
||||
<!-- text-green-400 -->
|
||||
<!-- text-teal-400 -->
|
||||
<!-- text-indigo-400 -->
|
||||
<!-- text-purple-400 -->
|
||||
<!-- text-orange-400 -->
|
||||
<!-- text-pink-400 -->
|
||||
<!-- text-red-400 -->
|
||||
<!-- text-yellow-400 -->
|
||||
<ButtonSecondary
|
||||
v-for="(color, index) of accentColors"
|
||||
:key="`color-${index}`"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${color.charAt(0).toUpperCase()}${color.slice(1)}`"
|
||||
:class="[`text-${color}-400`, { 'bg-primary': color === active }]"
|
||||
icon="lens"
|
||||
@click.native="setActiveColor(color)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -49,15 +46,11 @@ export default {
|
||||
setLocalConfig("THEME_COLOR", color)
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
setActiveColor(color) {
|
||||
document.documentElement.setAttribute("data-accent", color)
|
||||
this.active = color
|
||||
},
|
||||
capitalized(color) {
|
||||
return `${color.charAt(0).toUpperCase()}${color.slice(1)}`
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -277,9 +277,6 @@ export default {
|
||||
|
||||
.label {
|
||||
@apply p-2;
|
||||
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
}
|
||||
|
||||
.siblings {
|
||||
|
||||
@@ -200,9 +200,6 @@ export default {
|
||||
@apply mx-2;
|
||||
@apply left-0;
|
||||
@apply z-50;
|
||||
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
@apply shadow-lg;
|
||||
|
||||
top: calc(100% - 8px);
|
||||
|
||||
@@ -6,44 +6,26 @@
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
arrow
|
||||
interactive
|
||||
:animate-fill="false"
|
||||
>
|
||||
<template #trigger>
|
||||
<ButtonSecondary
|
||||
<SmartItem
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('choose_language')"
|
||||
:label="$i18n.locales.find(({ code }) => code == $i18n.locale).name"
|
||||
/>
|
||||
{{
|
||||
$i18n.locales.find(({ code }) => code == $i18n.locale).country
|
||||
:label="`${
|
||||
$i18n.locales.find(({ code }) => code == $i18n.locale).country
|
||||
| formatCountry
|
||||
}}
|
||||
} ${$i18n.locales.find(({ code }) => code == $i18n.locale).name}`"
|
||||
/>
|
||||
</template>
|
||||
<NuxtLink
|
||||
<SmartItem
|
||||
v-for="locale in $i18n.locales.filter(
|
||||
({ code }) => code !== $i18n.locale
|
||||
)"
|
||||
:key="locale.code"
|
||||
class="
|
||||
inline-flex
|
||||
items-center
|
||||
px-4
|
||||
py-2
|
||||
transition
|
||||
rounded-lg
|
||||
hover:bg-accentLight hover:text-secondaryDark
|
||||
focus:bg-accentLight focus:text-secondaryDark focus:outline-none
|
||||
"
|
||||
:to="switchLocalePath(locale.code)"
|
||||
>
|
||||
<span class="mr-2 text-lg">
|
||||
{{ locale.country | formatCountry }}
|
||||
</span>
|
||||
<span class="font-semibold">
|
||||
{{ locale.name }}
|
||||
</span>
|
||||
</NuxtLink>
|
||||
:to="switchLocalePath(locale.code).toString()"
|
||||
:label="`${locale.country | formatCountry} ${locale.name}`"
|
||||
/>
|
||||
</tippy>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -1,31 +1,17 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<label>
|
||||
<ColorScheme placeholder="..." tag="span">
|
||||
{{ $t("background") }}:
|
||||
{{
|
||||
$colorMode.preference.charAt(0).toUpperCase() +
|
||||
$colorMode.preference.slice(1)
|
||||
}}
|
||||
<span v-if="$colorMode.preference === 'system'">
|
||||
({{ $colorMode.value }} mode detected)
|
||||
</span>
|
||||
</ColorScheme>
|
||||
</label>
|
||||
<div>
|
||||
<ButtonSecondary
|
||||
v-for="(color, index) of colors"
|
||||
:key="`color-${index}`"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${color.charAt(0).toUpperCase()}${color.slice(1)}`"
|
||||
:class="[
|
||||
{ 'bg-primary': color === $colorMode.preference },
|
||||
{ 'text-accent hover:text-accent': color === $colorMode.value },
|
||||
]"
|
||||
:icon="getIcon(color)"
|
||||
@click.native="$colorMode.preference = color"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-for="(color, index) of colors"
|
||||
:key="`color-${index}`"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${color.charAt(0).toUpperCase()}${color.slice(1)}`"
|
||||
:class="[
|
||||
{ 'bg-primary': color === $colorMode.preference },
|
||||
{ 'text-accent hover:text-accent': color === $colorMode.value },
|
||||
]"
|
||||
:icon="getIcon(color)"
|
||||
@click.native="$colorMode.preference = color"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
@apply text-secondary;
|
||||
@apply font-mono;
|
||||
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
@apply border border-divider;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,24 +16,29 @@
|
||||
"
|
||||
:class="[
|
||||
{ 'opacity-50 cursor-not-allowed': disabled },
|
||||
{ 'pointer-events-none': loading },
|
||||
{ 'flex-1': label },
|
||||
{ 'flex-row-reverse justify-end': reverse },
|
||||
]"
|
||||
:disabled="disabled"
|
||||
:tabindex="loading ? '-1' : '0'"
|
||||
>
|
||||
<i
|
||||
v-if="icon"
|
||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||
class="material-icons"
|
||||
>
|
||||
{{ icon }}
|
||||
</i>
|
||||
<SmartIcon
|
||||
v-if="svg"
|
||||
:name="svg"
|
||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||
class="svg-icons"
|
||||
/>
|
||||
<span v-if="!loading" class="inline-flex items-center">
|
||||
<i
|
||||
v-if="icon"
|
||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||
class="material-icons"
|
||||
>
|
||||
{{ icon }}
|
||||
</i>
|
||||
<SmartIcon
|
||||
v-if="svg"
|
||||
:name="svg"
|
||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||
class="svg-icons"
|
||||
/>
|
||||
</span>
|
||||
<SmartSpinner v-else class="mr-4" />
|
||||
<div class="inline-flex items-start" :class="{ 'flex-col': description }">
|
||||
<div class="font-semibold">
|
||||
{{ label }}
|
||||
@@ -42,6 +47,9 @@
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<i v-if="infoIcon" class="ml-4 text-accent material-icons">
|
||||
{{ infoIcon }}
|
||||
</i>
|
||||
</SmartLink>
|
||||
</template>
|
||||
|
||||
@@ -80,14 +88,18 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
infoIcon: {
|
||||
type: String,
|
||||
default: "",
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
reverse: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
infoIcon: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -123,8 +123,8 @@ export default {
|
||||
@apply flex;
|
||||
@apply items-center;
|
||||
@apply justify-center;
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
@apply transition;
|
||||
|
||||
@apply bg-primaryLight;
|
||||
}
|
||||
|
||||
@@ -133,13 +133,11 @@ export default {
|
||||
@apply flex flex-1 flex-col;
|
||||
@apply m-2;
|
||||
@apply p-4;
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
@apply transition;
|
||||
@apply bg-primary;
|
||||
@apply rounded-lg;
|
||||
@apply shadow-xl;
|
||||
@apply max-w-md;
|
||||
@apply max-h-xl;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
@@ -149,6 +147,7 @@ export default {
|
||||
.modal-body {
|
||||
@apply my-4;
|
||||
@apply overflow-auto;
|
||||
@apply max-h-xl;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
@@ -164,7 +163,6 @@ export default {
|
||||
.modal-leave-active .modal-container {
|
||||
@apply transform;
|
||||
@apply scale-90;
|
||||
@apply ease-in-out;
|
||||
@apply duration-150;
|
||||
@apply transition;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<svg
|
||||
class="animate-spin"
|
||||
:class="`w-${size} h-${size}`"
|
||||
class="animate-spin w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -21,14 +20,3 @@
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
size: {
|
||||
type: Number,
|
||||
default: 6,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -45,7 +45,7 @@ $transition: all 0.2s ease-in-out;
|
||||
@apply align-middle;
|
||||
@apply rounded-full;
|
||||
@apply p-0;
|
||||
@apply m-4;
|
||||
@apply mr-4;
|
||||
@apply cursor-pointer;
|
||||
@apply flex-shrink-0;
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
<div v-else>
|
||||
<label>{{ $t("login_with") }}</label>
|
||||
<p>
|
||||
<FirebaseLogin @show-email="showEmail = true" />
|
||||
<ButtonPrimary
|
||||
v-if="currentUser"
|
||||
label="Get Started"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,7 +49,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
||||
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||
</AppSection>
|
||||
</template>
|
||||
|
||||
@@ -62,7 +66,7 @@ export default {
|
||||
editingteamID: "",
|
||||
me: {},
|
||||
myTeams: [],
|
||||
showEmail: false,
|
||||
showLogin: false,
|
||||
}
|
||||
},
|
||||
subscriptions() {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<transition
|
||||
:appear="appear"
|
||||
name="translate-fade"
|
||||
enter-active-class="duration-500"
|
||||
enter-active-class="transition"
|
||||
enter-class="opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="duration-500"
|
||||
leave-active-class="transition"
|
||||
leave-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<transition
|
||||
:appear="appear"
|
||||
name="translate-slide-right"
|
||||
enter-active-class="duration-500 transform"
|
||||
enter-active-class="transition transform"
|
||||
enter-class="-translate-x-full"
|
||||
enter-to-class="translate-x-0"
|
||||
leave-active-class="duration-500 transform"
|
||||
leave-active-class="transition transform"
|
||||
leave-class="translate-x-0"
|
||||
leave-to-class="-translate-x-full"
|
||||
>
|
||||
|
||||
@@ -251,11 +251,12 @@
|
||||
"extensions_use_toggle": "Use the browser extension to send requests (if present)",
|
||||
"extension_version": "Extension Version",
|
||||
"extension_ver_not_reported": "Not Reported",
|
||||
"extensions_info1": "Browser extension that simplifies access to Hoppscotch",
|
||||
"extensions_info1": "Browser extension simplifies access to Hoppscotch, fix CORS issues, etc.",
|
||||
"extensions_info2": "Get Hoppscotch browser extension!",
|
||||
"installed": "Installed",
|
||||
"login_with": "Login with",
|
||||
"login": "Login",
|
||||
"login_to_hoppscotch": "Login to Hoppscotch",
|
||||
"logged_out": "Logged out",
|
||||
"login_success": "Successfully logged in",
|
||||
"logout": "Logout",
|
||||
@@ -333,10 +334,9 @@
|
||||
"import_from_my_collections": "Import from My Collections",
|
||||
"export_as_json": "Export as JSON",
|
||||
"send_magic_link": "Send a magic link",
|
||||
"check_your_inbox": "Check your inbox.",
|
||||
"you_can_dismiss_this_modal": "You can dismiss this ",
|
||||
"we_sent_magic_link": "We sent you a magic link!",
|
||||
"we_sent_magic_link_description": "We sent an email to {email}. It contains a magic link that’ll log you in.",
|
||||
"we_sent_magic_link_description": "Check your inbox - we sent an email to {email}. It contains a magic link that will log you in.",
|
||||
"hide_sidebar": "Hide sidebar",
|
||||
"show_sidebar": "Show sidebar",
|
||||
"protocols": "Protocols",
|
||||
|
||||
@@ -443,6 +443,6 @@ export default {
|
||||
|
||||
// Router configuration (https://nuxtjs.org/api/configuration-router)
|
||||
router: {
|
||||
linkExactActiveClass: "text-accent",
|
||||
linkExactActiveClass: "active",
|
||||
},
|
||||
}
|
||||
|
||||
15
package-lock.json
generated
15
package-lock.json
generated
@@ -35,6 +35,7 @@
|
||||
"tern": "^0.24.3",
|
||||
"three": "^0.130.0",
|
||||
"three-globe": "^2.18.5",
|
||||
"three-trackballcontrols": "^0.9.0",
|
||||
"vue-apollo": "^3.0.7",
|
||||
"vue-cli-plugin-apollo": "^0.22.2",
|
||||
"vue-functional-data-merge": "^3.1.0",
|
||||
@@ -28000,6 +28001,14 @@
|
||||
"three": ">=0.88.0"
|
||||
}
|
||||
},
|
||||
"node_modules/three-trackballcontrols": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/three-trackballcontrols/-/three-trackballcontrols-0.9.0.tgz",
|
||||
"integrity": "sha512-Z6HmIJnP70r5uONvcPCdLEF0SsG1kbGzNb7qQYj3c7b6v2E3XTlbNpZsgTjt36oKm0Z2tU11D6EbW4i8KIHuqA==",
|
||||
"peerDependencies": {
|
||||
"three": ">= 0.86 <= 1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/throat": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
||||
@@ -55000,6 +55009,12 @@
|
||||
"tinycolor2": "^1.4"
|
||||
}
|
||||
},
|
||||
"three-trackballcontrols": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/three-trackballcontrols/-/three-trackballcontrols-0.9.0.tgz",
|
||||
"integrity": "sha512-Z6HmIJnP70r5uONvcPCdLEF0SsG1kbGzNb7qQYj3c7b6v2E3XTlbNpZsgTjt36oKm0Z2tU11D6EbW4i8KIHuqA==",
|
||||
"requires": {}
|
||||
},
|
||||
"throat": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
"tern": "^0.24.3",
|
||||
"three": "^0.130.0",
|
||||
"three-globe": "^2.18.5",
|
||||
"three-trackballcontrols": "^0.9.0",
|
||||
"vue-apollo": "^3.0.7",
|
||||
"vue-cli-plugin-apollo": "^0.22.2",
|
||||
"vue-functional-data-merge": "^3.1.0",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
<template>
|
||||
<div>
|
||||
<FirebaseLogin />
|
||||
<ButtonPrimary
|
||||
v-if="currentUser === null"
|
||||
label="Get Started"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { currentUser$ } from "~/helpers/fb/auth"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showLogin: false,
|
||||
}
|
||||
},
|
||||
subscriptions() {
|
||||
return {
|
||||
currentUser: currentUser$,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,74 +4,148 @@
|
||||
<Teams />
|
||||
</div>
|
||||
|
||||
<AppSection label="account">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("account") }}</label>
|
||||
<div v-if="currentUser">
|
||||
<ButtonSecondary />
|
||||
<img
|
||||
v-if="currentUser.photoURL"
|
||||
:src="currentUser.photoURL"
|
||||
class="w-6 h-6 rounded-full material-icons"
|
||||
/>
|
||||
<i v-else class="material-icons">account_circle</i>
|
||||
<span>
|
||||
{{ currentUser.displayName || $t("nothing_found") }}
|
||||
</span>
|
||||
|
||||
<br />
|
||||
<ButtonSecondary />
|
||||
<i class="material-icons">email</i>
|
||||
<span>
|
||||
{{ currentUser.email || $t("nothing_found") }}
|
||||
</span>
|
||||
|
||||
<br />
|
||||
<FirebaseLogout />
|
||||
<p>
|
||||
<SmartToggle
|
||||
:on="SYNC_COLLECTIONS"
|
||||
@change="toggleSettings('syncCollections', !SYNC_COLLECTIONS)"
|
||||
>
|
||||
{{ $t("syncCollections") + " " + $t("sync") }}
|
||||
{{ SYNC_COLLECTIONS ? $t("enabled") : $t("disabled") }}
|
||||
</SmartToggle>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<SmartToggle
|
||||
:on="SYNC_ENVIRONMENTS"
|
||||
@change="toggleSettings('syncEnvironments', !SYNC_ENVIRONMENTS)"
|
||||
>
|
||||
{{ $t("syncEnvironments") + " " + $t("sync") }}
|
||||
{{ SYNC_ENVIRONMENTS ? $t("enabled") : $t("disabled") }}
|
||||
</SmartToggle>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<SmartToggle
|
||||
:on="SYNC_HISTORY"
|
||||
@change="toggleSettings('syncHistory', !SYNC_HISTORY)"
|
||||
>
|
||||
{{ $t("syncHistory") + " " + $t("sync") }}
|
||||
{{ SYNC_HISTORY ? $t("enabled") : $t("disabled") }}
|
||||
</SmartToggle>
|
||||
<div class="space-y-8">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||
<div class="md:col-span-1 p-8">
|
||||
<h3 class="heading">
|
||||
{{ $t("account") }}
|
||||
</h3>
|
||||
<p class="mt-1 text-xs text-secondaryLight">
|
||||
Customize your account settings.
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<label>{{ $t("login_with") }}</label>
|
||||
<p>
|
||||
<FirebaseLogin @show-email="showEmail = true" />
|
||||
</p>
|
||||
<div class="md:col-span-2 border border-divider p-8 rounded-lg">
|
||||
<div v-if="currentUser === null">
|
||||
<ButtonPrimary label="Log in" @click.native="showLogin = true" />
|
||||
<div class="mt-4 text-xs text-secondaryLight">
|
||||
Log in to access.
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="space-y-8">
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">User</legend>
|
||||
<div class="mt-4 space-y-4">
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center">
|
||||
<img
|
||||
v-if="currentUser.photoURL"
|
||||
:src="currentUser.photoURL"
|
||||
class="w-5 h-5 rounded-full material-icons"
|
||||
/>
|
||||
<i v-else class="material-icons">account_circle</i>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<label>
|
||||
{{ currentUser.displayName || $t("nothing_found") }}
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-secondaryLight">
|
||||
This is your display name.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center">
|
||||
<i class="material-icons">email</i>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<label>
|
||||
{{ currentUser.email || $t("nothing_found") }}
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-secondaryLight">
|
||||
Your primary email address.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">Sync</legend>
|
||||
<div class="mt-1 text-xs text-secondaryLight">
|
||||
These settings are synced to cloud.
|
||||
</div>
|
||||
<div class="mt-4 space-y-4">
|
||||
<div class="flex items-center">
|
||||
<SmartToggle
|
||||
:on="SYNC_COLLECTIONS"
|
||||
@change="
|
||||
toggleSettings('syncCollections', !SYNC_COLLECTIONS)
|
||||
"
|
||||
>
|
||||
{{ $t("syncCollections") }}
|
||||
</SmartToggle>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<SmartToggle
|
||||
:on="SYNC_ENVIRONMENTS"
|
||||
@change="
|
||||
toggleSettings('syncEnvironments', !SYNC_ENVIRONMENTS)
|
||||
"
|
||||
>
|
||||
{{ $t("syncEnvironments") }}
|
||||
</SmartToggle>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<SmartToggle
|
||||
:on="SYNC_HISTORY"
|
||||
@change="toggleSettings('syncHistory', !SYNC_HISTORY)"
|
||||
>
|
||||
{{ $t("syncHistory") }}
|
||||
</SmartToggle>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
|
||||
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||
<div class="md:col-span-1 p-8">
|
||||
<h3 class="heading">
|
||||
{{ $t("theme") }}
|
||||
</h3>
|
||||
<p class="mt-1 text-xs text-secondaryLight">
|
||||
Customize your application theme.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="md:col-span-2 border border-divider p-8 rounded-lg space-y-8"
|
||||
>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
{{ $t("background") }}
|
||||
</legend>
|
||||
<div class="mt-1 text-xs text-secondaryLight">
|
||||
<ColorScheme placeholder="..." tag="span">
|
||||
{{
|
||||
$colorMode.preference.charAt(0).toUpperCase() +
|
||||
$colorMode.preference.slice(1)
|
||||
}}
|
||||
<span v-if="$colorMode.preference === 'system'">
|
||||
({{ $colorMode.value }} mode detected)
|
||||
</span>
|
||||
</ColorScheme>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<SmartColorModePicker />
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
{{ $t("color") }}
|
||||
</legend>
|
||||
<div class="mt-1 text-xs text-secondaryLight">
|
||||
{{ active.charAt(0).toUpperCase() + active.slice(1) }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<SmartAccentModePicker />
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AppSection label="theme">
|
||||
<div class="flex flex-col">
|
||||
<label>{{ $t("theme") }}</label>
|
||||
<SmartColorModePicker />
|
||||
<SmartAccentModePicker />
|
||||
<span>
|
||||
<SmartToggle
|
||||
:on="SCROLL_INTO_ENABLED"
|
||||
@@ -199,7 +273,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</AppSection>
|
||||
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
||||
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -215,6 +289,7 @@ import {
|
||||
import type { KeysMatching } from "~/types/ts-utils"
|
||||
import { currentUserInfo$ } from "~/helpers/teams/BackendUserInfo"
|
||||
import { currentUser$ } from "~/helpers/fb/auth"
|
||||
import { getLocalConfig } from "~/newstore/localpersistence"
|
||||
|
||||
type SettingsType = typeof defaultSettings
|
||||
|
||||
@@ -237,10 +312,12 @@ export default Vue.extend({
|
||||
EXTENSIONS_ENABLED: true,
|
||||
PROXY_ENABLED: true,
|
||||
|
||||
showEmail: false,
|
||||
|
||||
currentBackendUser: null,
|
||||
currentUser: null,
|
||||
|
||||
showLogin: false,
|
||||
|
||||
active: getLocalConfig("THEME_COLOR") || "green",
|
||||
}
|
||||
},
|
||||
subscriptions() {
|
||||
|
||||
Reference in New Issue
Block a user