Added stylelint, improved code readability, implemented swipe controls

This commit is contained in:
Andrew Illarionov 2023-11-23 02:53:30 +03:00
parent c509c770f6
commit 2a1bcfc3d2
26 changed files with 1454 additions and 139 deletions

View File

@ -1,4 +1,5 @@
> 1%
last 2 versions
last 5 major versions
not dead
not ie 11
not ie <= 11
not op_mini all

1
.stylelintcache Normal file
View File

@ -0,0 +1 @@
[{"D:\\Software\\Development\\Websites\\enderman.ch\\index\\assets\\styles\\list-types.scss":"1","D:\\Software\\Development\\Websites\\enderman.ch\\index\\assets\\styles\\transitions.scss":"2","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Logo.vue":"3","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\LinkButton.vue":"4","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\TransitionY.vue":"5","D:\\Software\\Development\\Websites\\enderman.ch\\index\\app.vue":"6","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\EMail.vue":"7","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Navigation.vue":"8","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Separator.vue":"9","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Flooter.vue":"10","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Portal.vue":"11","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\about.vue":"12","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\index.vue":"13","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\projects.vue":"14","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\social.vue":"15"},{"size":389,"mtime":1700689887460,"hashOfConfig":"16"},{"size":165,"mtime":1700688268778,"hashOfConfig":"16"},{"size":1113,"mtime":1700251498711,"hashOfConfig":"16"},{"size":986,"mtime":1700324714794,"hashOfConfig":"16"},{"size":1513,"mtime":1700430002840,"hashOfConfig":"16"},{"size":2315,"mtime":1700689012136,"hashOfConfig":"16"},{"size":804,"mtime":1700688952880,"hashOfConfig":"16"},{"size":1183,"mtime":1700689030040,"hashOfConfig":"16"},{"size":300,"mtime":1700689033070,"hashOfConfig":"16"},{"size":1853,"mtime":1700508715727,"hashOfConfig":"16"},{"size":16880,"mtime":1700502035614,"hashOfConfig":"16"},{"size":2135,"mtime":1700689265787,"hashOfConfig":"16"},{"size":3117,"mtime":1700689271383,"hashOfConfig":"16"},{"size":2304,"mtime":1700689265769,"hashOfConfig":"16"},{"size":3232,"mtime":1700689265781,"hashOfConfig":"16"},"5tgxr3"]

2
.stylelintignore Normal file
View File

@ -0,0 +1,2 @@
node_modules/
assets/styles/**/*.css

11
.stylelintrc.cjs Normal file
View File

@ -0,0 +1,11 @@
module.exports = {
defaultSeverity: 'warning',
extends: [
'stylelint-config-standard-scss',
'stylelint-config-recommended-vue',
],
plugins: [],
rules: {
'declaration-empty-line-before': null,
},
}

View File

