mirror of
https://github.com/Findus23/lw1.at.git
synced 2024-09-16 12:13:44 +02:00
convert to typescript
This commit is contained in:
parent
2ff9524ab3
commit
7358470f10
21 changed files with 1163 additions and 851 deletions
4
.eslintignore
Normal file
4
.eslintignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
# don't ever lint node_modules
|
||||
node_modules
|
||||
# don't lint build output (make sure it's set to your correct build folder name)
|
||||
dist
|
32
.eslintrc.js
Normal file
32
.eslintrc.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
"parser": "vue-eslint-parser",
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
"html"
|
||||
],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
"plugin:vue/essential",
|
||||
"plugin:vue/base",
|
||||
],
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
semi: "error",
|
||||
"no-mixed-spaces-and-tabs": 0,
|
||||
"vue/no-side-effects-in-computed-properties": 0,
|
||||
"vue/no-unused-vars": 0, //maybe warn instead
|
||||
"no-undef": 0,
|
||||
"@typescript-eslint/ban-ts-comment": 0,
|
||||
"@typescript-eslint/no-var-requires": 0
|
||||
},
|
||||
};
|
|
@ -4,9 +4,8 @@
|
|||
"version": "1.0.0",
|
||||
"author": "Lukas Winkler <l.winkler23@mailbox.org>",
|
||||
"private": true,
|
||||
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=\"production\" TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack --config webpack.prod.ts",
|
||||
"build": "NODE_ENV=\"production\" TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack --config webpack.prod.ts --progress",
|
||||
"dev": "TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack serve --config webpack.dev.ts --hot",
|
||||
"json": "TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack --config webpack.prod.ts --profile --json > stats.json"
|
||||
},
|
||||
|
@ -37,6 +36,8 @@
|
|||
"@types/webpack": "^4.41.25",
|
||||
"@types/webpack-dev-server": "^3.11.1",
|
||||
"@types/webpack-subresource-integrity": "^1.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.10.0",
|
||||
"@typescript-eslint/parser": "^4.10.0",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-loader": "^8.0.0-beta.0",
|
||||
|
@ -45,9 +46,10 @@
|
|||
"compression-webpack-plugin": "^7.1.0",
|
||||
"cross-env": "^7.0.0",
|
||||
"css-loader": "^5.0.1",
|
||||
"eslint": "^7.4.0",
|
||||
"eslint": "^7.16.0",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-html": "^6.0.0",
|
||||
"eslint-plugin-vue": "^7.3.0",
|
||||
"file-loader": "^6.0.0",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"image-webpack-loader": "^7.0.1",
|
||||
|
@ -59,6 +61,7 @@
|
|||
"prerender-spa-plugin": "^3.0.0-beta.2",
|
||||
"sass-loader": "^10.0.3",
|
||||
"sharp": "^0.26.1",
|
||||
"ts-loader": "^8.0.12",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.1.3",
|
||||
"vue-loader": "^15.2.4",
|
||||
|
|
57
src/App.vue
57
src/App.vue
|
@ -4,34 +4,39 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'app',
|
||||
props: ["language"],
|
||||
};
|
||||
<script lang="ts">
|
||||
import Vue, {PropType} from "vue";
|
||||
import {Language} from "./types";
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'app',
|
||||
props: {
|
||||
language: String as PropType<Language>
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../node_modules/normalize.css/normalize";
|
||||
@import "variables";
|
||||
@import "../node_modules/milligram/src/Color";
|
||||
@import "../node_modules/milligram/src/Vars";
|
||||
@import "../node_modules/milligram/src/Base";
|
||||
@import "../node_modules/milligram/src/Blockquote";
|
||||
@import "../node_modules/milligram/src/Blocks";
|
||||
/*@import "../node_modules/milligram/src/Button";*/
|
||||
@import "../node_modules/milligram/src/Code";
|
||||
@import "../node_modules/milligram/src/Divider";
|
||||
@import "../node_modules/milligram/src/Form";
|
||||
@import "../node_modules/milligram/src/Grid";
|
||||
@import "../node_modules/milligram/src/Images";
|
||||
@import "../node_modules/milligram/src/Label";
|
||||
@import "../node_modules/milligram/src/Link";
|
||||
@import "../node_modules/milligram/src/List";
|
||||
@import "../node_modules/milligram/src/Navbar";
|
||||
@import "../node_modules/milligram/src/Spacing";
|
||||
@import "../node_modules/milligram/src/Table";
|
||||
@import "../node_modules/milligram/src/Typography";
|
||||
@import "../node_modules/milligram/src/Utility";
|
||||
@import "../node_modules/normalize.css/normalize";
|
||||
@import "variables";
|
||||
@import "../node_modules/milligram/src/Color";
|
||||
@import "../node_modules/milligram/src/Vars";
|
||||
@import "../node_modules/milligram/src/Base";
|
||||
@import "../node_modules/milligram/src/Blockquote";
|
||||
@import "../node_modules/milligram/src/Blocks";
|
||||
/*@import "../node_modules/milligram/src/Button";*/
|
||||
@import "../node_modules/milligram/src/Code";
|
||||
@import "../node_modules/milligram/src/Divider";
|
||||
@import "../node_modules/milligram/src/Form";
|
||||
@import "../node_modules/milligram/src/Grid";
|
||||
@import "../node_modules/milligram/src/Images";
|
||||
@import "../node_modules/milligram/src/Label";
|
||||
@import "../node_modules/milligram/src/Link";
|
||||
@import "../node_modules/milligram/src/List";
|
||||
@import "../node_modules/milligram/src/Navbar";
|
||||
@import "../node_modules/milligram/src/Spacing";
|
||||
@import "../node_modules/milligram/src/Table";
|
||||
@import "../node_modules/milligram/src/Typography";
|
||||
@import "../node_modules/milligram/src/Utility";
|
||||
|
||||
</style>
|
||||
|
|
122
src/Contact.vue
122
src/Contact.vue
|
@ -85,7 +85,8 @@
|
|||
<path d="M2807-894.7v-10.6l-8 5.3z" fill="transparent"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<a rel="me noopener" href="https://git.lw1.at/lw1" target="_blank" :aria-label="gitlabText" data-balloon-pos="up">
|
||||
<a rel="me noopener" href="https://git.lw1.at/lw1" target="_blank" :aria-label="gitlabText"
|
||||
data-balloon-pos="up">
|
||||
<!-- License - http://fontawesome.io/license (SIL OFL 1.1) -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54">
|
||||
<title>{{gitlabText}}</title>
|
||||
|
@ -123,69 +124,74 @@
|
|||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "contact",
|
||||
props: ["language"],
|
||||
computed: {
|
||||
english() {
|
||||
return this.language === "en"
|
||||
},
|
||||
githubText() {
|
||||
return this.english ? "view my code on GitHub" : "Schau meinen Code auf GitHub an"
|
||||
},
|
||||
keybaseText() {
|
||||
return this.english ? "View Profile on Keybase.io" : "Profil auf Keybase.io"
|
||||
},
|
||||
mastodonText() {
|
||||
return this.english ? "Follow me on Mastodon" : "Folg mir bei Mastodon"
|
||||
},
|
||||
twitterText() {
|
||||
return this.english ? "Follow me on Twitter" : "Folg mir bei Twitter"
|
||||
},
|
||||
matrixText() {
|
||||
return this.english ? "Contact me via matrix.org (riot.im)" : "Kontaktiere mich über matrix.org (riot.im)"
|
||||
},
|
||||
nextcloudText() {
|
||||
return this.english ? "share files with me via Nextcloud" : "Teile Dateien mit mir über Nextcloud"
|
||||
},
|
||||
peertubeText() {
|
||||
return this.english ? "view my videos on PeerTube" : "Schaue meine Videos auf PeerTube an"
|
||||
},
|
||||
gitlabText() {
|
||||
return this.english ? "view my code on GitLab" : "Schaue meinen Code auf GitLab an"
|
||||
},
|
||||
guidesText() {
|
||||
return this.english ? "view my guides" : "Lies meine Anleitungen"
|
||||
},
|
||||
emailText() {
|
||||
return this.english ? "write me an E-Mail (hi@lw1.at)" : "Schreib mir eine E-Mail (hi@lw1.at)"
|
||||
},
|
||||
<script lang="ts">
|
||||
import Vue, {PropType} from "vue";
|
||||
import {Language} from "./types";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "contact",
|
||||
props: {
|
||||
language: String as PropType<Language>
|
||||
},
|
||||
computed: {
|
||||
english(): boolean {
|
||||
return this.language === "en";
|
||||
},
|
||||
};
|
||||
githubText(): string {
|
||||
return this.english ? "view my code on GitHub" : "Schau meinen Code auf GitHub an";
|
||||
},
|
||||
keybaseText(): string {
|
||||
return this.english ? "View Profile on Keybase.io" : "Profil auf Keybase.io";
|
||||
},
|
||||
mastodonText(): string {
|
||||
return this.english ? "Follow me on Mastodon" : "Folg mir bei Mastodon";
|
||||
},
|
||||
twitterText(): string {
|
||||
return this.english ? "Follow me on Twitter" : "Folg mir bei Twitter";
|
||||
},
|
||||
matrixText(): string {
|
||||
return this.english ? "Contact me via matrix.org (riot.im)" : "Kontaktiere mich über matrix.org (riot.im)";
|
||||
},
|
||||
nextcloudText(): string {
|
||||
return this.english ? "share files with me via Nextcloud" : "Teile Dateien mit mir über Nextcloud";
|
||||
},
|
||||
peertubeText(): string {
|
||||
return this.english ? "view my videos on PeerTube" : "Schaue meine Videos auf PeerTube an";
|
||||
},
|
||||
gitlabText(): string {
|
||||
return this.english ? "view my code on GitLab" : "Schaue meinen Code auf GitLab an";
|
||||
},
|
||||
guidesText(): string {
|
||||
return this.english ? "view my guides" : "Lies meine Anleitungen";
|
||||
},
|
||||
emailText(): string {
|
||||
return this.english ? "write me an E-Mail (hi@lw1.at)" : "Schreib mir eine E-Mail (hi@lw1.at)";
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "variables";
|
||||
@import "variables";
|
||||
|
||||
.contact {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
.contact {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
svg {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
color: $consoleBackground;
|
||||
transition: color .2s;
|
||||
padding: 5px;
|
||||
svg {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
color: $consoleBackground;
|
||||
transition: color .2s;
|
||||
padding: 5px;
|
||||
|
||||
&.keybase .line {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
a:hover svg {
|
||||
outline: 1px solid $consoleBackground;
|
||||
}
|
||||
&.keybase .line {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
a:hover svg {
|
||||
outline: 1px solid $consoleBackground;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,43 +5,56 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {decode, isBlurhashValid} from "blurhash";
|
||||
<script lang="ts">
|
||||
|
||||
export default {
|
||||
name: "HashImage",
|
||||
props: ["img", "small"],
|
||||
mounted() {
|
||||
if (isBlurhashValid(this.img.hash).result) {
|
||||
const canvas = this.$refs.myCanvas;
|
||||
const pixels = decode(this.img.hash, 30, 15);
|
||||
import Vue, {PropType} from "vue";
|
||||
import {decode, isBlurhashValid} from "blurhash";
|
||||
import {ImageObject} from "./types";
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
const imageData = new ImageData(pixels, 30, 15);
|
||||
ctx.scale(10, 10);
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
ctx.drawImage(canvas, 0, 0);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
height() {
|
||||
return this.small ? 150 : 600;
|
||||
},
|
||||
width() {
|
||||
return this.small ? 300 : 1200;
|
||||
},
|
||||
absolutePath() {
|
||||
return "/" + this.img.path;
|
||||
}
|
||||
export default Vue.extend({
|
||||
name: "HashImage",
|
||||
props: {
|
||||
small: Boolean,
|
||||
img: Object as PropType<ImageObject>
|
||||
},
|
||||
mounted(): void {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const that = this as any;
|
||||
const img = that.img as ImageObject;
|
||||
const hash: string = img.hash;
|
||||
if (isBlurhashValid(hash).result) {
|
||||
const canvas = that.$refs.myCanvas;
|
||||
const pixels = decode(hash, 30, 15);
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
const imageData = new ImageData(pixels, 30, 15);
|
||||
ctx.scale(10, 10);
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
ctx.drawImage(canvas, 0, 0);
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
height() {
|
||||
return this.small ? 150 : 600;
|
||||
},
|
||||
width() {
|
||||
return this.small ? 300 : 1200;
|
||||
},
|
||||
absolutePath() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const that = this as any;
|
||||
const img = that.img as ImageObject;
|
||||
return "/" + img.path;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<div id="imprint">
|
||||
<div class="backButton">
|
||||
<router-link :to="{ name: 'Overview', params: { language: language }}">
|
||||
<span class="arrow">←</span> {{language==="de" ? "Zurück zur Hauptseite":"Back to the main page"}}
|
||||
<span class="arrow">←</span> {{ language === "de" ? "Zurück zur Hauptseite" : "Back to the main page" }}
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="languageSelector">
|
||||
<router-link :to="{ name: (language==='de' ? 'Imprint':'Impressum')}" rel="alternate"
|
||||
:hreflang="language==='de' ? 'en':'de'">
|
||||
{{language==="de" ? "English":"Deutsch"}}
|
||||
{{ language === "de" ? "English" : "Deutsch" }}
|
||||
</router-link>
|
||||
</div>
|
||||
<h1 v-if="language==='de'">Impressum</h1>
|
||||
|
@ -282,22 +282,27 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "imprint",
|
||||
props: ["language"]
|
||||
};
|
||||
<script lang="ts">
|
||||
import Vue, {PropType} from "vue";
|
||||
import {Language} from "./types";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "imprint",
|
||||
props: {
|
||||
language: String as PropType<Language>
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#imprint {
|
||||
.mainText {
|
||||
text-align: left;
|
||||
}
|
||||
#imprint {
|
||||
.mainText {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
188
src/Intro.vue
188
src/Intro.vue
|
@ -16,110 +16,114 @@
|
|||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "intro",
|
||||
props: ["language"],
|
||||
};
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "intro",
|
||||
props: ["language"],
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "variables";
|
||||
$liberapay: #f6c915;
|
||||
$bitcoin: #f7931a;
|
||||
$flattr: #595959;
|
||||
@import "variables";
|
||||
|
||||
.donate-buttons {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
$liberapay: #f6c915;
|
||||
$bitcoin: #f7931a;
|
||||
$flattr: #595959;
|
||||
|
||||
a {
|
||||
margin: 0 16px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
.donate-buttons {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
img, svg {
|
||||
border-radius: 5px;
|
||||
height: 100%;
|
||||
transition: .2s;
|
||||
}
|
||||
a {
|
||||
margin: 0 16px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
|
||||
&:hover img {
|
||||
filter: brightness(1.3);
|
||||
}
|
||||
|
||||
&:not(.image) {
|
||||
padding: 4px 6px;
|
||||
text-decoration: none;
|
||||
transition: .2s;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
svg, span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.liberapay-btn {
|
||||
background-color: $liberapay;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($liberapay, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.bitcoin {
|
||||
background-color: $bitcoin;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($bitcoin, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.flattr {
|
||||
background-color: $flattr;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($flattr, 10%);
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: white;
|
||||
height: 15px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
img, svg {
|
||||
border-radius: 5px;
|
||||
height: 100%;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.introduction {
|
||||
text-align: left;
|
||||
margin-bottom: 10px;
|
||||
padding: 0 10px;
|
||||
&:hover img {
|
||||
filter: brightness(1.3);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: $consoleFont;
|
||||
color: black !important;
|
||||
div {
|
||||
font-size: 24px;
|
||||
line-height: 28px;
|
||||
}
|
||||
&:not(.image) {
|
||||
padding: 4px 6px;
|
||||
text-decoration: none;
|
||||
transition: .2s;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
h1 {
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
|
||||
}
|
||||
.languageSelector {
|
||||
right: 10px;
|
||||
}
|
||||
svg, span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.liberapay-btn {
|
||||
background-color: $liberapay;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($liberapay, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.bitcoin {
|
||||
background-color: $bitcoin;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($bitcoin, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.flattr {
|
||||
background-color: $flattr;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($flattr, 10%);
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: white;
|
||||
height: 15px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.introduction {
|
||||
text-align: left;
|
||||
margin-bottom: 10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: $consoleFont;
|
||||
color: black !important;
|
||||
|
||||
div {
|
||||
font-size: 24px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
h1 {
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
|
||||
}
|
||||
.languageSelector {
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
<div class="modal-body" ref="test">
|
||||
<h1>{{ translate(element.title) }}
|
||||
<div v-if="element.subtitle">{{translate(element.subtitle)}}</div>
|
||||
<div v-if="element.subtitle">{{ translate(element.subtitle) }}</div>
|
||||
</h1>
|
||||
<div :class="{'modal-linkbar':true, try:element.try}">
|
||||
<a v-bind:href="element.url" v-if="element.url" target="_blank">
|
||||
|
@ -26,7 +26,7 @@
|
|||
<path d="M54.22083 161.88751C75.49125 69.74037 157.61638.879 255.99447-.0344V71.2784c-58.68038.82679-108.44983 38.32148-127.51646 90.6032H54.22378z"></path>
|
||||
<path d="M183.32848 154.61394L93.60991 255.96317-.0104 154.45508"></path>
|
||||
</svg>
|
||||
<span>{{language==="de" ? "Ausprobieren": "Try it out!"}}</span>
|
||||
<span>{{ language === "de" ? "Ausprobieren" : "Try it out!" }}</span>
|
||||
</div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420 420">
|
||||
<title>Website</title>
|
||||
|
@ -98,255 +98,268 @@
|
|||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LicenseIcons from "./LicenseIcons.vue";
|
||||
import HashImage from "./HashImage.vue";
|
||||
<script lang="ts">
|
||||
import LicenseIcons from "./LicenseIcons.vue";
|
||||
import HashImage from "./HashImage.vue";
|
||||
import Vue, {PropType} from "vue";
|
||||
import {Article, Language, translatableString} from "./types";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: null,
|
||||
element: null,
|
||||
sentReadmore: false
|
||||
};
|
||||
},
|
||||
props: ['language', 'data'],
|
||||
mounted() {
|
||||
document.body.style.overflow = "hidden";
|
||||
this.id = this.$route.params.id;
|
||||
this.element = this.data.find(elem => elem.id === this.id);
|
||||
if (!this.element) {
|
||||
this.$router.replace("/");
|
||||
return false;
|
||||
}
|
||||
document.title = this.translate(this.element.title) + " - lw1.at";
|
||||
this.$nextTick(function() {
|
||||
_paq.push(['setDocumentTitle', document.title]);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
});
|
||||
this.$refs.container.focus();
|
||||
},
|
||||
methods: {
|
||||
translate: function(value) {
|
||||
if (typeof value === "object") {
|
||||
return value[this.language];
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
},
|
||||
readmore: function() {
|
||||
this.sentReadmore = true;
|
||||
if (typeof _paq != "undefined") {
|
||||
_paq.push(['trackEvent', 'Feedback', 'readmore', this.id]);
|
||||
} else {
|
||||
console.info("Feedback not sent as Matomo isn't loaded");
|
||||
}
|
||||
}
|
||||
},
|
||||
head: {
|
||||
title: function() {
|
||||
if (this.element) {
|
||||
return {inner: this.translate(this.element.title)};
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
HashImage,
|
||||
LicenseIcons
|
||||
export default Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
title: "",
|
||||
element: undefined as Article | undefined,
|
||||
sentReadmore: false as boolean,
|
||||
id: ""
|
||||
};
|
||||
},
|
||||
props: {
|
||||
language: String as PropType<Language>,
|
||||
data: Array as PropType<Article[]>
|
||||
},
|
||||
|
||||
mounted() {
|
||||
document.body.style.overflow = "hidden";
|
||||
this.id = this.$route.params.id;
|
||||
|
||||
this.element = this.data.find(elem => elem.id === this.id);
|
||||
if (!this.element) {
|
||||
this.$router.replace("/");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
document.title = this.translate(this.element.title) + " - lw1.at";
|
||||
|
||||
this.$nextTick(function () {
|
||||
const _paq = window._paq;
|
||||
_paq.push(['setDocumentTitle', document.title]);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
});
|
||||
const container=this.$refs.container as HTMLDivElement;
|
||||
container.focus();
|
||||
},
|
||||
methods: {
|
||||
translate: function (value: translatableString): string {
|
||||
if (typeof value === "object") {
|
||||
return value[this.language];
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
},
|
||||
readmore: function (): void {
|
||||
this.sentReadmore = true;
|
||||
if (typeof window._paq != "undefined") {
|
||||
window._paq.push(['trackEvent', 'Feedback', 'readmore', this.id]);
|
||||
} else {
|
||||
console.info("Feedback not sent as Matomo isn't loaded");
|
||||
}
|
||||
}
|
||||
},
|
||||
// head: {
|
||||
// title: function (): string {
|
||||
// if (this.element) {
|
||||
// return {inner: this.translate(this.element.title)};
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
components: {
|
||||
HashImage,
|
||||
LicenseIcons
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "variables";
|
||||
@import "variables";
|
||||
|
||||
.closeButton {
|
||||
position: absolute;
|
||||
font-size: 22px;
|
||||
line-height: 22px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
.closeButton {
|
||||
position: absolute;
|
||||
font-size: 22px;
|
||||
line-height: 22px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
color: $color-primary;
|
||||
z-index: 2000;
|
||||
|
||||
&:hover {
|
||||
color: darkgrey;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 0 20px;
|
||||
@media (max-width: 40.0rem) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
z-index: 1000;
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
position: relative;
|
||||
max-width: 1000px;
|
||||
/*
|
||||
@media (max-width: 40.0rem) {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
*/
|
||||
margin: 50px auto 0;
|
||||
background-color: #fff;
|
||||
border-radius: $borderRadius;
|
||||
|
||||
.imagewrapper {
|
||||
padding-bottom: 50%;
|
||||
|
||||
&.seperator {
|
||||
border-bottom: solid 1px #ddd;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-top-left-radius: $borderRadius;
|
||||
border-top-right-radius: $borderRadius;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1100;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-header h3 {
|
||||
margin-top: 0;
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 20px 30px;
|
||||
margin: 20px 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.modal-default-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following styles are auto-applied to elements with
|
||||
* transition="modal" when their visibility is toggled
|
||||
* by Vue.js.
|
||||
*
|
||||
* You can easily play with the modal transition by editing
|
||||
* these styles.
|
||||
*/
|
||||
|
||||
.modal-enter {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/*.modal-enter .modal-container,*/
|
||||
/*.modal-leave-active .modal-container {*/
|
||||
/*transform: scale(0.8);*/
|
||||
/*}*/
|
||||
|
||||
.modal-linkbar {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
&.try {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
padding: 16px;
|
||||
|
||||
> svg {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: block;
|
||||
color: black;
|
||||
}
|
||||
|
||||
svg, span {
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
color: $color-primary;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: darkgrey;
|
||||
}
|
||||
.try-it-out {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 0 20px;
|
||||
@media (max-width: 40.0rem) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
z-index: 1000;
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
.try-it-out {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 23px;
|
||||
right: -150px;
|
||||
vertical-align: top;
|
||||
color: black;
|
||||
|
||||
.modal-container {
|
||||
svg {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
max-width: 1000px;
|
||||
/*
|
||||
@media (max-width: 40.0rem) {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
*/
|
||||
margin: 50px auto 0;
|
||||
background-color: #fff;
|
||||
border-radius: $borderRadius;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
.imagewrapper {
|
||||
padding-bottom: 50%;
|
||||
span {
|
||||
|
||||
&.seperator {
|
||||
border-bottom: solid 1px #ddd;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-top-left-radius: $borderRadius;
|
||||
border-top-right-radius: $borderRadius;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1100;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-header h3 {
|
||||
margin-top: 0;
|
||||
color: #42b983;
|
||||
}
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border: none;
|
||||
border-radius: $borderRadius;
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 20px 30px;
|
||||
margin: 20px 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.modal-default-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following styles are auto-applied to elements with
|
||||
* transition="modal" when their visibility is toggled
|
||||
* by Vue.js.
|
||||
*
|
||||
* You can easily play with the modal transition by editing
|
||||
* these styles.
|
||||
*/
|
||||
|
||||
.modal-enter {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/*.modal-enter .modal-container,*/
|
||||
/*.modal-leave-active .modal-container {*/
|
||||
/*transform: scale(0.8);*/
|
||||
/*}*/
|
||||
|
||||
.modal-linkbar {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
&.try {
|
||||
margin-top: 40px;
|
||||
}
|
||||
a {
|
||||
position: relative;
|
||||
padding: 16px;
|
||||
|
||||
> svg {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: block;
|
||||
color: black;
|
||||
}
|
||||
|
||||
svg, span {
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
.try-it-out {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.try-it-out {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 23px;
|
||||
right: -150px;
|
||||
vertical-align: top;
|
||||
color: black;
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
span {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border: none;
|
||||
border-radius: $borderRadius;
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.note {
|
||||
background-color: $consoleBackground;
|
||||
color: $consoleOrange;
|
||||
font-family: $consoleFont;
|
||||
text-align: center;
|
||||
/*background-color: #fdbc4b;*/
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.note {
|
||||
background-color: $consoleBackground;
|
||||
color: $consoleOrange;
|
||||
font-family: $consoleFont;
|
||||
text-align: center;
|
||||
/*background-color: #fdbc4b;*/
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -21,39 +21,41 @@
|
|||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "license-icons",
|
||||
props: ["id", "url"]
|
||||
};
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "license-icons",
|
||||
props: ["id", "url"]
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
svg {
|
||||
color: black;
|
||||
svg {
|
||||
color: black;
|
||||
|
||||
path {
|
||||
fill: white;
|
||||
stroke: currentColor;
|
||||
stroke-width: 15.349;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
path {
|
||||
fill: white;
|
||||
stroke: currentColor;
|
||||
stroke-width: 15.349;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
text {
|
||||
font-family: Arial, sans-serif;
|
||||
fill: currentColor;
|
||||
text-align: start;
|
||||
line-height: 125%;
|
||||
font-weight: 700;
|
||||
font-size: 124.104px
|
||||
}
|
||||
}
|
||||
text {
|
||||
font-family: Arial, sans-serif;
|
||||
fill: currentColor;
|
||||
text-align: start;
|
||||
line-height: 125%;
|
||||
font-weight: 700;
|
||||
font-size: 124.104px
|
||||
}
|
||||
}
|
||||
|
||||
.MIT text {
|
||||
font-size: 124.104px;
|
||||
}
|
||||
.MIT text {
|
||||
font-size: 124.104px;
|
||||
}
|
||||
|
||||
.GPL text {
|
||||
font-size: 109.871px;
|
||||
}
|
||||
.GPL text {
|
||||
font-size: 109.871px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export default class MatomoTracker {
|
||||
init() {
|
||||
if (typeof _paq === 'undefined' && !window.__PRERENDER_INJECTED) { // should only occur with hot reloading
|
||||
let _paq = window._paq || [];
|
||||
init(): void {
|
||||
if (!window.__PRERENDER_INJECTED) { // should only occur with hot reloading
|
||||
const _paq = window._paq || [];
|
||||
_paq.push(['setRequestMethod', 'POST']);
|
||||
_paq.push(['enableHeartBeatTimer']);
|
||||
|
||||
|
@ -9,16 +9,18 @@ export default class MatomoTracker {
|
|||
_paq.push(["setDoNotTrack", true]);
|
||||
}
|
||||
_paq.push(['disableCookies']);
|
||||
(function() {
|
||||
let u = (process.env.NODE_ENV === "production") ? "https://matomo.lw1.at/" : "//localhost/piwik/";
|
||||
(function () {
|
||||
const u = (process.env.NODE_ENV === "production") ? "https://matomo.lw1.at/" : "//localhost/piwik/";
|
||||
_paq.push(['setTrackerUrl', u + ((process.env.NODE_ENV === "production") ? 'statistics.php' : 'piwik.php')]);
|
||||
_paq.push(['setSiteId', (process.env.NODE_ENV === "production") ? 14 : 5]);
|
||||
let d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||
const d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||
g.type = 'text/javascript';
|
||||
g.async = true;
|
||||
g.defer = true;
|
||||
g.src = u + ((process.env.NODE_ENV === "production") ? 'statistics.js' : 'piwik.js');
|
||||
s.parentNode.insertBefore(g, s);
|
||||
if (s.parentNode) {
|
||||
s.parentNode.insertBefore(g, s);
|
||||
}
|
||||
})();
|
||||
window._paq = _paq;
|
||||
} else {
|
||||
|
@ -26,3 +28,12 @@ export default class MatomoTracker {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_paq: paq;
|
||||
__PRERENDER_INJECTED: boolean
|
||||
}
|
||||
}
|
||||
|
||||
declare type paq = [[unknown, unknown, unknown, unknown] | [unknown, unknown, unknown] | [unknown, unknown] | [unknown]]
|
539
src/Overview.vue
539
src/Overview.vue
|
@ -3,7 +3,7 @@
|
|||
<div class="languageSelector">
|
||||
<router-link :to="{ name: 'Overview', params: { language: otherLanguage }}"
|
||||
rel="alternate" :hreflang="otherLanguage">
|
||||
{{language==="de" ? "English":"Deutsch"}}
|
||||
{{ language === "de" ? "English" : "Deutsch" }}
|
||||
</router-link>
|
||||
</div>
|
||||
<intro :language="language"></intro>
|
||||
|
@ -11,19 +11,19 @@
|
|||
<div id="filterwrapper">
|
||||
<button class="button-outline" @click="filter=false;search=''"
|
||||
:class="filter ? '' : 'active'">
|
||||
{{language==="de"?"Alle Projekte":"All Projects"}}
|
||||
{{ language === "de" ? "Alle Projekte" : "All Projects" }}
|
||||
</button>
|
||||
<button v-for="(tag, key, index) in filterTags"
|
||||
<button v-for="(tag, key, index) in filterTags" :key="key"
|
||||
:class="['button-outline',(filter === key)?'active':'']"
|
||||
@click="filter=key">
|
||||
{{translate(tag.name)}}
|
||||
{{ translate(tag.name) }}
|
||||
</button>
|
||||
</div>
|
||||
<div id="searchwrapper">
|
||||
<input title="test" v-model="search" :placeholder="language==='de'?'Suchen...':'Search...'"/>
|
||||
</div>
|
||||
<div v-if="noResults" id="noresults">
|
||||
{{language==="de"?"Keine Ergebnisse":"No results"}}!
|
||||
{{ language === "de" ? "Keine Ergebnisse" : "No results" }}!
|
||||
</div>
|
||||
<div id="blockwrapper">
|
||||
<router-link v-for="element in elements" :key="element.id" class="card"
|
||||
|
@ -39,8 +39,8 @@
|
|||
{{ formatDate(element.date) }}
|
||||
</div>
|
||||
<div class="tagwrapper">
|
||||
<div class="tag"
|
||||
v-for="tag in element.tags">{{translate(tags[tag].name)}}
|
||||
<div class="tag" :key="tag"
|
||||
v-for="tag in element.tags">{{ translate(tags[tag].name) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -48,11 +48,12 @@
|
|||
</router-link>
|
||||
</div>
|
||||
<router-link class="toImprint" :to="{ name: (language==='de' ? 'Impressum':'Imprint')}">
|
||||
{{language==="de" ? "Impressum":"Imprint"}}
|
||||
{{ language === "de" ? "Impressum" : "Imprint" }}
|
||||
</router-link>
|
||||
<a href="https://keyoxide.org/63DB263BACE368B5C5F79CE494AFBE7C2656A5B5" class="gpg" target="_blank" rel="noopener">
|
||||
GPG: 63DB 263B ACE3 68B5 C5F7 9CE4 94AF BE7C 2656 A5B5
|
||||
</a>
|
||||
<a href="https://keyoxide.org/63DB263BACE368B5C5F79CE494AFBE7C2656A5B5" class="gpg" target="_blank"
|
||||
rel="noopener">
|
||||
GPG: 63DB 263B ACE3 68B5 C5F7 9CE4 94AF BE7C 2656 A5B5
|
||||
</a>
|
||||
<router-link :to="{ name: 'itemModal',params:{id:'classiccounter'} }"><img
|
||||
src="https://matomo.lw1.at/index.php?module=ClassicCounter&action=svg&idSite=14"
|
||||
alt="Matomo visit counter"
|
||||
|
@ -64,286 +65,298 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Intro from "./Intro.vue";
|
||||
import Contact from "./Contact.vue";
|
||||
import HashImage from "./HashImage.vue";
|
||||
<script lang="ts">
|
||||
import Intro from "./Intro.vue";
|
||||
import Contact from "./Contact.vue";
|
||||
import HashImage from "./HashImage.vue";
|
||||
import Vue, {PropType} from "vue";
|
||||
import {Article, Language, Tags, translatableString, YamlImport} from "./types";
|
||||
|
||||
const yaml = require('./tags.yaml');
|
||||
yaml.data.forEach((part, index, array) => {
|
||||
part.dateObj = new Date(part.date);
|
||||
array[index] = part;
|
||||
});
|
||||
const data = yaml.data;
|
||||
const tags = yaml.tags;
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const yaml: YamlImport = require('./tags.yaml');
|
||||
yaml.data.forEach((part, index, array) => {
|
||||
part.dateObj = new Date(part.date);
|
||||
array[index] = part;
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {Intro, Contact, HashImage},
|
||||
name: 'overview',
|
||||
data() {
|
||||
return {
|
||||
data: data,
|
||||
tags: tags,
|
||||
filter: false,
|
||||
search: "",
|
||||
noResults: false
|
||||
};
|
||||
const data = yaml.data;
|
||||
const tags = yaml.tags;
|
||||
|
||||
export default Vue.extend({
|
||||
components: {Intro, Contact, HashImage},
|
||||
name: 'overview',
|
||||
data() {
|
||||
return {
|
||||
data: data,
|
||||
tags: tags as Tags,
|
||||
filter: "",
|
||||
search: "",
|
||||
noResults: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
language: String as PropType<Language>
|
||||
},
|
||||
computed: {
|
||||
elements(): Article[] {
|
||||
let filtered = this.data.filter(item => {
|
||||
return this.filterContains(item) && this.filterSearch(item);
|
||||
});
|
||||
if (filtered.length === 0) {
|
||||
filtered = this.data;
|
||||
this.noResults = true;
|
||||
} else {
|
||||
this.noResults = false;
|
||||
}
|
||||
return filtered.sort((a, b) => {
|
||||
return b.dateObj.valueOf() - a.dateObj.valueOf();
|
||||
});
|
||||
},
|
||||
props: ["language"],
|
||||
computed: {
|
||||
elements() {
|
||||
let filtered = this.data.filter(item => {
|
||||
return this.filterContains(item) && this.filterSearch(item);
|
||||
});
|
||||
if (filtered.length === 0) {
|
||||
filtered = this.data;
|
||||
this.noResults = true;
|
||||
} else {
|
||||
this.noResults = false;
|
||||
}
|
||||
return filtered.sort((a, b) => {
|
||||
return b.dateObj - a.dateObj;
|
||||
});
|
||||
},
|
||||
filterTags() {
|
||||
return Object.keys(this.tags).reduce((filtered, key) => {
|
||||
if (!this.tags[key].hidden) {
|