Lazy-load markdown renderer on about page for smaller bundle size

merge-requests/552/head
Eliot Berriot 2018-12-20 00:47:05 +01:00
rodzic 3682aa81db
commit 17d86a2832
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
7 zmienionych plików z 13 dodań i 262 usunięć

Wyświetl plik

@ -27,9 +27,9 @@
<p>{{ instance.short_description.value }}</p>
</div>
<div
v-if="instance.long_description.value"
v-if="markdown && instance.long_description.value"
class="ui middle aligned stackable text container"
v-html="$options.filters.markdown(instance.long_description.value)">
v-html="markdown.makeHtml(instance.long_description.value)">
</div>
</section>
</main>
@ -43,8 +43,17 @@ export default {
components: {
Stats
},
created() {
data () {
return {
markdown: null
}
},
created () {
this.$store.dispatch("instance/fetchSettings")
let self = this
import('showdown').then(module => {
self.markdown = new module.default.Converter()
})
},
computed: {
...mapState({

Wyświetl plik

@ -206,10 +206,8 @@ export default {
labels() {
let mainMenu = this.$gettext("Main menu")
let selectTrack = this.$gettext("Play this track")
let pendingRequests = this.$gettext("Pending import requests")
let pendingFollows = this.$gettext("Pending follow requests")
return {
pendingRequests,
pendingFollows,
mainMenu,
selectTrack

Wyświetl plik

@ -1,53 +0,0 @@
<template>
<div class="comment">
<div class="content">
<a class="author">{{ user.username }}</a>
<div class="metadata">
<div class="date"><human-date :date="date"></human-date></div>
</div>
<div class="text" v-html="comment"></div>
</div>
<div class="actions">
<span
@click="collapsed = false"
v-if="truncated && collapsed"
class="expand">
<translate>Expand</translate>
</span>
<span
@click="collapsed = true"
v-if="truncated && !collapsed"
class="collapse">
<translate>Collapse</translate>
</span>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
user: {type: Object, required: true},
date: {required: true},
content: {type: String, required: true}
},
data () {
return {
collapsed: true,
length: 50
}
},
computed: {
comment () {
let text = this.content
if (this.collapsed) {
text = this.$options.filters.truncate(text, this.length)
}
return this.$options.filters.markdown(text)
},
truncated () {
return this.content.length > this.length
}
}
}
</script>

Wyświetl plik

@ -1,61 +0,0 @@
<template>
<div :class="['ui', {collapsed: collapsed}, 'card']">
<div class="content">
<div class="header">{{ request.artist_name }}</div>
<div class="description">
<div
v-if="request.albums" v-html="$options.filters.markdown(request.albums)"></div>
<div class="ui comments">
<comment
:user="request.user"
:content="request.comment || ''"
:date="request.creation_date"></comment>
</div>
</div>
</div>
<div class="extra content">
<span >
<i v-if="request.status === 'pending'" class="hourglass start icon"></i>
<i v-if="request.status === 'accepted'" class="hourglass half icon"></i>
<i v-if="request.status === 'imported'" class="check icon"></i>
{{ request.status | capitalize }}
</span>
<button
@click="createImport"
v-if="request.status === 'pending' && importAction && $store.state.auth.availablePermissions['library']"
class="ui mini basic green right floated button"><translate>Create import</translate></button>
</div>
</div>
</template>
<script>
import Comment from '@/components/discussion/Comment'
export default {
props: {
request: {type: Object, required: true},
importAction: {type: Boolean, default: true}
},
components: {
Comment
},
data () {
return {
collapsed: true
}
},
methods: {
createImport () {
this.$router.push({
name: 'library.import.launch',
query: {request: this.request.id}})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

Wyświetl plik

@ -1,127 +0,0 @@
<template>
<div>
<form v-if="!over" class="ui form" @submit.prevent="submit">
<p><translate>Something's missing in the library? Let us know what you would like to listen!</translate></p>
<div class="required field">
<label><translate>Artist name</translate></label>
<input v-model="currentArtistName" :placeholder="labels.artistNamePlaceholder" required maxlength="200">
</div>
<div class="field">
<label><translate>Albums</translate></label>
<p><translate>Leave this field empty if you're requesting the whole discography.</translate></p>
<input v-model="currentAlbums" :placeholder="labels.albumTitlePlaceholder" maxlength="2000">
</div>
<div class="field">
<label><translate>Comment</translate></label>
<textarea v-model="currentComment" rows="3" :placeholder="labels.commentPlaceholder" maxlength="2000"></textarea>
</div>
<button class="ui submit button" type="submit"><translate>Submit</translate></button>
</form>
<div v-else class="ui success message">
<div class="header"><translate>Request submitted!</translate></div>
<p><translate>We've received your request, you'll get some groove soon ;)</translate></p>
<button @click="reset" class="ui button"><translate>Submit another request</translate></button>
</div>
<div v-if="requests.length > 0">
<div class="ui divider"></div>
<h3 class="ui header"><translate>Pending requests</translate></h3>
<div class="ui list">
<div v-for="request in requests" class="item">
<div class="content">
<div class="header">{{ request.artist_name }}</div>
<div v-if="request.albums" class="description">
{{ request.albums|truncate }}</div>
<div v-if="request.comment" class="description">
{{ request.comment|truncate }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import $ from 'jquery'
import axios from 'axios'
import logger from '@/logging'
export default {
props: {
defaultArtistName: {type: String, default: ''},
defaultAlbums: {type: String, default: ''},
defaultComment: {type: String, default: ''}
},
created () {
this.fetchRequests()
},
mounted () {
$('.ui.radio.checkbox').checkbox()
},
data () {
return {
currentArtistName: this.defaultArtistName,
currentAlbums: this.defaultAlbums,
currentComment: this.defaultComment,
isLoading: false,
over: false,
requests: []
}
},
computed: {
labels () {
let artistNamePlaceholder = this.$gettext('The Beatles, Mickael Jackson…')
let albumTitlePlaceholder = this.$gettext('The White Album, Thriller…')
let commentPlaceholder = this.$gettext('Use this comment box to add details to your request if needed')
return {
artistNamePlaceholder,
albumTitlePlaceholder,
commentPlaceholder
}
}
},
methods: {
fetchRequests () {
let self = this
let url = 'requests/import-requests/'
axios.get(url, {}).then((response) => {
self.requests = response.data.results
})
},
submit () {
let self = this
this.isLoading = true
let url = 'requests/import-requests/'
let payload = {
artist_name: this.currentArtistName,
albums: this.currentAlbums,
comment: this.currentComment
}
axios.post(url, payload).then((response) => {
logger.default.info('Submitted request!')
self.isLoading = false
self.over = true
self.requests.unshift(response.data)
}, (response) => {
logger.default.error('error while submitting request')
self.isLoading = false
})
},
reset () {
this.over = false
this.currentArtistName = ''
this.currentAlbums = ''
this.currentComment = ''
},
truncate (string, length) {
if (string.length > length) {
return string.substring(0, length) + '…'
}
return string
}
}
}
</script>
<style scoped>
</style>

Wyświetl plik

@ -1,7 +1,6 @@
import Vue from 'vue'
import moment from 'moment'
import showdown from 'showdown'
export function truncate (str, max, ellipsis) {
max = max || 100
@ -14,13 +13,6 @@ export function truncate (str, max, ellipsis) {
Vue.filter('truncate', truncate)
export function markdown (str) {
const converter = new showdown.Converter()
return converter.makeHtml(str)
}
Vue.filter('markdown', markdown)
export function ago (date) {
const m = moment(date)
return m.fromNow()

Wyświetl plik

@ -1,6 +1,6 @@
import {expect} from 'chai'
import {truncate, markdown, ago, capitalize, year} from '@/filters'
import {truncate, ago, capitalize, year} from '@/filters'
describe('filters', () => {
describe('truncate', () => {
@ -20,13 +20,6 @@ describe('filters', () => {
expect(output).to.equal('Hello pouet')
})
})
describe('markdown', () => {
it('renders markdown', () => {
const input = 'Hello world'
let output = markdown(input)
expect(output).to.equal('<p>Hello world</p>')
})
})
describe('ago', () => {
it('works', () => {
const input = new Date()