Configure automatic linting (#83)

* Configure automatic linting

* Remove FontAwesome icons

* Ignore mismatching component name
This commit is contained in:
arkon 2020-01-08 23:15:44 -05:00 committed by Simon M
parent cf40ac73ad
commit f3f186cef0
12 changed files with 1325 additions and 181 deletions

22
.eslintrc.json Normal file
View File

@ -0,0 +1,22 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"plugin:vue/essential",
"vuepress",
"prettier"
],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"vue",
"prettier"
],
"rules": {
"prettier/prettier": ["error"]
}
}

1134
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,8 @@
"name": "tachiyomi-website", "name": "tachiyomi-website",
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"build": "vuepress build src", "build": "npm run lint && vuepress build src",
"lint": "eslint --fix src/.vuepress/**/*.{js,vue} --no-ignore",
"serve": "vuepress dev src" "serve": "vuepress dev src"
}, },
"repository": { "repository": {
@ -13,7 +14,13 @@
"devDependencies": { "devDependencies": {
"@vuepress/plugin-back-to-top": "^1.2.0", "@vuepress/plugin-back-to-top": "^1.2.0",
"@vuepress/plugin-google-analytics": "^1.2.0", "@vuepress/plugin-google-analytics": "^1.2.0",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-prettier": "^6.9.0",
"eslint-config-vuepress": "^2.1.0",
"eslint-plugin-prettier": "^3.1.2",
"node-sass": "^4.13.0", "node-sass": "^4.13.0",
"prettier": "^1.19.1",
"sass-loader": "^8.0.0", "sass-loader": "^8.0.0",
"vue-agile": "^1.0.11", "vue-agile": "^1.0.11",
"vuepress": "^1.2.0", "vuepress": "^1.2.0",
@ -21,11 +28,8 @@
"vuepress-plugin-container": "^2.1.2" "vuepress-plugin-container": "^2.1.2"
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/vue-fontawesome": "^0.1.9",
"@mdi/font": "^4.7.95", "@mdi/font": "^4.7.95",
"axios": "^0.19.0", "axios": "^0.19.1",
"iso-639-1": "^2.1.0", "iso-639-1": "^2.1.0",
"lodash.groupby": "^4.6.0", "lodash.groupby": "^4.6.0",
"lodash.sortby": "^4.7.0", "lodash.sortby": "^4.7.0",

View File

@ -1,18 +1,18 @@
<template> <template>
<agile :options="config" :id="name"> <Agile :id="name" :options="config">
<slot /> <slot />
<template slot="prevButton"> <template slot="prevButton">
<MaterialIcon iconName="navigate_next" /> <MaterialIcon icon-name="navigate_next" />
</template> </template>
<template slot="nextButton"> <template slot="nextButton">
<MaterialIcon iconName="navigate_next" /> <MaterialIcon icon-name="navigate_next" />
</template> </template>
</agile> </Agile>
</template> </template>
<script> <script>
export default { export default {
name: "carousel", name: "Carousel",
props: { props: {
name: { name: {
type: String, type: String,
@ -20,25 +20,25 @@ export default {
}, },
config: { config: {
type: Object, type: Object,
default: function () { default: function() {
return { return {
navButtons: true, navButtons: true,
centerMode: true centerMode: true
} };
} }
} }
} }
} };
</script> </script>
<style> <style>
.agile { .agile {
background: #F0F4F8; background: #f0f4f8;
border-radius: 1em; border-radius: 1em;
} }
.agile__nav-button { .agile__nav-button {
background: hsla(0,0%,100%,.75); background: hsla(0, 0%, 100%, 0.75);
border: none; border: none;
color: rgba(44, 62, 80); color: rgba(44, 62, 80);
cursor: pointer; cursor: pointer;
@ -47,13 +47,13 @@ export default {
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
position: absolute; position: absolute;
transition-duration: .3s; transition-duration: 0.3s;
width: 50px; width: 50px;
border-radius: 99em; border-radius: 99em;
} }
.agile__nav-button:hover { .agile__nav-button:hover {
background-color: rgba(0,0,0, .5); background-color: rgba(0, 0, 0, 0.5);
opacity: 1; opacity: 1;
} }
@ -62,7 +62,7 @@ export default {
} }
.agile__nav-button--prev i { .agile__nav-button--prev i {
transform: rotateZ(180deg) transform: rotateZ(180deg);
} }
.agile__nav-button--next { .agile__nav-button--next {
@ -81,8 +81,8 @@ export default {
} }
.agile__dot button { .agile__dot button {
background-color: hsla(0,0%,100%,.75); background-color: hsla(0, 0%, 100%, 0.75);
border: 1px solid hsla(0,0%,100%,.75); border: 1px solid hsla(0, 0%, 100%, 0.75);
border-radius: 50%; border-radius: 50%;
cursor: pointer; cursor: pointer;
display: block; display: block;
@ -91,7 +91,7 @@ export default {
line-height: 0; line-height: 0;
margin: 0; margin: 0;
padding: 0; padding: 0;
transition-duration: .3s; transition-duration: 0.3s;
width: 10px; width: 10px;
} }

View File

@ -1,19 +1,19 @@
<template> <template>
<div class="slide" :id="name"> <div :id="name" class="slide">
<slot /> <slot />
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: "carousel-item", name: "CarouselItem",
props: { props: {
name: { name: {
type: String, type: String,
default: "carousel-cell" default: "carousel-cell"
} }
} }
} };
</script> </script>
<style> <style>

View File

@ -1,21 +1,40 @@
<template> <template>
<ul class="no-select download-list"> <ul class="no-select download-list">
<li> <li>
<a class="download-link" rel="noopener noreferrer" :href="browserDownloadUrl || 'https://github.com/inorichi/tachiyomi/releases/latest'" :title="tagName" download> <a
class="download-link"
rel="noopener noreferrer"
:href="
browserDownloadUrl ||
'https://github.com/inorichi/tachiyomi/releases/latest'
"
:title="tagName"
download
>
<div class="download-button stable"> <div class="download-button stable">
<span class="download-area"> <span class="download-area">
<MaterialIcon name="download-get_app download-icons" icon-name="get_app"/> <MaterialIcon
<span class="download-text-stable download-text">Stable release</span> name="download-get_app download-icons"
icon-name="get_app"
/>
<span class="download-text-stable download-text"
>Stable release</span
>
</span> </span>
</div> </div>
</a> </a>
</lI> </li>
<li> <li>
<a class="download-link" href="http://tachiyomi.kanade.eu/latest"> <a class="download-link" href="http://tachiyomi.kanade.eu/latest">
<div class="download-button dev"> <div class="download-button dev">
<div class="download-area"> <div class="download-area">
<MaterialIcon name="download-bug_report download-icons" icon-name="bug_report"/> <MaterialIcon
<span class="download-text-dev download-text">Dev release</span> name="download-bug_report download-icons"
icon-name="bug_report"
/>
<span class="download-text-dev download-text"
>Dev release</span
>
</div> </div>
</div> </div>
</a> </a>
@ -25,19 +44,21 @@
<style scoped lang="scss"> <style scoped lang="scss">
* { * {
font-family: "Open Sans", Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-family: "Open Sans", Roboto, -apple-system, BlinkMacSystemFont,
"Segoe UI", Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans",
"Helvetica Neue", sans-serif;
} }
ul { ul {
width: 100%; width: 100%;
text-align: center; text-align: center;
margin: .625em 0 0 0; margin: 0.625em 0 0 0;
padding: 0; padding: 0;
} }
li { li {
display: inline-block; display: inline-block;
margin: .3125em .625em .3125em .625em; margin: 0.3125em 0.625em 0.3125em 0.625em;
} }
a.download-link { a.download-link {
@ -49,13 +70,13 @@ a.download-link {
cursor: pointer; cursor: pointer;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: #2E84BF; background-color: #2e84bf;
width: 11.25em; width: 11.25em;
height: 3.75em; height: 3.75em;
border-radius: .3125em; border-radius: 0.3125em;
padding: 0 1em 0 1em; padding: 0 1em 0 1em;
&.stable { &.stable {
background-color: #2E84BF; background-color: #2e84bf;
&:hover { &:hover {
filter: brightness(110%); filter: brightness(110%);
} }
@ -68,26 +89,26 @@ a.download-link {
} }
.download-area { .download-area {
font-size: 1.125em; font-size: 1.125em;
color: #FFFFFF; color: #ffffff;
display: flex; display: flex;
align-items: center; align-items: center;
.download-icons { .download-icons {
color: #FFFFFF; color: #ffffff;
max-width: 2em; max-width: 2em;
font-size: .875em; font-size: 0.875em;
} }
.download-get_app { .download-get_app {
margin-left: .188em; margin-left: 0.188em;
margin-right: .250em; margin-right: 0.25em;
} }
.download-bug_report { .download-bug_report {
margin-right: .250em; margin-right: 0.25em;
} }
.download-text-stable { .download-text-stable {
margin-right: .375em; margin-right: 0.375em;
} }
.download-text-dev { .download-text-dev {
margin-right: .063em; margin-right: 0.063em;
} }
} }
} }
@ -95,26 +116,26 @@ a.download-link {
</style> </style>
<script> <script>
import axios from 'axios'; import axios from "axios";
const RELEASE_URL = 'https://api.github.com/repos/inorichi/tachiyomi/releases/latest'; const RELEASE_URL =
"https://api.github.com/repos/inorichi/tachiyomi/releases/latest";
export default { export default {
data() {
data () {
return { return {
tagName: '', tagName: "",
browserDownloadUrl: '', browserDownloadUrl: ""
} };
}, },
async mounted () { async mounted() {
const { data } = await axios.get(RELEASE_URL); const { data } = await axios.get(RELEASE_URL);
// Maybe eventually some release has more than the apk in assets. // Maybe eventually some release has more than the apk in assets.
const apkAsset = data.assets.find(a => a.name.includes('.apk')); const apkAsset = data.assets.find(a => a.name.includes(".apk"));
// Set the values. // Set the values.
this.$data.tagName = data.tag_name; this.$data.tagName = data.tag_name;
this.$data.browserDownloadUrl = apkAsset.browser_download_url; this.$data.browserDownloadUrl = apkAsset.browser_download_url;
} }
} };
</script> </script>

View File

@ -2,18 +2,26 @@
<div> <div>
<div v-for="extensionGroup in extensions" :key="extensionGroup[0].lang"> <div v-for="extensionGroup in extensions" :key="extensionGroup[0].lang">
<h3>{{ langName(extensionGroup[0].lang) }}</h3> <h3>{{ langName(extensionGroup[0].lang) }}</h3>
<div <div
class="anchor" v-for="extension in extensionGroup"
v-for="extension in extensionGroup" :id="extension.name.split(': ')[1]"
:key="extension.apk" :key="extension.apk"
:id="extension.name.split(': ')[1]"> class="anchor"
>
<div class="extension"> <div class="extension">
<a :href="`#${extension.name.split(': ')[1]}`" aria-hidden="true" class="header-anchor"># </a> <a
<img :src="iconUrl(extension.apk)" width="42" height="42"> :href="`#${extension.name.split(': ')[1]}`"
aria-hidden="true"
class="header-anchor"
>#
</a>
<img :src="iconUrl(extension.apk)" width="42" height="42" />
<div class="extension-text"> <div class="extension-text">
<div class="upper"> <div class="upper">
<span class="bold">{{ extension.name.split(': ')[1] }}</span> <span class="bold">{{
<Badge :text="'v' + extension.version"/> extension.name.split(": ")[1]
}}</span>
<Badge :text="'v' + extension.version" />
</div> </div>
<div class="down"> <div class="down">
{{ extension.pkg }} {{ extension.pkg }}
@ -23,8 +31,9 @@
:href="apkUrl(extension.apk)" :href="apkUrl(extension.apk)"
class="button" class="button"
title="Download APK" title="Download APK"
download> download
<font-awesome-icon icon="download" /> >
<MaterialIcon icon-name="cloud_download" />
<span>Download</span> <span>Download</span>
</a> </a>
</div> </div>
@ -34,41 +43,46 @@
</template> </template>
<script> <script>
import axios from 'axios'; import axios from "axios";
import groupBy from 'lodash.groupby'; import groupBy from "lodash.groupby";
import sortBy from 'lodash.sortby'; import sortBy from "lodash.sortby";
import ISO6391 from 'iso-639-1'; import ISO6391 from "iso-639-1";
const EXTENSION_JSON = 'https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo/index.json'; const EXTENSION_JSON =
"https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo/index.json";
export default { export default {
data () { data() {
return { return {
extensions: [] extensions: []
};
},
async beforeMount() {
const { data } = await axios.get(EXTENSION_JSON);
const values = Object.values(groupBy(data, "lang"));
this.$data.extensions = sortBy(values, [g => this.langName(g[0].lang)]);
},
updated() {
if (location.hash) {
location.replace(location.hash);
} }
}, },
methods: { methods: {
langName: code => code === 'all' ? 'All' : `${ISO6391.getName(code)} (${ISO6391.getNativeName(code)})`, langName: code =>
iconUrl (pkg) { code === "all"
const pkgName = pkg.substring(0, pkg.lastIndexOf('.')); ? "All"
: `${ISO6391.getName(code)} (${ISO6391.getNativeName(code)})`,
iconUrl(pkg) {
const pkgName = pkg.substring(0, pkg.lastIndexOf("."));
return `https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo/icon/${pkgName}.png`; return `https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo/icon/${pkgName}.png`;
}, },
apkUrl: apk => `https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo/apk/${apk}` apkUrl: apk =>
}, `https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo/apk/${apk}`
async beforeMount () {
const { data } = await axios.get(EXTENSION_JSON);
const values = Object.values(groupBy(data, 'lang'));
this.$data.extensions = sortBy(values, [g => this.langName(g[0].lang)]);
},
updated () {
if (location.hash) {
location.replace(location.hash);
}
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">
@ -118,8 +132,12 @@ export default {
text-decoration: none !important; text-decoration: none !important;
} }
svg + span { .material-holder {
margin-left: 0.25rem; color: #fff;
+ span {
margin-left: 0.25rem;
}
} }
} }
} }
@ -127,7 +145,7 @@ export default {
.anchor { .anchor {
margin-top: -3.9em; margin-top: -3.9em;
padding-top: 3.9em; padding-top: 3.9em;
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid #eaecef; border-bottom: 1px solid #eaecef;
} }
@ -141,7 +159,8 @@ export default {
@media (max-width: 767px) { @media (max-width: 767px) {
.extension { .extension {
.extension-text .down, .button span { .extension-text .down,
.button span {
display: none; display: none;
} }
} }

View File

@ -1,18 +1,22 @@
<template> <template>
<div :class="name" class="material-holder"> <div :class="name" class="material-holder">
<i v-if="legacy" :class="iconName" class="material-legacy-icons mdi"></i> <i
v-if="legacy"
:class="iconName"
class="material-legacy-icons mdi"
></i>
<i v-else class="material-icons">{{ iconName }}</i> <i v-else class="material-icons">{{ iconName }}</i>
</div> </div>
</template> </template>
<script> <script>
/** /**
* For material icon references use https://material.io/resources/icons/ * For material icon references use https://material.io/resources/icons/
* Code example: <MaterialIcon icon-name="android" /> * Code example: <MaterialIcon icon-name="android" />
* *
* For material icon references use http://materialdesignicons.com/ * For material icon references use http://materialdesignicons.com/
* Code example: <MaterialIcon icon-name="mdi-glasses" legacy /> * Code example: <MaterialIcon icon-name="mdi-glasses" legacy />
*/ */
export default { export default {
props: { props: {
legacy: { legacy: {
@ -28,7 +32,7 @@ export default {
required: true required: true
} }
} }
} };
</script> </script>
<style scoped> <style scoped>
@ -41,7 +45,7 @@ export default {
} }
.material-icons { .material-icons {
font-family: 'Material Icons'; font-family: "Material Icons";
font-size: 1.35em; font-size: 1.35em;
font-style: normal; font-style: normal;
position: relative; position: relative;
@ -54,12 +58,12 @@ export default {
white-space: nowrap; white-space: nowrap;
word-wrap: normal; word-wrap: normal;
direction: ltr; direction: ltr;
-webkit-font-feature-settings: 'liga'; -webkit-font-feature-settings: "liga";
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
} }
.material-legacy-icons { .material-legacy-icons {
font-family: 'Material Design Icons'; font-family: "Material Design Icons";
font-size: 1.35em; font-size: 1.35em;
font-style: normal; font-style: normal;
} }

View File

@ -1,38 +1,34 @@
module.exports = [ module.exports = [
{ {
text: 'Need help?', text: "Need help?",
link: '/help/', link: "/help/",
items: [ items: [
{ {
text: 'Frequently Asked Questions', text: "Frequently Asked Questions",
items: [ items: [
{ text: 'Application', link: '/help/faq/application' }, { text: "Application", link: "/help/faq/application" },
{ text: 'Extensions', link: '/help/faq/extensions' } { text: "Extensions", link: "/help/faq/extensions" }
] ]
}, },
{ {
text: 'Guides', text: "Guides",
items: [ items: [
{ text: 'General', link: '/help/guides/getting-started' }, { text: "General", link: "/help/guides/getting-started" },
{ text: 'Menus', link: '/help/guides/menus' }, { text: "Menus", link: "/help/guides/menus" },
{ text: 'Settings', link: '/help/guides/settings' }, { text: "Settings", link: "/help/guides/settings" },
{ text: 'Forks', link: '/help/guides/forks' } { text: "Forks", link: "/help/guides/forks" }
] ]
}, },
{ {
text: 'Contribution', text: "Contribution",
items: [ items: [{ text: "How can I help?", link: "/help/contribution" }]
{ text: 'How can I help?', link: '/help/contribution' }
]
}, },
{ {
text: 'Available extensions', text: "Available extensions",
items: [ items: [{ text: "List", link: "/extensions/" }]
{ text: 'List', link: '/extensions/' }
]
} }
] ]
}, },
{ text: 'Discord', link: 'https://discord.gg/tachiyomi' }, { text: "Discord", link: "https://discord.gg/tachiyomi" },
{ text: 'Reddit', link: 'https://reddit.com/r/Tachiyomi' } { text: "Reddit", link: "https://reddit.com/r/Tachiyomi" }
]; ];

View File

@ -1,18 +1,39 @@
module.exports = [ module.exports = [
['clean-urls', { [
normalSuffix: '/' }], "clean-urls",
['@vuepress/back-to-top'], {
['@vuepress/google-analytics', { normalSuffix: "/"
'ga': 'UA-148212082-1' }], }
['vuepress-plugin-container', { ],
type: 'expander', ["@vuepress/back-to-top"],
before: info => `<details class="expander content"><summary class="expander expansion">${info}</summary>`, [
after: '</details>'}], "@vuepress/google-analytics",
['vuepress-plugin-container', { {
type: 'guide', ga: "UA-148212082-1"
before: info => `<div class="guide"><p class="title">${info}</p>`, }
after: '</div>'}], ],
['vuepress-plugin-container', { [
type: 'aside', "vuepress-plugin-container",
defaultTitle: ''}] {
type: "expander",
before: info =>
`<details class="expander content"><summary class="expander expansion">${info}</summary>`,
after: "</details>"
}
],
[
"vuepress-plugin-container",
{
type: "guide",
before: info => `<div class="guide"><p class="title">${info}</p>`,
after: "</div>"
}
],
[
"vuepress-plugin-container",
{
type: "aside",
defaultTitle: ""
}
]
]; ];

View File

@ -1,19 +1,14 @@
import './styles/index.scss'; import './styles/index.scss';
import './styles/fonts.scss' import './styles/fonts.scss'
import { library } from '@fortawesome/fontawesome-svg-core';
import { faDownload } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { VueAgile } from 'vue-agile' import { VueAgile } from 'vue-agile'
library.add(faDownload);
export default ({ export default ({
Vue, // the version of Vue being used in the VuePress app Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance options, // the options for the root Vue instance
router, // the router instance for the app router, // the router instance for the app
siteData // site metadata siteData // site metadata
}) => { }) => {
Vue.component('font-awesome-icon', FontAwesomeIcon); // eslint-disable-next-line vue/match-component-file-name
Vue.component('agile', VueAgile) Vue.component('Agile', VueAgile)
}; };

View File

@ -1,3 +1,3 @@
module.exports = { module.exports = {
extend: '@vuepress/theme-default' extend: "@vuepress/theme-default"
}; };