Added options, preparing for Quasar rewrite

This commit is contained in:
2024-01-23 23:53:21 +03:00
parent dd084afb61
commit 4ac1fd9574
32 changed files with 3649 additions and 4609 deletions
+97
View File
@@ -0,0 +1,97 @@
<script setup lang="ts">
import { useQuasar } from 'quasar'
import type { PropType } from 'vue'
type ModeOptions = 'in-out' | 'out-in' | 'default' | undefined
type RenderOptions =
| 'never'
| 'always'
| 'xs'
| 'sm'
| 'sm-down'
| 'sm-up'
| 'md'
| 'md-down'
| 'md-up'
| 'lg'
| 'lg-down'
| 'lg-up'
| 'xl'
| undefined
const quasar = useQuasar()
const props = defineProps({
fallback: {
type: String,
default: '',
},
render: {
type: String as PropType<RenderOptions>,
default: 'always',
},
appear: {
type: Boolean,
default: false,
},
mode: {
type: String as PropType<ModeOptions>,
default: 'out-in',
},
enter: {
type: String,
default: 'animate__fadeIn',
},
leave: {
type: String,
default: 'animate__fadeOut',
},
})
const render = computed(() => {
switch (props.render) {
case 'never':
return false
case 'always':
return true
case 'xs':
return quasar.screen.xs
case 'sm':
return quasar.screen.sm
case 'sm-down':
return quasar.screen.xs || quasar.screen.sm
case 'sm-up':
return !quasar.screen.xs
case 'md':
return quasar.screen.md
case 'md-down':
return !quasar.screen.lg && !quasar.screen.xl
case 'md-up':
return !quasar.screen.xs && !quasar.screen.sm
case 'lg':
return quasar.screen.lg
case 'lg-down':
return !quasar.screen.xl
case 'lg-up':
return quasar.screen.lg || quasar.screen.xl
case 'xl':
return quasar.screen.xl
default:
return false
}
})
</script>
<template>
<ClientOnly>
<template #fallback>{{ props.fallback }}</template>
<Transition
:appear="props.appear"
:mode="props.mode"
:enter-active-class="`animate__animated ${props.enter}`"
:leave-active-class="`animate__animated ${props.leave}`"
>
<slot v-if="(quasar.screen.width || quasar.screen.height) && render" />
</Transition>
</ClientOnly>
</template>
@@ -1,6 +1,6 @@
<script setup lang="ts">
import sky from '~/assets/images/portal/sky.png'
import particles from '~/assets/images/portal/particles.png'
import sky from '~/assets/images/textures/sky.png'
import particles from '~/assets/images/textures/particles.png'
const resources: string[] = [sky, particles]
@@ -21,7 +21,10 @@ const mailTemplate = `I've just found a bug on https://enderman.ch and would lik
<footer class="user-select-none text-align-center line-height-1-5">
<span
class="font-small"
:class="{ transpaque: !props.opaque, 'text-shadow': !props.opaque }"
:class="{
'footer-transparent': !props.opaque,
'text-shadow': !props.opaque,
}"
>
<EMail
:class="{
@@ -45,7 +48,8 @@ const mailTemplate = `I've just found a bug on https://enderman.ch and would lik
href="https://enderman.ch"
>Enderman</a
>. All rights reserved.
<sub>
<wbr />
<sub class="nobr">
β{{ version ? version : '?.?.?' }} ({{
buildDate ? buildDate : '1970-01-01'
}})
@@ -55,15 +59,15 @@ const mailTemplate = `I've just found a bug on https://enderman.ch and would lik
</template>
<style scoped lang="scss">
.transpaque {
.footer-transparent {
color: white;
opacity: 0.25;
transition: ease 0.3s;
}
.transpaque:hover {
opacity: 1;
&:hover {
opacity: 1;
}
}
.line-height-1-5 {
@@ -28,9 +28,10 @@ const props = defineProps({
</script>
<template>
<NuxtLink class="no-decoration user-select-none" to="/">
<div
class="logo d-flex flex-row align-items-center justify-content-sm-center"
<div class="d-flex flex-row justify-content-sm-center">
<NuxtLink
class="no-decoration logo d-flex flex-row align-items-center user-select-none"
to="/"
>
<img
class="logo-image"
@@ -45,8 +46,8 @@ const props = defineProps({
<Separator />
<p class="mb-0">{{ props.description }}</p>
</div>
</div>
</NuxtLink>
</NuxtLink>
</div>
</template>
<style scoped lang="scss">
@@ -3,28 +3,11 @@ import { storeToRefs } from 'pinia'
import { usePageStore } from '~/stores/pages'
import logo from '~/assets/images/logo.gif'
import aboutIcon from '~/assets/images/icons/info.png'
import projectIcon from '~/assets/images/icons/defrag.png'
import socialIcon from '~/assets/images/icons/user.png'
const pageStore = usePageStore()
const { pages } = storeToRefs(pageStore)
const links = toRaw(pages.value).filter((page) => page.path !== '/')
const icons = [
{
src: aboutIcon,
alt: 'Information',
},
{
src: projectIcon,
alt: 'Blocks',
},
{
src: socialIcon,
alt: 'Users',
},
]
</script>
<template>
@@ -41,11 +24,11 @@ const icons = [
class="navbar-nav flex-row align-items-center align-items-sm-start align-items-lg-center justify-content-center gap-3 m-2 m-sm-0 mx-lg-2 my-sm-2 my-lg-0"
>
<li v-for="(page, index) in links" :key="index" class="nav-item">
<LinkButton
<Route
:path="page.path"
:name="page.name"
:icon="icons[index].src"
:alt="icons[index].alt"
:icon="page.icon!.src"
:alt="page.icon!.alt"
/>
</li>
</ul>
+66
View File
@@ -0,0 +1,66 @@
<script setup lang="ts">
import { useQuasar } from 'quasar'
import Dialog from '~/components/ui/Dialog.vue'
import cogIcon from '~/assets/images/icons/cog.png'
import pearlIcon from '~/assets/images/icons/pearl.gif'
const quasar = useQuasar()
function optionsMenu() {
quasar
.dialog({
component: Dialog,
componentProps: {
icon: pearlIcon,
alt: 'Pearl',
},
})
.onOk(() => {
console.log('OK')
})
.onCancel(() => {
console.log('Cancel')
})
.onDismiss(() => {
console.log('OK or Cancel (Dialog Dismissed)')
})
}
</script>
<template>
<div class="options-layout pass-through">
<div class="options clickable" @click="optionsMenu()">
<img
class="logo user-select-none"
draggable="false"
:src="cogIcon"
alt="Options"
/>
</div>
</div>
</template>
<style scoped lang="scss">
.options {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 10px;
&-layout {
position: fixed;
top: 0;
right: 0;
}
}
.logo {
width: 16px;
height: 16px;
}
</style>
@@ -33,7 +33,7 @@ const props = defineProps({
:src="props.icon"
:alt="props.alt"
/>
<span class="display-xs-none">
<span class="display-sm">
<strong>
{{ props.name }}
</strong>
@@ -48,8 +48,8 @@ const props = defineProps({
}
&-image {
width: 1.5em;
height: 1.5em;
width: 32px;
height: 32px;
}
}
</style>
+61
View File
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { storeToRefs } from 'pinia'
import { usePageStore } from '~/stores/pages'
const pageStore = usePageStore()
const { pages } = storeToRefs(pageStore)
const route = useRoute()
const state = computed(() => {
const i = pages.value.indexOf(
pages.value.find((page) => page.path === route.fullPath)!,
)
return {
current: route.fullPath,
index: i,
next: toRaw(pages.value)[(i + 1) % pages.value.length].path,
prev: toRaw(pages.value)[i - 1 < 0 ? pages.value.length - (i + 1) : i - 1]
.path,
}
})
</script>
<template>
<div class="control-layout pass-through">
<NuxtLink class="control-icon no-decoration" :to="state.prev">
<FontAwesomeIcon icon="fa-solid fa-angle-left" fixed-width />
</NuxtLink>
<NuxtLink class="control-icon no-decoration" :to="state.next">
<FontAwesomeIcon icon="fa-solid fa-angle-right" fixed-width />
</NuxtLink>
</div>
</template>
<style scoped lang="scss">
.control {
&-layout {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
position: fixed;
width: 100%;
height: 100%;
}
&-icon {
opacity: 0.25;
transition: 0.15s ease;
&:hover {
opacity: 1;
}
}
}
</style>
+84
View File
@@ -0,0 +1,84 @@
<script setup>
import { useDialogPluginComponent } from 'quasar'
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
useDialogPluginComponent()
defineEmits({
...useDialogPluginComponent.emitsObject,
})
const props = defineProps({
icon: {
type: String,
default: '',
},
alt: {
type: String,
default: 'Icon',
},
})
const theme = ref(false)
const animation = ref(true)
</script>
<template>
<QDialog ref="dialogRef" @hide="onDialogHide">
<QCard class="dialog">
<div class="overlay background"></div>
<div class="overlay content">
<img
class="icon-badge user-select-none"
draggable="false"
:src="props.icon"
:alt="props.alt"
/>
<QCardSection>
<h3 class="alex text-align-center">Site options</h3>
<div class="row">
<div class="col-12 col-sm-6">
<p>
<strong>Theme</strong><br />
Available in all flavors, vanilla and chocolate.
</p>
<QToggle
v-model="theme"
class="px-5"
color="black"
dense
size="xl"
:unchecked-icon="mdiWhiteBalanceSunny"
:checked-icon="mdiWeatherNight"
icon-color="primary"
@change="theme = !theme"
/>
<QCheckbox v-model="theme" />
</div>
<div class="col-12 col-sm-6">
<p>
<strong>Animation</strong><br />
Some computers may have issues rendering that gorgeous
background animation. Enabling it substantially increases power
consumption.
</p>
<QToggle
v-model="animation"
color="purple"
dense
size="xl"
:unchecked-icon="mdiStop"
:checked-icon="mdiPlay"
@change="theme = !theme"
/>
</div>
</div>
Report a bug
<QCardActions>
<QBtn label="OK" @click="onDialogOK" />
</QCardActions>
</QCardSection>
</div>
</QCard>
</QDialog>
</template>