@ -17,6 +17,7 @@ useHead({
class="d-flex flex-column align-items-center pt-sm-5 h-100 animate__animated-sm animate__delay-1-5s animate__fadeInDown"
>
<NuxtLayout name="card">
<template #header> </template>
<template #footer>
<ClientOnly>
<template #fallback> </template>
@ -52,5 +53,3 @@ useHead({
/>
</Transition>
</template>
<style></style>

BIN
assets/images/icons/cog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -15570,16 +15570,6 @@ textarea.form-control-lg {
filter: blur(1em);
}
.expand-enter-active,
.expand-leave-active {
transition-property: opacity, height;
}
.expand-enter,
.expand-leave-to {
opacity: 0;
}
@counter-style do {
system: fixed;
symbols: "💻" "📌" "👻" "📷";
@ -15623,7 +15613,7 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: white;
font-family: "Lato", sans-serif;
font-family: Lato, sans-serif;
font-size: 18px;
height: 100%;
}
@ -15655,7 +15645,7 @@ body {
}
.alex {
font-family: "Alexandria", sans-serif;
font-family: Alexandria, sans-serif;
}
.smooth-glide {
@ -15776,7 +15766,6 @@ body {
}
.animate__animated-sm {
animation-duration: var(--animate-duration);
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.animate__delay-1-5s {

File diff suppressed because one or more lines are too long

15
assets/styles/main.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -33,24 +33,18 @@ html {
body {
display: flex;
flex-direction: column;
background-color: rgb(6, 25, 28);
background-color: rgb(6 25 28);
background-image: url('~/assets/images/sky.png');
background-attachment: fixed;
background-blend-mode: multiply;
background-size: cover;
background-repeat: no-repeat;
image-rendering: pixelated;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: white;
font-family: 'Lato', sans-serif;
font-family: Lato, sans-serif;
font-size: 18px;
height: 100%;
}
@ -83,7 +77,7 @@ body {
}
.alex {
font-family: 'Alexandria', sans-serif;
font-family: Alexandria, sans-serif;
}
.smooth-glide {
@ -92,7 +86,7 @@ body {
// Query-overridable classes.
.background {
background-color: rgba(0, 0, 0, 0.5);
background-color: rgb(0 0 0 / 50%);
}
.dimensions {
@ -111,6 +105,7 @@ body {
&-hi {
@extend .link;
color: cornflowerblue;
&:hover {
@ -132,17 +127,16 @@ body {
.radial-gradient {
background: radial-gradient(
circle at left,
rgba(255, 255, 255, 0.8),
rgba(255, 255, 255, 0.75),
rgba(255, 255, 255, 0)
rgb(255 255 255 / 80%),
rgb(255 255 255 / 75%),
rgb(255 255 255 / 0%)
);
}
.scrollbar {
min-height: 128px;
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 0.15) rgba(0, 0, 0, 0.2);
scrollbar-color: rgb(255 255 255 / 15%) rgb(0 0 0 / 20%);
&::-webkit-scrollbar {
width: 8px;
@ -150,12 +144,12 @@ body {
&::-webkit-scrollbar-track {
border-radius: 8px;
background-color: rgba(0, 0, 0, 0.2);
background-color: rgb(0 0 0 / 20%);
}
&::-webkit-scrollbar-thumb {
border-radius: 8px;
background-color: rgba(255, 255, 255, 0.15);
background-color: rgb(255 255 255 / 15%);
}
}
@ -165,20 +159,20 @@ body {
}
.scrollbar {
scrollbar-color: rgba(0, 0, 0, 0.2) rgba(255, 255, 255, 0.2);
scrollbar-color: rgb(0 0 0 / 20%) rgb(255 255 255 / 20%);
&::-webkit-scrollbar-track {
background-color: rgba(255, 255, 255, 0.2);
background-color: rgb(255 255 255 / 20%);
}
&::-webkit-scrollbar-thumb {
border-radius: 8px;
background-color: rgba(0, 0, 0, 0.2);
background-color: rgb(0 0 0 / 20%);
}
}
.background {
background-color: rgba(255, 255, 255, 0.8);
background-color: rgb(255 255 255 / 80%);
}
.link {
@ -198,23 +192,20 @@ body {
.radial-gradient {
background: radial-gradient(
circle at left,
rgba(0, 0, 0, 0.95),
rgba(0, 0, 0, 0.8),
rgba(0, 0, 0, 0)
rgb(0 0 0 / 95%),
rgb(0 0 0 / 80%),
rgb(0 0 0 / 0%)
);
}
}
.floaty {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: fit-content;
height: fit-content;
margin: auto;
}
@ -231,12 +222,11 @@ body {
.dimensions {
width: 80%;
min-height: fit-content;
max-height: 90%;
}
.fade-mask-sm {
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 5%, rgba(0, 0, 0, 1) 95%, rgba(0, 0, 0, 0));
mask-image: linear-gradient(to bottom, rgb(0 0 0 / 0%), rgb(0 0 0 / 100%) 5%, rgb(0 0 0 / 100%) 95%, rgb(0 0 0 / 0%));
}
.rounded-1 {
@ -249,7 +239,6 @@ body {
.animate__animated-sm {
animation-duration: var(--animate-duration);
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}

View File

@ -1,14 +0,0 @@
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
body::-webkit-scrollbar-thumb {
background-color: darkgrey;
outline: 1px solid slategrey;
}
/*# sourceMappingURL=scrollbar.css.map */

View File

@ -1 +0,0 @@
{"version":3,"sourceRoot":"","sources":["scrollbar.scss"],"names":[],"mappings":"AAAA;EACI;;;AAGJ;EACI;;;AAGJ;EACE;EACA","file":"scrollbar.css"}

View File

@ -10,13 +10,3 @@
filter: blur(1em);
}
}
.expand-enter-active,
.expand-leave-active {
transition-property: opacity, height;
}
.expand-enter,
.expand-leave-to {
opacity: 0;
}

View File

@ -39,5 +39,3 @@ const href =
</slot>
</a>
</template>
<style scoped lang="scss"></style>

View File

@ -17,7 +17,10 @@ const mailTemplate = `I've just found a bug on https://enderman.ch and would lik
<template>
<footer class="user-select-none text-align-center line-height-1-5">
<span class="font-small text-shadow" :class="{ transpaque: !props.opaque }">
<span
class="font-small"
:class="{ transpaque: !props.opaque, 'text-shadow': !props.opaque }"
>
<EMail
class="link-hi-force-dark"
address="contact@enderman.ch"

View File

@ -10,6 +10,7 @@ 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 = [aboutIcon, projectIcon, socialIcon]
</script>
@ -26,7 +27,7 @@ const icons = [aboutIcon, projectIcon, socialIcon]
<ul
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 pages" :key="index" class="nav-item">
<li v-for="(page, index) in links" :key="index" class="nav-item">
<LinkButton
:path="page.path"
:name="page.name"
@ -37,5 +38,3 @@ const icons = [aboutIcon, projectIcon, socialIcon]
</ul>
</nav>
</template>
<style scoped lang="scss"></style>

View File

@ -17,5 +17,3 @@ const props = defineProps({
:style="{ height: props.height + 'px' }"
/>
</template>
<style scoped lang="scss"></style>

View File

@ -1,7 +1,53 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import type { UseSwipeDirection } from '@vueuse/core'
import { useSwipe } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { usePageStore } from '~/stores/pages'
const router = useRouter()
const route = useRoute()
const card = ref<HTMLElement | null>(null)
const pageStore = usePageStore()
const { pages } = storeToRefs(pageStore)
const swipe = useSwipe(card, {
passive: true,
onSwipe: (touch: TouchEvent) => {
console.log(card.value?.offsetWidth, swipe.lengthX.value)
},
onSwipeEnd: (touch: TouchEvent, direction: UseSwipeDirection) => {
const currentPage = pages.value.find(
(page) => page.path === route.fullPath,
)!
const currentIndex = pages.value.indexOf(currentPage)
if (
card.value?.offsetWidth &&
Math.abs(swipe.lengthX.value) / card.value?.offsetWidth >= 0.5
) {
if (swipe.lengthX.value > 0) {
router.push(
toRaw(pages.value)[
currentIndex - 1 < 0
? pages.value.length - (currentIndex + 1)
: currentIndex - 1
].path,
)
} else {
router.push(
toRaw(pages.value)[(currentIndex + 1) % pages.value.length].path,
)
}
}
},
})
</script>
<template>
<main
ref="card"
class="dimensions background rounded-1 overflow-auto d-flex flex-column gap-3 gap-sm-2 px-4 pt-4 pb-3"
>
<Navigation />
@ -12,5 +58,3 @@
<slot name="footer" />
</main>
</template>
<style scoped lang="scss"></style>

View File

@ -41,7 +41,7 @@ export default defineNuxtConfig({
],
},
css: [
'~/assets/styles/main.css',
'~/assets/styles/main.min.css',
'@fortawesome/fontawesome-svg-core/styles.css',
],
plugins: [],
@ -51,6 +51,7 @@ export default defineNuxtConfig({
'@nuxtjs/eslint-module',
'@pinia/nuxt',
'nuxt-quasar-ui',
'@nuxtjs/stylelint-module',
],
quasar: {
lang: 'en-US',

1298
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,8 +19,10 @@
"@nuxt/types": "^2.17.2",
"@nuxtjs/eslint-config-typescript": "^12.1.0",
"@nuxtjs/eslint-module": "^4.1.0",
"@nuxtjs/stylelint-module": "^5.1.0",
"@pinia/nuxt": "^0.5.1",
"@typescript-eslint/parser": "^6.10.0",
"csso": "^5.0.5",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-nuxt": "^4.0.0",
@ -30,6 +32,9 @@
"nuxt-quasar-ui": "^2.0.6",
"prettier": "^3.0.3",
"sass": "^1.69.5",
"stylelint": "^15.11.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard-scss": "^11.1.0",
"typescript": "^5.2.2",
"vite-plugin-require": "^0.0.3",
"vue": "^3.3.8",
@ -50,6 +55,7 @@
"@quasar/extras": "^1.16.8",
"animate.css": "^4.1.1",
"bootstrap": "^5.3.2",
"caniuse-lite": "^1.0.30001564",
"humps": "^2.0.1",
"pinia": "^2.1.7",
"quasar": "^2.14.0"

View File

@ -52,9 +52,9 @@ useHead({
<hr />
<p>
Nice to meet you! I'm Andrew, a {{ age }}-year-old guy from Kaluga,
Russia. I have been developing software since I was 10 years old, and I
have always been interested in technology. I'm a middle-senior C/++
developer and a junior full-stack engineer.
Russia. I have been developing software since I was 10, and I have always
been interested in technology. I'm a middle-senior C/++ developer and a
junior full-stack engineer.
<sup>1</sup>
</p>
<p class="font-small">
@ -75,5 +75,3 @@ useHead({
</p>
</section>
</template>
<style scoped lang="scss"></style>

View File

@ -99,5 +99,3 @@ useHead({
</p>
</section>
</template>
<style scoped lang="scss"></style>

View File

@ -91,5 +91,3 @@ useHead({
</p>
</section>
</template>
<style scoped lang="scss"></style>

View File

@ -88,7 +88,7 @@ useHead({
<template>
<section>
<h3 class="alex">Social media</h3>
<h3 class="alex">Online presence</h3>
<hr />
<p>
<strong>🚧 This page is currently under construction.</strong> Expect a
@ -97,30 +97,43 @@ useHead({
I will make sure to sand them down.
</p>
<hr />
<ul class="list-style-type-none p-0">
<li v-for="(page, index) in socials" :key="index">
<div class="d-flex flex-row align-items-center gap-1">
<ClientOnly>
<FontAwesomeIcon :icon="`fa-brands fa-${page.icon}`" fixed-width />
</ClientOnly>
<a class="link-hi" target="_blank" rel="noopener" :href="page.url">
{{ page.name }}
</a>
</div>
</li>
</ul>
<h3 class="alex">Contact me</h3>
<p>
Personal:
<EMail
class="link-hi"
address="contact@enderman.ch"
subject="Hey Enderman!"
/><br />
Manager: <EMail class="link-hi" address="manager@enderman.ch" /><br />
Abuse: <EMail class="link-hi" address="abuse@enderman.ch" />
</p>
<div class="row">
<div class="col-12 col-md-3">
<h5 class="alex">Social media</h5>
<ul class="list-style-type-none p-0">
<li v-for="(page, index) in socials" :key="index">
<div class="d-flex flex-row align-items-center gap-1">
<ClientOnly>
<FontAwesomeIcon
:icon="`fa-brands fa-${page.icon}`"
fixed-width
/>
</ClientOnly>
<a
class="link-hi"
target="_blank"
rel="noopener"
:href="page.url"
>
{{ page.name }}
</a>
</div>
</li>
</ul>
</div>
<div class="col-12 col-md-9">
<h5 class="alex">Contact me</h5>
<p>
Personal:
<EMail
class="link-hi"
address="contact@enderman.ch"
subject="Hey Enderman!"
/><br />
Manager: <EMail class="link-hi" address="manager@enderman.ch" /><br />
Abuse: <EMail class="link-hi" address="abuse@enderman.ch" />
</p>
</div>
</div>
</section>
</template>
<style scoped lang="scss"></style>

View File

@ -7,6 +7,10 @@ export const usePageStore = defineStore('page', () => {
'endermanch, enderman, developer, youtuber, filmmaker, artist, engineer'
const pages = ref([
{
name: 'Home',
path: '/',
},
{
name: 'About',
path: '/about',
@ -26,13 +30,12 @@ export const usePageStore = defineStore('page', () => {
useRouter()
.getRoutes()
.forEach((route) => {
if (route.path !== '/')
pages.value.push({
name: route.path.slice(1)[0].toUpperCase() + route.path.slice(2),
path: route.path,
})
})
.forEach((route) =>
pages.value.push({
name: route.path.slice(1)[0].toUpperCase() + route.path.slice(2),
path: route.path,
}),
)
}
return {