add and apply linter
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Simon Vieille 2023-02-24 21:46:46 +01:00
parent 0d4a468014
commit e3a9c580b2
Signed by: deblan
GPG key ID: 579388D585F70417
13 changed files with 1799 additions and 170 deletions

19
.eslintrc.json Normal file
View file

@ -0,0 +1,19 @@
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-recommended"
],
"parserOptions": {
"ecmaVersion": 12
},
"plugins": [
"vue"
],
"rules": {
}
}

1
.prettierrc.json Normal file
View file

@ -0,0 +1 @@
{}

1431
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,14 +10,19 @@
"dev-server": "./node_modules/.bin/encore dev-server",
"dev": "./node_modules/.bin/encore dev",
"watch": "./node_modules/.bin/encore dev --watch",
"build": "./node_modules/.bin/encore production"
"build": "./node_modules/.bin/encore production",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
"format": "prettier . --write"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.3",
"autoprefixer": "^10.4.13",
"eslint": "^8.34.0",
"eslint-plugin-vue": "^9.9.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"postcss-loader": "^7.0.2",
"prettier": "2.8.4",
"sass": "^1.57.1",
"sass-loader": "^13.2.0",
"tailwindcss": "^3.2.4",

View file

@ -1,21 +1,56 @@
<template>
<header class="flex flex-row items-center gap-2 pb-4 border-b-2 sm:gap-4 lg:pb-8">
<span class="px-3 py-2 rounded bg-fuchsia-300">
<svg class="inline stroke-purple-900" height="32" viewBox="0 0 21 21" width="21" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" transform="translate(4 3)"><path d="m6.5.5 6 4v6l-6 4-6-4v-6z"/><circle cx="6.5" cy="7.5" r="3"/></g></svg>
<svg
class="inline stroke-purple-900"
height="32"
viewBox="0 0 21 21"
width="21"
xmlns="http://www.w3.org/2000/svg"
><g
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
transform="translate(4 3)"
><path d="m6.5.5 6 4v6l-6 4-6-4v-6z" /><circle
cx="6.5"
cy="7.5"
r="3"
/></g></svg>
</span>
<h1 class="font-bold font-mono text-2xl text-gray-900 lg:text-4xl">OG:IMAGE</h1>
<h1 class="font-bold font-mono text-2xl text-gray-900 lg:text-4xl">
OG:IMAGE
</h1>
<div class="ml-auto">
<RouterLink :to="{name: 'home'}" custom="true" v-slot="{isActive, href, navigate}">
<RouterLink
v-slot="{isActive, href, navigate}"
:to="{name: 'home'}"
custom="true"
>
<a
v-bind="$attrs"
:href="href"
@click="navigate"
class="rounded ml-8 p-3"
:class="{'bg-slate-300': isActive}"
@click="navigate"
>
<svg class="inline" height="21" viewBox="0 0 21 21" width="21" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" transform="translate(1 1)"><path d="m.5 9.5 9-9 9 9"/><path d="m2.5 7.5v8c0 .5522847.44771525 1 1 1h3c.55228475 0 1-.4477153 1-1v-4c0-.5522847.44771525-1 1-1h2c.5522847 0 1 .4477153 1 1v4c0 .5522847.4477153 1 1 1h3c.5522847 0 1-.4477153 1-1v-8"/></g></svg>
<svg
class="inline"
height="21"
viewBox="0 0 21 21"
width="21"
xmlns="http://www.w3.org/2000/svg"
><g
fill="none"
fill-rule="evenodd"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
transform="translate(1 1)"
><path d="m.5 9.5 9-9 9 9" /><path d="m2.5 7.5v8c0 .5522847.44771525 1 1 1h3c.55228475 0 1-.4477153 1-1v-4c0-.5522847.44771525-1 1-1h2c.5522847 0 1 .4477153 1 1v4c0 .5522847.4477153 1 1 1h3c.5522847 0 1-.4477153 1-1v-8" /></g></svg>
Home
</a>

View file

