diff --git a/front/src/components/audio/EmbedWizard.vue b/front/src/components/audio/EmbedWizard.vue new file mode 100644 index 0000000000000000000000000000000000000000..7a50ffa54223a189d40cd91fbbe9f0e41b0814ee --- /dev/null +++ b/front/src/components/audio/EmbedWizard.vue @@ -0,0 +1,80 @@ +<template> + <div> + <div class="ui form"> + <div class="two fields"> + <div class="field"> + <div class="field"> + <label for="embed-width"><translate>Widget width</translate></label> + <p><translate>Leave empty for a responsive widget</translate></p> + <input id="embed-width" type="number" v-model.number="width" min="0" step="10" /> + </div> + <template v-if="type != 'track'"> + <br> + <div class="field"> + <label for="embed-height"><translate>Widget height</translate></label> + <input id="embed-height" type="number" v-model="height" :min="minHeight" max="1000" step="10" /> + </div> + </template> + </div> + <div class="field"> + <button @click="copy" class="ui right floated button"><translate>Copy</translate></button> + <label for="embed-width"><translate>Embed code</translate></label> + <p><translate>Copy/paste this code in your website HTML</translate></p> + <div class="ui hidden divider"></div> + <textarea ref="textarea":value="embedCode" rows="3" readonly> + </textarea> + </div> + </div> + </div> + <div class="preview"> + <h3><translate>Preview</translate></h3> + <iframe :width="frameWidth" :height="height" scrolling="no" frameborder="no" :src="iframeSrc"></iframe> + </div> + </div> +</template> + +<script> + +export default { + props: ['type', 'id'], + data () { + let d = { + width: null, + height: 150, + minHeight: 100 + } + if (this.type === 'album') { + d.height = 330 + d.minHeight = 250 + } + return d + }, + computed: { + iframeSrc () { + return this.$store.getters['instance/absoluteUrl']( + `/front/embed.html?&type=${this.type}&id=${this.id}` + ) + }, + frameWidth () { + if (this.width) { + return this.width + } + return '100%' + }, + embedCode () { + let src = this.iframeSrc.replace(/&/g, '&') + return `<iframe width="${this.frameWidth}" height="${this.height}" scrolling="no" frameborder="no" src="${src}"></iframe>` + } + }, + methods: { + copy () { + this.$refs.textarea.select() + document.execCommand("Copy") + } + } +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> +</style> diff --git a/front/src/components/federation/LibraryWidget.vue b/front/src/components/federation/LibraryWidget.vue index ff73bb7a892d77d09969100e54e7137b6d15e0c4..abe993e4662a01cda6feb10f6f97d19bcdb26ea4 100644 --- a/front/src/components/federation/LibraryWidget.vue +++ b/front/src/components/federation/LibraryWidget.vue @@ -62,6 +62,7 @@ export default { self.nextPage = response.data.next self.isLoading = false self.libraries = response.data.results + self.$emit('loaded', self.libraries) }, error => { self.isLoading = false self.errors = error.backendErrors diff --git a/front/src/components/library/Album.vue b/front/src/components/library/Album.vue index 9a4adfafc1134d854e6267a68740e19f4c413649..6a3cfaa8ebf64fc87e51c36179b25b8bbc6b2ebd 100644 --- a/front/src/components/library/Album.vue +++ b/front/src/components/library/Album.vue @@ -37,6 +37,30 @@ <i class="external icon"></i> <translate>View on MusicBrainz</translate> </a> + <template v-if="publicLibraries.length > 0"> + <button + @click="showEmbedModal = !showEmbedModal" + class="ui button"> + <i class="code icon"></i> + <translate>Embed</translate> + </button> + <modal :show.sync="showEmbedModal"> + <div class="header"> + <translate>Embed this album on your website</translate> + </div> + <div class="content"> + <div class="description"> + <embed-wizard type="album" :id="album.id" /> + + </div> + </div> + <div class="actions"> + <div class="ui deny button"> + <translate>Cancel</translate> + </div> + </div> + </modal> + </template> </div> </section> <template v-if="discs && discs.length > 1"> @@ -64,7 +88,7 @@ <h2> <translate>User libraries</translate> </h2> - <library-widget :url="'albums/' + id + '/libraries/'"> + <library-widget @loaded="libraries = $event" :url="'albums/' + id + '/libraries/'"> <translate slot="subtitle">This album is present in the following libraries:</translate> </library-widget> </section> @@ -79,6 +103,8 @@ import backend from "@/audio/backend" import PlayButton from "@/components/audio/PlayButton" import TrackTable from "@/components/audio/track/Table" import LibraryWidget from "@/components/federation/LibraryWidget" +import EmbedWizard from "@/components/audio/EmbedWizard" +import Modal from '@/components/semantic/Modal' const FETCH_URL = "albums/" @@ -98,13 +124,17 @@ export default { components: { PlayButton, TrackTable, - LibraryWidget + LibraryWidget, + EmbedWizard, + Modal }, data() { return { isLoading: true, album: null, - discs: [] + discs: [], + libraries: [], + showEmbedModal: false } }, created() { @@ -129,6 +159,11 @@ export default { title: this.$gettext("Album") } }, + publicLibraries () { + return this.libraries.filter(l => { + return l.privacy_level === 'everyone' + }) + }, wikipediaUrl() { return ( "https://en.wikipedia.org/w/index.php?search=" + diff --git a/front/src/components/library/Track.vue b/front/src/components/library/Track.vue index 4aeecdf39dbf5355ccadaa1053899403119d57d6..d4127de1d719a0dd800d24de93956d1d35551aa1 100644 --- a/front/src/components/library/Track.vue +++ b/front/src/components/library/Track.vue @@ -55,6 +55,30 @@ <i class="download icon"></i> <translate>Download</translate> </a> + <template v-if="publicLibraries.length > 0"> + <button + @click="showEmbedModal = !showEmbedModal" + class="ui button"> + <i class="code icon"></i> + <translate>Embed</translate> + </button> + <modal :show.sync="showEmbedModal"> + <div class="header"> + <translate>Embed this track on your website</translate> + </div> + <div class="content"> + <div class="description"> + <embed-wizard type="track" :id="track.id" /> + + </div> + </div> + <div class="actions"> + <div class="ui deny button"> + <translate>Cancel</translate> + </div> + </div> + </modal> + </template> </div> </section> <section class="ui vertical stripe center aligned segment"> @@ -144,7 +168,7 @@ <h2> <translate>User libraries</translate> </h2> - <library-widget :url="'tracks/' + id + '/libraries/'"> + <library-widget @loaded="libraries = $event" :url="'tracks/' + id + '/libraries/'"> <translate slot="subtitle">This track is present in the following libraries:</translate> </library-widget> </section> @@ -162,6 +186,7 @@ import TrackFavoriteIcon from "@/components/favorites/TrackFavoriteIcon" import TrackPlaylistIcon from "@/components/playlists/TrackPlaylistIcon" import LibraryWidget from "@/components/federation/LibraryWidget" import Modal from '@/components/semantic/Modal' +import EmbedWizard from "@/components/audio/EmbedWizard" const FETCH_URL = "tracks/" @@ -172,7 +197,8 @@ export default { TrackPlaylistIcon, TrackFavoriteIcon, LibraryWidget, - Modal + Modal, + EmbedWizard }, data() { return { @@ -181,7 +207,9 @@ export default { isLoadingLyrics: true, track: null, lyrics: null, - licenseData: null + licenseData: null, + libraries: [], + showEmbedModal: false } }, created() { @@ -224,6 +252,11 @@ export default { } }, computed: { + publicLibraries () { + return this.libraries.filter(l => { + return l.privacy_level === 'everyone' + }) + }, labels() { return { title: this.$gettext("Track")