Verified Commit 8ee9a536 authored by Georg Krause's avatar Georg Krause
Browse files

Lint the frontend code

parent 869fc205
......@@ -136,10 +136,7 @@ eslint:
- cd front
- yarn install
script:
# We search for all files ending with .vue or .js in src which changed in relation to develop
# and lint them. This way we focus on some errors instead of checking the hole repository
- export changedFiles=$(git diff --relative --name-only --diff-filter=d origin/develop -- src/ | grep -E "\.(vue|js)$")
- yarn run eslint --quiet -f table $(echo $changedFiles | tr '\n' ' ')
- yarn lint
cache:
key: "$CI_PROJECT_ID__eslint_npm_cache"
paths:
......
......@@ -20,5 +20,7 @@ module.exports = {
'vue'
],
rules: {
"vue/no-v-html": "off", // TODO: tackle this properly
"vue/no-use-v-if-with-v-for": "off"
}
}
......@@ -8,7 +8,7 @@
"serve": "[ ! -d src/translations ] && npm run i18n-compile; vue-cli-service serve --port ${VUE_PORT:-8080} --host ${VUE_HOST:-0.0.0.0}",
"build": "scripts/i18n-compile.sh && vue-cli-service build",
"test:unit": "vue-cli-service test:unit --reporter mocha-junit-reporter",
"lint": "eslint $(git status --porcelain --untracked-files=no | grep -E '(A|M) ' | cut -d' ' -f3 | sed s_front/__ | grep -E '.(js|vue)$')",
"lint": "eslint --ext .js,.vue src",
"i18n-compile": "scripts/i18n-compile.sh",
"i18n-extract": "scripts/i18n-extract.sh",
"fix-fomantic-css": "scripts/fix-fomantic-css.sh",
......
This diff is collapsed.
var Album = {
const Album = {
clean (album) {
// we manually rebind the album and artist to each child track
album.tracks = album.tracks.map((track) => {
......@@ -8,7 +8,7 @@ var Album = {
return album
}
}
var Artist = {
const Artist = {
clean (artist) {
// clean data as given by the API
artist.albums = artist.albums.map((album) => {
......
const DYNAMIC_RANGE = 40 // dB
function toLinearVolumeScale(v) {
if (v <= 0.0) {
return 0.0
}
function toLinearVolumeScale (v) {
if (v <= 0.0) {
return 0.0
}
// (1.0; 0.0) -> (0; -DYNAMIC_RANGE) dB
let dB = (v-1)*DYNAMIC_RANGE
// (1.0; 0.0) -> (0; -DYNAMIC_RANGE) dB
const dB = (v - 1) * DYNAMIC_RANGE
return Math.pow(10, dB / 20)
return Math.pow(10, dB / 20)
}
function toLogarithmicVolumeScale(v) {
if (v <= 0.0) {
return 0.0
}
function toLogarithmicVolumeScale (v) {
if (v <= 0.0) {
return 0.0
}
let dB = 20 * Math.log10(v)
const dB = 20 * Math.log10(v)
// (0; -DYNAMIC_RANGE) [dB] -> (1.0; 0.0)
return 1 - (dB / -DYNAMIC_RANGE)
// (0; -DYNAMIC_RANGE) [dB] -> (1.0; 0.0)
return 1 - (dB / -DYNAMIC_RANGE)
}
exports.toLinearVolumeScale = toLinearVolumeScale
......
<template>
<footer id="footer" role="contentinfo" class="ui vertical footer segment" aria-labelledby="footer-label">
<h1 id="footer-label" class="visually-hidden">
<translate translate-context="*/*/*">Application footer</translate>
<footer
id="footer"
role="contentinfo"
class="ui vertical footer segment"
aria-labelledby="footer-label"
>
<h1
id="footer-label"
class="visually-hidden"
>
<translate translate-context="*/*/*">
Application footer
</translate>
</h1>
<div class="ui container">
<div class="ui stackable equal height stackable grid">
<section class="four wide column">
<h4 v-if="podName" class="ui header ellipsis">
<span v-translate="{instanceName: podName}" translate-context="Footer/About/Title">About %{instanceName}</span>
<h4
v-if="podName"
class="ui header ellipsis"
>
<span
v-translate="{instanceName: podName}"
translate-context="Footer/About/Title"
>About %{instanceName}</span>
</h4>
<h4 v-else class="ui header ellipsis">
<span v-translate="{instanceUrl: instanceHostname}" translate-context="Footer/About/Title">About %{instanceUrl}</span>
<h4
v-else
class="ui header ellipsis"
>
<span
v-translate="{instanceUrl: instanceHostname}"
translate-context="Footer/About/Title"
>About %{instanceUrl}</span>
</h4>
<div class="ui list">
<router-link v-if="this.$route.path != '/about'" class="link item" to="/about">
<translate translate-context="Footer/About/List item.Link">About</translate>
<router-link
v-if="$route.path != '/about'"
class="link item"
to="/about"
>
<translate translate-context="Footer/About/List item.Link">
About
</translate>
</router-link>
<router-link v-else-if="this.$route.path == '/about' && $store.state.auth.authenticated" class="link item" to="/library">
<translate translate-context="Footer/*/List item.Link">Go to Library</translate>
<router-link
v-else-if="$route.path == '/about' && $store.state.auth.authenticated"
class="link item"
to="/library"
>
<translate translate-context="Footer/*/List item.Link">
Go to Library
</translate>
</router-link>
<router-link v-else class="link item" to="/">
<translate translate-context="Footer/*/List item.Link">Home Page</translate>
<router-link
v-else
class="link item"
to="/"
>
<translate translate-context="Footer/*/List item.Link">
Home Page
</translate>
</router-link>
<a v-if="version" class="link item" href="https://docs.funkwhale.audio/changelog.html" target="_blank">
<translate translate-context="Footer/*/List item" :translate-params="{version: version}" >Version %{version}</translate>
</a>
<a role="button" href="" class="link item" @click.prevent="$emit('show:set-instance-modal')" >
<a
v-if="version"
class="link item"
href="https://docs.funkwhale.audio/changelog.html"
target="_blank"
>
<translate
translate-context="Footer/*/List item"
:translate-params="{version: version}"
>Version %{version}</translate>
</a>
<a
role="button"
href=""
class="link item"
@click.prevent="$emit('show:set-instance-modal')"
>
<translate translate-context="Footer/*/List item.Link">Use another instance</translate>
</a>
</div>
<div class="ui form">
<div class="ui field">
<label for="language-select"><translate translate-context="Footer/Settings/Dropdown.Label/Short, Verb">Change language</translate></label>
<select id="language-select" class="ui dropdown" :value="$language.current" @change="$store.dispatch('ui/currentLanguage', $event.target.value)">
<option v-for="(language, key) in $language.available" :key="key" :value="key">{{ language }}</option>
<select
id="language-select"
class="ui dropdown"
:value="$language.current"
@change="$store.dispatch('ui/currentLanguage', $event.target.value)"
>
<option
v-for="(language, key) in $language.available"
:key="key"
:value="key"
>
{{ language }}
</option>
</select>
</div>
</div>
</section>
<section class="four wide column">
<h4 v-translate class="ui header" translate-context="Footer/*/Title">Using Funkwhale</h4>
<h4
v-translate
class="ui header"
translate-context="Footer/*/Title"
>
Using Funkwhale
</h4>
<div class="ui list">
<a href="https://docs.funkwhale.audio" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link/Short, Noun">Documentation</translate></a>
<a href="https://funkwhale.audio/apps" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Mobile and desktop apps</translate></a>
<a hrelf="" class="link item" @click.prevent="$emit('show:shortcuts-modal')"><translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate></a>
<a
href="https://docs.funkwhale.audio"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link/Short, Noun">Documentation</translate></a>
<a
href="https://funkwhale.audio/apps"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link">Mobile and desktop apps</translate></a>
<a
hrelf=""
class="link item"
@click.prevent="$emit('show:shortcuts-modal')"
><translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate></a>
</div>
<div class="ui form">
<div class="ui field">
<label for="theme-select"><translate translate-context="Footer/Settings/Dropdown.Label/Short, Verb">Change theme</translate></label>
<select id="theme-select" class="ui dropdown" :value="$store.state.ui.theme" @change="$store.dispatch('ui/theme', $event.target.value)">
<option v-for="theme in themes" :key="theme.key" :value="theme.key">{{ theme.name }}</option>
<select
id="theme-select"
class="ui dropdown"
:value="$store.state.ui.theme"
@change="$store.dispatch('ui/theme', $event.target.value)"
>
<option
v-for="theme in themes"
:key="theme.key"
:value="theme.key"
>
{{ theme.name }}
</option>
</select>
</div>
</div>
</section>
<section class="four wide column">
<h4 v-translate translate-context="Footer/*/Link" class="ui header">Getting help</h4>
<h4
v-translate
translate-context="Footer/*/Link"
class="ui header"
>
Getting help
</h4>
<div class="ui list">
<a href="https://forum.funkwhale.audio/" class="link item" target="_blank"><translate translate-context="Footer/*/Listitem.Link">Support forum</translate></a>
<a href="https://matrix.to/#/#funkwhale-troubleshooting:matrix.org" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Chat room</translate></a>
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Issue tracker</translate></a>
<a
href="https://forum.funkwhale.audio/"
class="link item"
target="_blank"
><translate translate-context="Footer/*/Listitem.Link">Support forum</translate></a>
<a
href="https://matrix.to/#/#funkwhale-troubleshooting:matrix.org"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link">Chat room</translate></a>
<a
href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link">Issue tracker</translate></a>
</div>
</section>
<section class="four wide column">
<h4 v-translate class="ui header" translate-context="Footer/*/Title/Short">About Funkwhale</h4>
<h4
v-translate
class="ui header"
translate-context="Footer/*/Title/Short"
>
About Funkwhale
</h4>
<div class="ui list">
<a href="https://funkwhale.audio" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Official website</translate></a>
<a href="https://contribute.funkwhale.audio" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Contribute</translate></a>
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="link item" target="_blank"><translate translate-context="Footer/*/List item.Link">Source code</translate></a>
<a
href="https://funkwhale.audio"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link">Official website</translate></a>
<a
href="https://contribute.funkwhale.audio"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link">Contribute</translate></a>
<a
href="https://dev.funkwhale.audio/funkwhale/funkwhale"
class="link item"
target="_blank"
><translate translate-context="Footer/*/List item.Link">Source code</translate></a>
</div>
<div class="ui hidden divider"></div>
<div class="ui hidden divider" />
<p>
<translate translate-context="Footer/*/List item.Link">The Funkwhale logo was kindly designed and provided by Francis Gading.</translate>
<translate translate-context="Footer/*/List item.Link">
The Funkwhale logo was kindly designed and provided by Francis Gading.
</translate>
</p>
</section>
</div>
......@@ -80,24 +211,22 @@
</template>
<script>
import Vue from "vue"
import { mapState } from "vuex"
import axios from 'axios'
import { mapState } from 'vuex'
import _ from '@/lodash'
export default {
props: ["version"],
props: { version: { type: String, required: true } },
computed: {
...mapState({
messages: state => state.ui.messages,
nodeinfo: state => state.instance.nodeinfo,
nodeinfo: state => state.instance.nodeinfo
}),
podName() {
podName () {
return _.get(this.nodeinfo, 'metadata.nodeName')
},
instanceHostname() {
let url = this.$store.state.instance.instanceUrl
let parser = document.createElement("a")
instanceHostname () {
const url = this.$store.state.instance.instanceUrl
const parser = document.createElement('a')
parser.href = url
return parser.hostname
},
......
This diff is collapsed.
<template>
<svg version="1.1" id="layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
<g>
<svg
id="layer_1"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 141.7 141.7"
enable-background="new 0 0 141.7 141.7"
xml:space="preserve"
>
<g>
<path :fill="fill" d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"/>
<path :fill="fill" d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
<g>
<path
:fill="fill"
d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"
/>
<path
:fill="fill"
d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
c0,17.1-13.9,31-31,31c-17.1,0-31-13.9-31-31c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C29.6,87.6,48.1,106.1,70.9,106.1z"
/>
<path :fill="fill" d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
<path
:fill="fill"
d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,33.8,27.5,61.3,61.3,61.3c33.8,0,61.3-27.5,61.3-61.3
C132.2,64.3,131.7,63.8,131.1,63.8z"/>
</g>
<path :fill="fill" d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
C132.2,64.3,131.7,63.8,131.1,63.8z"
/>
</g>
<path
:fill="fill"
d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
c0,0,2,5.2,6.4,5.2c4.7,0,6.4-5.2,6.4-5.2l0.3-5.2c0,0-0.1-4.7,2.4-8.5c1.6-2.5,3.2-4.3,5.8-5.7c4-2.3,8.4-2.7,12.5-4.8
c4.1-2.1,8.1-4.8,10.8-8.6c2.7-3.8,4-8.8,2.5-13.2c-7.8-0.4-16.8,0.5-23.7,4.2c-9.6,5.1-15.4,3.3-17.1,10.9h-0.1
c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"/>
</g>
c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"
/>
</g>
</svg>
</template>
<script>
export default {
props: {
fill: {type: String, default: '#222222'}
fill: { type: String, default: '#222222' }
}
}
</script>
<template>
<svg viewBox="0 0 271.66678 53.49133" version="1.1">
<svg
viewBox="0 0 271.66678 53.49133"
version="1.1"
>
<g transform="translate(34.65295 -109.48195)">
<g>
<g transform="matrix(.3191 0 0 .3191 -45.91741 93.47184)">
......@@ -14,7 +17,11 @@
</g>
</g>
</g>
<g transform="translate(-.75595 -.75595)" :fill="text" stroke-width=".74383">
<g
transform="translate(-.75595 -.75595)"
:fill="text"
stroke-width=".74383"
>
<path d="M32.84591 132.89252c0-6.69443 2.6034-9.29781 10.41356-9.29781 1.63641 0 3.71912.14876 4.83486.37191.59506.14876 1.11574.59506 1.11574 1.11574v2.00832c0 .59506-.4463 1.11574-1.11574 1.11574h-.66944c-.8182 0-1.48765-.29753-2.529-.29753-4.83487 0-5.80184.96698-5.80184 4.98363v.29753h6.62004c.59506 0 1.11574.4463 1.11574 1.11574v2.15709c0 .66945-.4463 1.11574-1.11574 1.11574h-6.62004v11.30614c0 .59506-.4463 1.11574-1.11574 1.11574h-4.01666c-.59506 0-1.11574-.52068-1.11574-1.11574z" />
<path d="M57.02023 141.59528c0 3.04968 1.41327 4.31418 3.49598 4.31418 1.78518 0 3.49598-1.2645 4.83487-2.60339v-12.12435c0-.59506.52068-1.11573 1.11574-1.11573h4.09103c.59506 0 1.11574.52067 1.11574 1.11573v17.70304c0 .59506-.4463 1.11574-1.11574 1.11574h-4.09104c-.59505 0-1.11573-.52068-1.11573-1.11574v-1.19012c-1.7108 1.48765-3.57036 2.67777-6.32252 2.67777-4.83486 0-8.25646-2.529-8.25646-8.70275v-10.41355c0-.59506.4463-1.11574 1.11574-1.11574h4.09104c.59506 0 1.11574.52068 1.11574 1.11574v10.33917z" />
<path d="M90.71552 138.47121c0-3.04968-1.41327-4.31419-3.49598-4.31419-1.78518 0-3.57036 1.26451-4.90925 2.60339v12.19874c0 .59506-.4463 1.11573-1.11573 1.11573h-4.09104c-.66945 0-1.11574-.52067-1.11574-1.11573v-17.77743c0-.59506.4463-1.11573 1.11574-1.11573h4.16542c.59506 0 1.11574.52067 1.11574 1.11573v1.19012c1.7108-1.48765 3.57036-2.67777 6.3969-2.67777 4.83486 0 8.25645 2.52901 8.25645 8.70276v10.41355c0 .59506-.4463 1.11574-1.11573 1.11574h-4.09104c-.59506 0-1.11574-.52068-1.11574-1.11574z" />
......@@ -33,9 +40,9 @@
<script>
export default {
props: {
primary: {type: String, default: '#009fe3'},
secondary: {type: String, default: 'var(--text-color)'},
text: {type: String, default: 'var(--text-color)'},
primary: { type: String, default: '#009fe3' },
secondary: { type: String, default: 'var(--text-color)' },
text: { type: String, default: 'var(--text-color)' }
}
}
</script>
<template>
<main class="main pusher" :v-title="labels.title">
<main
class="main pusher"
:v-title="labels.title"
>
<section class="ui vertical stripe segment">
<div class="ui text container">
<h1 class="ui huge header">
<i class="warning icon"></i>
<i class="warning icon" />
<div class="content">
<translate translate-context="Content/*/Title">Page not found!</translate>
<translate translate-context="Content/*/Title">
Page not found!
</translate>
</div>
</h1>
<p><translate translate-context="Content/*/Paragraph">Sorry, the page you asked for does not exist:</translate></p>
<p>
<translate translate-context="Content/*/Paragraph">
Sorry, the page you asked for does not exist:
</translate>
</p>
<a :href="path">{{ path }}</a>
<div class="ui hidden divider"></div>
<router-link class="ui icon labeled right button" to="/">
<translate translate-context="Content/*/Button.Label/Verb">Go to home page</translate>
<i class="right arrow icon"></i>
<div class="ui hidden divider" />
<router-link
class="ui icon labeled right button"
to="/"
>
<translate translate-context="Content/*/Button.Label/Verb">
Go to home page
</translate>
<i class="right arrow icon" />
</router-link>
</div>
</section>
......@@ -22,15 +36,15 @@
<script>
export default {
data: function() {
data: function () {
return {
path: window.location.href
}
},
computed: {
labels() {
labels () {
return {
title: this.$pgettext('Head/*/Title', "Page Not Found")
title: this.$pgettext('Head/*/Title', 'Page Not Found')
}
}
}
......
<template>
<div v-if='maxPage > 1' class="ui pagination menu component-pagination" role="navigation" :aria-label="labels.pagination">
<a href
<div
v-if="maxPage > 1"
class="ui pagination menu component-pagination"
role="navigation"
:aria-label="labels.pagination"
>
<a
href
:disabled="current - 1 < 1"
role="button"
:aria-label="labels.previousPage"
:class="[{'disabled': current - 1 < 1}, 'item']"
@click.prevent.stop="selectPage(current - 1)"
:class="[{'disabled': current - 1 < 1}, 'item']"><i class="angle left icon"></i></a>
><i class="angle left icon" /></a>
<template v-if="!compact">
<a href
<a
v-for="page in pages"
:key="page"
href
:class="[{'active': page === current}, {'disabled': page === 'skip'}, 'item']"
@click.prevent.stop="selectPage(page)"
:class="[{'active': page === current}, {'disabled': page === 'skip'}, 'item']">
>
<span v-if="page !== 'skip'">{{ page }}</span>
<span v-else></span>
</a>
</template>
<a href
<a
href
:disabled="current + 1 > maxPage"
role="button"
:aria-label="labels.nextPage"
:class="[{'disabled': current + 1 > maxPage}, 'item']"
@click.prevent.stop="selectPage(current + 1)"
:class="[{'disabled': current + 1 > maxPage}, 'item']"><i class="angle right icon"></i></a>
><i class="angle right icon" /></a>
</div>
</template>
<script>
import _ from "@/lodash"
import _ from '@/lodash'
export default {
props: {
current: { type: Number, default: 1 },
paginateBy: { type: Number, default: 25 },
total: { type: Number },
total: { type: Number, required: true },
compact: { type: Boolean, default: false }
},
computed: {
labels() {
labels () {
return {
pagination: this.$pgettext('Content/*/Hidden text/Noun', "Pagination"),
previousPage: this.$pgettext('Content/*/Link', "Previous Page"),
nextPage: this.$pgettext('Content/*/Link', "Next Page")
pagination: this.$pgettext('Content/*/Hidden text/Noun', 'Pagination'),
previousPage: this.$pgettext('Content/*/Link', 'Previous Page'),
nextPage: this.$pgettext('Content/*/Link', 'Next Page')
}
},
pages: function() {
let range = 2
let current = this.current
let beginning = _.range(1, Math.min(this.maxPage, 1 + range))
let middle = _.range(
pages: function () {
const range = 2
const current = this.current