@ -3,17 +3,42 @@
<div class="col-span-3 flex flex-col gap-4 lg:gap-6">
<div class="drop-shadow-md rounded-md border border-zinc-300 p-5">
<div>
<InputForm id="heading" label="Heading" v-model="heading" />
<RangeForm id="heading-size" min="1" max="10" step="0.1" v-model="headingSize" />
<InputForm
id="heading"
v-model="heading"
label="Heading"
/>
<RangeForm
id="heading-size"
v-model="headingSize"
min="1"
max="10"
step="0.1"
/>
</div>
<div class="py-6">
<TextareaForm id="subheading" label="Subheading" v-model="subheading" />
<RangeForm id="subheading-size" min="1" max="10" step="0.1" v-model="subheadingSize" />
<TextareaForm
id="subheading"
v-model="subheading"
label="Subheading"
/>
<RangeForm
id="subheading-size"
v-model="subheadingSize"
min="1"
max="10"
step="0.1"
/>
</div>
<div class="pb-6">
<SelectForm id="font" :items="fonts" label="Font" v-model="font" />
<SelectForm
id="font"
v-model="font"
:items="fonts"
label="Font"
/>
</div>
<div>
@ -25,66 +50,157 @@
<div class="drop-shadow-md rounded-md border border-zinc-300 p-5">
<div>
<InputForm id="author" label="Author" v-model="author" />
<InputForm
id="author"
v-model="author"
label="Author"
/>
</div>
<div class="py-6">
<FileForm id="avatar" label="Avatar" v-model="avatar" />
<FileForm
id="avatar"
v-model="avatar"
label="Avatar"
/>
</div>
<div>
<FileForm id="logo" label="Logo" v-model="logo" />
<FileForm
id="logo"
v-model="logo"
label="Logo"
/>
</div>
</div>
</div>
<div class="col-span-3 px-10 flex flex-col gap-4 lg:gap-6">
<div class="drop-shadow-md rounded-md border border-zinc-300 p-5">
<div>
<InputForm id="text-color" label="Text color" type="color" v-model="textColor" />
<InputForm
id="text-color"
v-model="textColor"
label="Text color"
type="color"
/>
</div>
<div class="py-6">
<FileForm id="background" label="Background" v-model="background" />
<FileForm
id="background"
v-model="background"
label="Background"
/>
</div>
<div>
<InputForm id="background-hover" label="Background hover" type="color" v-model="backgroundHover" />
<RangeForm id="background-hover-opacity" min="0" max="1" step="0.05" v-model="backgroundHoverOpacity" />
<InputForm
id="background-hover"
v-model="backgroundHover"
label="Background hover"
type="color"
/>
<RangeForm
id="background-hover-opacity"
v-model="backgroundHoverOpacity"
min="0"
max="1"
step="0.05"
/>
</div>
</div>
<div class="drop-shadow-md rounded-md border border-zinc-300 p-5">
<div>
<label class="block text-sm font-medium text-gray-700" for="width">Size and quality</label>
<label
class="block text-sm font-medium text-gray-700"
for="width"
>Size and quality</label>
<div class="grid grid-cols-2 gap-x-4">
<InputForm id="width" type="number" v-model="width" />
<InputForm id="height" type="number" v-model="height" />
<InputForm
id="width"
v-model="width"
type="number"
/>
<InputForm
id="height"
v-model="height"
type="number"
/>
</div>
<RangeForm id="quality" min="0" max="1" step="0.05" v-model="quality" />
<RangeForm
id="quality"
v-model="quality"
min="0"
max="1"
step="0.05"
/>
</div>
<div>
<RangeForm id="content-padding" min="2.5" max="10" step="0.05" v-model="contentPadding" label="Box padding" />
<RangeForm
id="content-padding"
v-model="contentPadding"
min="2.5"
max="10"
step="0.05"
label="Box padding"
/>
</div>
</div>
</div>
<div class="col-span-6 space-y-6" ref="ogwrapper">
<div class="og" ref="og" :style="ogStyle()">
<div class="og-image" :style="ogImageStyle()">
<div class="og-image-hover" :style="ogImageHoverStyle()">
<div class="h-full flex flex-col justify-between" :style="ogContentStyle()">
<div
ref="ogwrapper"
class="col-span-6 space-y-6"
>
<div
ref="og"
class="og"
:style="ogStyle()"
>
<div
class="og-image"
:style="ogImageStyle()"
>
<div
class="og-image-hover"
:style="ogImageHoverStyle()"
>
<div
class="h-full flex flex-col justify-between"
:style="ogContentStyle()"
>
<div>
<h1 class="leading-none" v-text="heading" :style="ogHeadingStyle()"></h1>
<p class="mt-10 mb-16 leading-tight" v-text="subheading" :style="ogSubheadingStyle()"></p>
<h1
class="leading-none"
:style="ogHeadingStyle()"
v-text="heading"
/>
<p
class="mt-10 mb-16 leading-tight"
:style="ogSubheadingStyle()"
v-text="subheading"
/>
</div>
<div class="w-full flex flex-row items-center og-image--footer">
<img class="mr-4 h-10 w-10 rounded-full" v-if="avatar" :src="avatar">
<img
v-if="avatar"
class="mr-4 h-10 w-10 rounded-full"
:src="avatar"
>
<span class="mr-auto" v-text="author"></span>
<span
class="mr-auto"
v-text="author"
/>
<img v-if="logo" class="mr-4 h-10 w-10 rounded-full" :src="logo">
<img
v-if="logo"
class="mr-4 h-10 w-10 rounded-full"
:src="logo"
>
</div>
</div>
</div>
@ -92,37 +208,21 @@
</div>
<div class="text-center">
<DownloadButton v-on:click="downloadAsPng" class="rounded-l-md" label="PNG"/>
<DownloadButton v-on:click="downloadAsJpeg" class="rounded-r-md" label="JPEG"/>
<DownloadButton
class="rounded-l-md"
label="PNG"
@click="downloadAsPng"
/>
<DownloadButton
class="rounded-r-md"
label="JPEG"
@click="downloadAsJpeg"
/>
</div>
</div>
</div>
</template>
<style>
.og {
background: #cecece;
max-width: 10px;
margin: auto;
}
.og-heading {
font-size: 5em;
}
.og-subheading {
font-size: 3em;
}
.og-image--footer {
font-size: 1.3em;
}
.og-image-hover {
overflow: hidden;
}
</style>
<script>
import { hexToRgb } from '../util/color'
import { toPng, toJpeg } from 'html-to-image'
@ -179,6 +279,63 @@ export default {
],
}
},
watch: {
author(value) {
localStorage.setItem('author', value)
},
heading(value) {
localStorage.setItem('heading', value)
},
subheading(value) {
localStorage.setItem('subheading', value)
},
avatar(value) {
localStorage.setItem('avatar', value)
},
logo(value) {
localStorage.setItem('logo', value)
},
textColor(value) {
localStorage.setItem('textColor', value)
},
background(value) {
localStorage.setItem('background', value)
},
backgroundHover(value) {
localStorage.setItem('backgroundHover', value)
},
backgroundHoverOpacity(value) {
localStorage.setItem('backgroundHoverOpacity', value)
},
headingSize(value) {
localStorage.setItem('headingSize', value)
},
subheadingSize(value) {
localStorage.setItem('subheadingSize', value)
},
headingAlign(value) {
localStorage.setItem('headingAlign', value)
},
width(value) {
localStorage.setItem('width', value)
},
height(value) {
localStorage.setItem('height', value)
},
quality(value) {
localStorage.setItem('quality', value)
},
contentPadding(value) {
localStorage.setItem('contentPadding', value)
},
font(value) {
localStorage.setItem('font', value)
},
},
mounted() {
this.updateOgMaxWidth()
window.addEventListener('resize', this.updateOgMaxWidth, false)
},
methods: {
ogStyle() {
return {
@ -258,63 +415,30 @@ export default {
this.ogMaxWidth = this.$refs.ogwrapper.offsetWidth
this.$refs.og.style.display = 'block'
},
},
watch: {
author(value) {
localStorage.setItem('author', value)
},
heading(value) {
localStorage.setItem('heading', value)
},
subheading(value) {
localStorage.setItem('subheading', value)
},
avatar(value) {
localStorage.setItem('avatar', value)
},
logo(value) {
localStorage.setItem('logo', value)
},
textColor(value) {
localStorage.setItem('textColor', value)
},
background(value) {
localStorage.setItem('background', value)
},
backgroundHover(value) {
localStorage.setItem('backgroundHover', value)
},
backgroundHoverOpacity(value) {
localStorage.setItem('backgroundHoverOpacity', value)
},
headingSize(value) {
localStorage.setItem('headingSize', value)
},
subheadingSize(value) {
localStorage.setItem('subheadingSize', value)
},
headingAlign(value) {
localStorage.setItem('headingAlign', value)
},
width(value) {
localStorage.setItem('width', value)
},
height(value) {
localStorage.setItem('height', value)
},
quality(value) {
localStorage.setItem('quality', value)
},
contentPadding(value) {
localStorage.setItem('contentPadding', value)
},
font(value) {
localStorage.setItem('font', value)
},
},
mounted() {
this.updateOgMaxWidth()
window.addEventListener('resize', this.updateOgMaxWidth, false)
}
}
</script>
<style>
.og {
background: #cecece;
max-width: 10px;
margin: auto;
}
.og-heading {
font-size: 5em;
}
.og-subheading {
font-size: 3em;
}
.og-image--footer {
font-size: 1.3em;
}
.og-image-hover {
overflow: hidden;
}
</style>

View file

@ -1,14 +1,50 @@
<template>
<button v-on:click="update('left')">
<svg class="inline border-gray-400 rounded-md" :class="{border: modelValue === 'left'}" height="40" viewBox="0 0 21 21" width="40" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="m4.5 6.5h12"/><path d="m4.498 10.5h5.997"/><path d="m4.5 14.5h9.995"/></g></svg>
<button @click="update('left')">
<svg
class="inline border-gray-400 rounded-md"
:class="{border: modelValue === 'left'}"
height="40"
viewBox="0 0 21 21"
width="40"
xmlns="http://www.w3.org/2000/svg"
><g
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
><path d="m4.5 6.5h12" /><path d="m4.498 10.5h5.997" /><path d="m4.5 14.5h9.995" /></g></svg>
</button>
<button v-on:click="update('center')">
<svg class="inline border-gray-400 rounded-md" :class="{border: modelValue === 'center'}" height="40" viewBox="0 0 21 21" width="40" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="m4.5 6.5h12"/><path d="m7.498 10.5h5.997"/><path d="m5.5 14.5h9.995"/></g></svg>
<button @click="update('center')">
<svg
class="inline border-gray-400 rounded-md"
:class="{border: modelValue === 'center'}"
height="40"
viewBox="0 0 21 21"
width="40"
xmlns="http://www.w3.org/2000/svg"
><g
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
><path d="m4.5 6.5h12" /><path d="m7.498 10.5h5.997" /><path d="m5.5 14.5h9.995" /></g></svg>
</button>
<button v-on:click="update('right')">
<svg class="inline border-gray-400 rounded-md" :class="{border: modelValue === 'right'}" height="40" viewBox="0 0 21 21" width="40" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="m4.5 6.5h12"/><path d="m10.498 10.5h5.997"/><path d="m6.5 14.5h9.995"/></g></svg>
<button @click="update('right')">
<svg
class="inline border-gray-400 rounded-md"
:class="{border: modelValue === 'right'}"
height="40"
viewBox="0 0 21 21"
width="40"
xmlns="http://www.w3.org/2000/svg"
><g
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
><path d="m4.5 6.5h12" /><path d="m10.498 10.5h5.997" /><path d="m6.5 14.5h9.995" /></g></svg>
</button>
</template>

View file

@ -1,11 +1,11 @@
<template>
<button
type="button"
class="px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-blue-500 dark:focus:text-white" v-on:click="downloadAsJpeg"
class="px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-blue-500 dark:focus:text-white"
:class="class"
@click="downloadAsJpeg"
v-text="label"
>
</button>
/>
</template>
<script>

View file

@ -1,12 +1,17 @@
<template>
<label class="block text-sm font-medium text-gray-700" :for="id" v-if="label" v-text="label"></label>
<label
v-if="label"
class="block text-sm font-medium text-gray-700"
:for="id"
v-text="label"
/>
<input
:id="id"
class="mt-2 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
type="file"
:id="id"
:class="class"
@change="convertFileToBase64($event.target.files)"
/>
>
</template>
<script>

View file

@ -1,14 +1,19 @@
<template>
<label class="block text-sm font-medium text-gray-700" :for="id" v-if="label" v-text="label"></label>
<label
v-if="label"
class="block text-sm font-medium text-gray-700"
:for="id"
v-text="label"
/>
<input
:id="id"
class="mt-2 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
:type="type"
:id="id"
:value="modelValue"
:class="class"
@change="$emit('change', $event)"
@input="$emit('update:modelValue', $event.target.value)"
/>
>
</template>
<script>

View file

@ -1,16 +1,21 @@
<template>
<label class="block text-sm font-medium text-gray-700" :for="id" v-if="label" v-text="label"></label>
<label
v-if="label"
class="block text-sm font-medium text-gray-700"
:for="id"
v-text="label"
/>
<input
:id="id"
class="mt-2 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
type="range"
:min="min"
:max="max"
:step="step"
:id="id"
:class="class"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
>
</template>
<script>

View file

@ -1,13 +1,23 @@
<template>
<label class="block text-sm font-medium text-gray-700" :for="id" v-if="label" v-text="label"></label>
<label
v-if="label"
class="block text-sm font-medium text-gray-700"
:for="id"
v-text="label"
/>
<select
:id="id"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
:id="id"
:class="class"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
<option v-for="item in items" :key="item.value" :value="item.value" v-text="item.label"></option>
:class="class"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
<option
v-for="item in items"
:key="item.value"
:value="item.value"
v-text="item.label"
/>
</select>
</template>

View file

@ -1,12 +1,17 @@
<template>
<label class="block text-sm font-medium text-gray-700" :for="id" v-if="label" v-text="label"></label>
<label
v-if="label"
class="block text-sm font-medium text-gray-700"
:for="id"
v-text="label"
/>
<textarea
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
:id="id"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
:class="class"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
></textarea>
/>
</template>
<script>