Paths in frontend templates to find the source files. Move non-abstract external UI components into this repo. ArtistCard working, with missing css
This commit is contained in:
parent
fe49c87e57
commit
684fc13f7e
|
@ -0,0 +1,51 @@
|
|||
<script setup lang="ts">
|
||||
import { FwCard, FwPlayButton, FwOptionsButton } from '~/components'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import type { Album } from '~/types/models'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const play = defineEmit<[album: Album]>()
|
||||
const album = defineProp<Album>('album', { required: true })
|
||||
|
||||
let navigate = (to: 'artist' | 'album') => {}
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
const router = useRouter()
|
||||
navigate = (to: 'artist' | 'album') => to === 'album'
|
||||
? router.push({ name: 'library.albums.detail', params: { id: album.value.id } })
|
||||
: router.push({ name: 'library.artists.detail', params: { id: album.value.artist.id } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<fw-card
|
||||
:title="album.name"
|
||||
:image="album.cover.urls.original"
|
||||
@click="navigate('album')"
|
||||
class="album-card"
|
||||
>
|
||||
<fw-play-button @play="play(album)" />
|
||||
|
||||
<a
|
||||
v-for="ac in album.artistCredit"
|
||||
:key="ac.artist.id"
|
||||
@click.stop="navigate('artist')"
|
||||
class="funkwhale link"
|
||||
>
|
||||
{{ ac.credit ?? t('components.Queue.meta.unknownArtist') }}
|
||||
<!-- {{ ac.joinphrase }} -->
|
||||
</a>
|
||||
|
||||
<template #footer>
|
||||
{{ t('vui.tracks', album.tracks.length) }}
|
||||
<fw-options-button />
|
||||
</template>
|
||||
</fw-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style.scss'
|
||||
</style>
|
|
@ -0,0 +1,25 @@
|
|||
.funkwhale {
|
||||
&.card.album-card {
|
||||
--fw-border-radius: 12px;
|
||||
--fw-card-width: 208px;
|
||||
--fw-card-image-width: var(--fw-card-width);
|
||||
--fw-card-padding: 16px;
|
||||
|
||||
> .card-image {
|
||||
border-radius: 0 !important;
|
||||
width: var(--fw-card-image-width);
|
||||
margin: calc(-1 * var(--fw-card-padding)) calc(-1 * var(--fw-card-padding)) 0;
|
||||
}
|
||||
|
||||
> .card-title {
|
||||
font-size: 1rem;
|
||||
text-align: left !important;
|
||||
padding-top: 16px !important;
|
||||
}
|
||||
|
||||
> .card-content {
|
||||
padding-top: 0 !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import type { Artist } from '~/types'
|
||||
|
||||
const play = defineEmit<[artist: Artist]>()
|
||||
|
||||
interface Props {
|
||||
artist: Artist;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const { artist } = props
|
||||
|
||||
let navigate = () => {}
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
const router = useRouter()
|
||||
navigate = () =>
|
||||
router.push({ name: 'library.artists.detail', params: { id: artist.id } })
|
||||
}
|
||||
const image = artist.cover
|
||||
? artist.cover.urls.original
|
||||
: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`
|
||||
</script>
|
||||
|
||||
<template>
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/artist/Card.vue
|
||||
<fw-card
|
||||
:title="artist.name"
|
||||
:image="image"
|
||||
:tags="artist.tags"
|
||||
@click="navigate"
|
||||
class="artist-card"
|
||||
>
|
||||
<fw-play-button @play="play(artist)" />
|
||||
|
||||
<template #footer>
|
||||
{{ $t("components.audio.artist.Card.meta.tracks", artist.tracks_count) }}
|
||||
<fw-options-button />
|
||||
</template>
|
||||
</fw-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
|
@ -0,0 +1,28 @@
|
|||
.funkwhale {
|
||||
&.card.artist-card {
|
||||
--fw-border-radius: 12px;
|
||||
--fw-card-width: 208px;
|
||||
--fw-card-image-width: calc(var(--fw-card-width) - 16px);
|
||||
--fw-card-padding: 16px;
|
||||
|
||||
> .card-image {
|
||||
border-radius: 50% !important;
|
||||
width: var(--fw-card-image-width);
|
||||
margin: calc(-1 * var(--fw-card-padding) + 8px) calc(-1 * var(--fw-card-padding) + 8px) 0;
|
||||
}
|
||||
|
||||
.play-button {
|
||||
top: calc(var(--fw-card-width) - 44px - 8px) !important;
|
||||
}
|
||||
|
||||
> .card-title {
|
||||
font-size: 1rem;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
> .card-content {
|
||||
padding-top: 6px !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
.funkwhale {
|
||||
&.card.artist-card {
|
||||
--fw-border-radius: 12px;
|
||||
--fw-card-width: 208px;
|
||||
--fw-card-image-width: calc(var(--fw-card-width) - 16px);
|
||||
--fw-card-padding: 16px;
|
||||
|
||||
> .card-image {
|
||||
border-radius: 50% !important;
|
||||
width: var(--fw-card-image-width);
|
||||
margin: calc(-1 * var(--fw-card-padding) + 8px) calc(-1 * var(--fw-card-padding) + 8px) 0;
|
||||
}
|
||||
|
||||
.play-button {
|
||||
top: calc(var(--fw-card-width) - 44px - 8px) !important;
|
||||
}
|
||||
|
||||
> .card-title {
|
||||
font-size: 1rem;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
> .card-content {
|
||||
padding-top: 6px !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -72,6 +72,7 @@ const labels = computed(() => ({
|
|||
|
||||
<template>
|
||||
<div>
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/audio/Search.vue
|
||||
<h2>
|
||||
{{ $t('components.audio.Search.header.search') }}
|
||||
</h2>
|
||||
|
|
|
@ -143,6 +143,7 @@ const remove = async () => {
|
|||
<section class="ui vertical stripe segment channel-serie">
|
||||
<div class="ui stackable grid container">
|
||||
<div class="ui seven wide column">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/library/AlbumBase.vue
|
||||
<div
|
||||
v-if="isSerie"
|
||||
class="padded basic segment"
|
||||
|
|
|
@ -120,6 +120,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
|||
<template>
|
||||
<main v-title="labels.title">
|
||||
<section class="ui vertical stripe segment">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/library/Albums.vue
|
||||
<h2 class="ui header">
|
||||
{{ $t('components.library.Albums.header.browse') }}
|
||||
</h2>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import ArtistCard from '~/components/artist/Card.vue'
|
||||
import type { OrderingProps } from '~/composables/navigation/useOrdering'
|
||||
import type { Artist, BackendResponse } from '~/types'
|
||||
import type { RouteRecordName } from 'vue-router'
|
||||
|
@ -15,7 +16,7 @@ import axios from 'axios'
|
|||
import $ from 'jquery'
|
||||
|
||||
import TagsSelector from '~/components/library/TagsSelector.vue'
|
||||
import ArtistCard from '~/components/audio/artist/Card.vue'
|
||||
// import ArtistCard from '~/components/audio/artist/Card.vue'
|
||||
import Pagination from '~/components/vui/Pagination.vue'
|
||||
|
||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||
|
@ -121,6 +122,7 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
|
|||
<template>
|
||||
<main v-title="labels.title">
|
||||
<section class="ui vertical stripe segment">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/library/Artists.vue
|
||||
<h2 class="ui header">
|
||||
{{ $t('components.library.Artists.header.browse') }}
|
||||
</h2>
|
||||
|
@ -233,6 +235,11 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
|
|||
>
|
||||
<div class="ui loader" />
|
||||
</div>
|
||||
<ArtistCard
|
||||
v-for="artist in result.results"
|
||||
:key="artist.id"
|
||||
:artist="artist"
|
||||
/>
|
||||
<artist-card
|
||||
v-for="artist in result.results"
|
||||
:key="artist.id"
|
||||
|
|
|
@ -110,11 +110,11 @@ fetchData()
|
|||
<h3 class="ui header">
|
||||
{{ $t('components.library.Home.header.newChannels') }}
|
||||
</h3>
|
||||
<channels-widget
|
||||
<!-- <channels-widget
|
||||
:show-modification-date="true"
|
||||
:limit="12"
|
||||
:filters="{ordering: '-creation_date', external: 'false'}"
|
||||
/>
|
||||
/> -->
|
||||
</template>
|
||||
</section>
|
||||
</main>
|
||||
|
|
|
@ -102,6 +102,7 @@ const labels = computed(() => ({
|
|||
<template>
|
||||
<div>
|
||||
<div class="ui inline form">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/manage/library/AlbumsTable.vue
|
||||
<div class="fields">
|
||||
<div class="ui six wide field">
|
||||
<label for="albums-search">{{ $t('components.manage.library.AlbumsTable.label.search') }}</label>
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<script setup lang="ts">
|
||||
import { FwCard, FwPlayButton, FwOptionsButton } from '~/components'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { Playlist } from '~/types/models'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const play = defineEmit<[playlist: Playlist]>()
|
||||
const playlist = defineProp<Playlist>('playlist', { required: true })
|
||||
|
||||
const covers = computed(() => playlist.value.album_covers
|
||||
.filter((src, index, array) => array.indexOf(src) === index)
|
||||
.slice(0, 4)
|
||||
)
|
||||
|
||||
const profileParams = computed(() => {
|
||||
const [username, domain] = playlist.value.user.full_username.split('@')
|
||||
return { username, domain }
|
||||
})
|
||||
|
||||
let navigate = (to: 'playlist' | 'user') => {}
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
const router = useRouter()
|
||||
navigate = (to: 'playlist' | 'user') => to === 'playlist'
|
||||
? router.push({ name: 'library.playlists.detail', params: { id: playlist.value.id } })
|
||||
: router.push({ name: 'profile.full', params: profileParams.value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<fw-card
|
||||
:title="playlist.name"
|
||||
@click="navigate('playlist')"
|
||||
class="playlist-card"
|
||||
>
|
||||
<template #image>
|
||||
<img
|
||||
v-for="src in covers"
|
||||
:key="src"
|
||||
:src="src"
|
||||
/>
|
||||
<div
|
||||
v-for="i in Math.max(0, 4 - covers.length)"
|
||||
:key="i"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<fw-play-button @play="play(playlist)" />
|
||||
|
||||
<a
|
||||
@click.stop="navigate('user')"
|
||||
class="funkwhale link"
|
||||
>
|
||||
{{ t('vui.by-user', playlist.user) }}
|
||||
</a>
|
||||
|
||||
<template #footer>
|
||||
{{ t('vui.tracks', playlist.tracks_count) }}
|
||||
<fw-options-button />
|
||||
</template>
|
||||
</fw-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style.scss'
|
||||
</style>
|
|
@ -0,0 +1,66 @@
|
|||
.funkwhale {
|
||||
&.card.playlist-card {
|
||||
|
||||
@include light-theme {
|
||||
> .card-image {
|
||||
> div {
|
||||
--fw-bg-color: var(--fw-pastel-blue-3);
|
||||
background-color: var(--fw-bg-color);
|
||||
&:nth-child(2) {
|
||||
--fw-bg-color: var(--fw-pastel-blue-1);
|
||||
}
|
||||
&:nth-child(3) {
|
||||
--fw-bg-color: var(--fw-pastel-blue-2);
|
||||
}
|
||||
&:nth-child(4) {
|
||||
--fw-bg-color: var(--fw-pastel-blue-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include dark-theme {
|
||||
> .card-image {
|
||||
> div {
|
||||
--fw-bg-color: var(--fw-pastel-blue-3);
|
||||
background-color: var(--fw-bg-color);
|
||||
&:nth-child(2) {
|
||||
--fw-bg-color: var(--fw-pastel-blue-1);
|
||||
}
|
||||
&:nth-child(3) {
|
||||
--fw-bg-color: var(--fw-pastel-blue-2);
|
||||
}
|
||||
&:nth-child(4) {
|
||||
--fw-bg-color: var(--fw-pastel-blue-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
--fw-border-radius: 12px;
|
||||
--fw-card-width: 208px;
|
||||
--fw-card-image-width: var(--fw-card-width);
|
||||
--fw-card-padding: 16px;
|
||||
|
||||
> .card-image {
|
||||
border-radius: 0 !important;
|
||||
width: var(--fw-card-image-width);
|
||||
margin: calc(-1 * var(--fw-card-padding)) calc(-1 * var(--fw-card-padding)) 0;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
> .card-title {
|
||||
font-size: 1rem;
|
||||
text-align: left !important;
|
||||
padding-top: 16px !important;
|
||||
}
|
||||
|
||||
> .card-content {
|
||||
padding-top: 0 !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<script setup lang="ts">
|
||||
import { FwCard, FwOptionsButton } from '~/components'
|
||||
import { useTimeAgo } from '@vueuse/core'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { Podcast } from '~/types/models'
|
||||
|
||||
const podcast = defineProp<Podcast>('podcast', { required: true })
|
||||
|
||||
const timeAgo = useTimeAgo(new Date(podcast.value.artist.modification_date))
|
||||
|
||||
let navigate = () => {}
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
const router = useRouter()
|
||||
navigate = () => router.push({ name: 'library.artists.detail', params: { id: podcast.value.artist.id } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<fw-card
|
||||
:title="podcast.name"
|
||||
:image="podcast.artist.cover.urls.original"
|
||||
@click="navigate"
|
||||
class="podcast-card"
|
||||
>
|
||||
<a
|
||||
@click.stop="navigate"
|
||||
class="funkwhale link"
|
||||
>
|
||||
{{ podcast.artist.name }}
|
||||
</a>
|
||||
|
||||
<template #footer>
|
||||
{{ timeAgo }}
|
||||
<fw-options-button />
|
||||
</template>
|
||||
</fw-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style.scss'
|
||||
</style>
|
|
@ -0,0 +1,23 @@
|
|||
.funkwhale {
|
||||
&.card.podcast-card {
|
||||
--fw-border-radius: 12px;
|
||||
--fw-card-width: 208px;
|
||||
--fw-card-image-width: var(--fw-card-width);
|
||||
--fw-card-padding: 16px;
|
||||
|
||||
> .card-image {
|
||||
--fw-border-radius: 10px;
|
||||
}
|
||||
|
||||
> .card-title {
|
||||
font-size: 1rem;
|
||||
text-align: left !important;
|
||||
padding-top: 20px !important;
|
||||
}
|
||||
|
||||
> .card-content {
|
||||
padding-top: 6px !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<script setup lang="ts">
|
||||
import { usePastel } from '~/composables/colors'
|
||||
import { FwCard, FwPlayButton } from '~/components'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { PastelProps } from '~/types/common-props'
|
||||
import type { Radio } from '~/types/models'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
interface Props {
|
||||
radio: Radio
|
||||
small?: boolean
|
||||
}
|
||||
|
||||
const play = defineEmit<[radio: Radio]>()
|
||||
const props = defineProps<Props & PastelProps>()
|
||||
|
||||
const pastel = usePastel(() => props.color)
|
||||
|
||||
let navigate = () => {}
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
const router = useRouter()
|
||||
navigate = () => router.push({ name: 'library.radios.detail', params: { id: props.radio.id } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<fw-card
|
||||
:title="radio.name"
|
||||
:class="pastel"
|
||||
@click="navigate"
|
||||
class="radio-card"
|
||||
>
|
||||
<template #image>
|
||||
<div class="cover-name">
|
||||
{{ t('vui.radio') }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<fw-play-button @play="play(props.radio)" />
|
||||
|
||||
<div
|
||||
v-if="!small"
|
||||
class="radio-description"
|
||||
>
|
||||
{{ radio.description }}
|
||||
</div>
|
||||
</fw-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style.scss'
|
||||
</style>
|
|
@ -0,0 +1,67 @@
|
|||
.funkwhale {
|
||||
&.card.radio-card {
|
||||
background: var(--fw-bg-color);
|
||||
|
||||
.radio-description {
|
||||
background: var(--fw-bg-color);
|
||||
color: var(--fw-text-color);
|
||||
}
|
||||
|
||||
@include light-theme {
|
||||
--fw-bg-color: var(--fw-pastel-3);
|
||||
--fw-text-color: var(--fw-gray-100);
|
||||
|
||||
.radio-description {
|
||||
--fw-bg-color: var(--fw-pastel-1);
|
||||
--fw-text-color: var(--fw-gray-900);
|
||||
}
|
||||
}
|
||||
|
||||
@include dark-theme {
|
||||
--fw-bg-color: var(--fw-pastel-4);
|
||||
--fw-text-color: var(--fw-gray-100);
|
||||
|
||||
.radio-description {
|
||||
--fw-bg-color: var(--fw-pastel-1);
|
||||
--fw-text-color: var(--fw-gray-900);
|
||||
}
|
||||
}
|
||||
--fw-border-radius: 12px;
|
||||
--fw-card-width: 208px;
|
||||
--fw-card-image-width: var(--fw-card-width);
|
||||
--fw-card-padding: 0;
|
||||
|
||||
text-align: left !important;
|
||||
|
||||
> .card-title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 16px 16px 0 !important;
|
||||
font-size: 2rem;
|
||||
white-space: initial;
|
||||
}
|
||||
|
||||
.cover-name {
|
||||
position: absolute;
|
||||
top: calc(var(--fw-card-width) - 16px);
|
||||
right: 16px;
|
||||
left: 16px;
|
||||
transform: translateY(-100%);
|
||||
|
||||
font-size: 1.5rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
> .card-content {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.radio-description {
|
||||
text-align: center;
|
||||
font-size: 0.875rem;
|
||||
padding: 16px 16px 22px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -225,6 +225,7 @@ const radioConfig = computed(() => {
|
|||
class="main pusher"
|
||||
>
|
||||
<section class="ui vertical stripe segment">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/audio/Search.vue
|
||||
<div
|
||||
v-if="id"
|
||||
class="ui small text container"
|
||||
|
|
|
@ -20,6 +20,7 @@ const defaultQuota = computed(() => humanSize(quota.value * 1e6))
|
|||
v-title="labels.title"
|
||||
class="ui vertical aligned stripe segment"
|
||||
>
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/audio/Search.vue
|
||||
<div class="ui text container">
|
||||
<h1>{{ labels.title }}</h1>
|
||||
<p>
|
||||
|
|
|
@ -41,6 +41,7 @@ const libraryCreated = (library: Library) => {
|
|||
|
||||
<template>
|
||||
<section class="ui vertical aligned stripe segment">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/components/audio/Search.vue
|
||||
<div
|
||||
v-if="isLoading"
|
||||
:class="['ui', {'active': isLoading}, 'inverted', 'dimmer']"
|
||||
|
|
|
@ -86,6 +86,7 @@ const updateUploads = (count: number) => {
|
|||
<template>
|
||||
<main v-title="labels.title">
|
||||
<div class="ui vertical stripe segment container">
|
||||
/Users/arnology/Sites/funkwhale/funkwhale/front/src/views/library/LibraryBase.vue
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="ui centered active inline loader"
|
||||
|
|
Loading…
Reference in New Issue