Skip to content
Snippets Groups Projects
Commit b6b1ec13 authored by Kasper Seweryn's avatar Kasper Seweryn 🥞
Browse files

Add activity card

parent fb7356b1
No related branches found
No related tags found
1 merge request!1Implement all components
Pipeline #23482 failed with stages
in 2 minutes and 50 seconds
......@@ -27,6 +27,7 @@ export default defineConfig({
{ text: "Playlist Card", link: "/components/card/playlist" },
{ text: "Podcast Card", link: "/components/card/podcast" },
] },
{ text: "Activity", link: "/components/activity/" },
]
}
]
......
<script setup lang="ts">
const track = {
name: 'Some lovely track',
artist: {
name: 'Artist'
},
cover: {
urls: {
original: 'https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb'
}
}
}
const user = {
username: 'username'
}
</script>
# Activity
```html
<fw-activity :track="track" :user="user" />
```
<fw-activity :track="track" :user="user" />
::: info
Whenever there is more than 1 activity entry in a row, there would be a 1px border to separate the entries
:::
```html
<fw-activity :track="track" :user="user" v-for="i in 3" :key="i" />
```
<fw-activity :track="track" :user="user" v-for="i in 3" :key="i" />
<script setup lang="ts">
import { FwOptionsButton, FwPlayButton } from '~/components'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
const { t } = useI18n()
interface Track {
id: number
name: string
artist: {
id: number
name: string
}
cover: {
urls: {
original: string
}
}
}
interface User {
username: string
full_username: string
}
interface Events {
(e: 'play', track: Track): void
}
interface Props {
track: Track
user: User
}
const emit = defineEmits<Events>()
const props = defineProps<Props>()
const profileParams = computed(() => {
const [username, domain] = props.user.full_username.split('@')
return { username, domain }
})
let navigate = (to: 'track' | 'artist' | 'user') => {}
if (import.meta.env.PROD) {
const router = useRouter()
navigate = (to: 'track' | 'artist' | 'user') => to === 'track'
? router.push({ name: 'library.tracks.detail', params: { id: props.track.id } })
: to === 'artist'
? router.push({ name: 'library.artists.detail', params: { id: props.track.artist.id } })
: router.push({ name: 'profile.full', params: profileParams.value })
}
</script>
<template>
<div
class="funkwhale activity"
@click="navigate('track')"
>
<div class="activity-image">
<img :src="track.cover.urls.original" />
<fw-play-button
@play="emit('play', track)"
:round="false"
:shadow="false"
/>
</div>
<div class="activity-content">
<div class="track-title">{{ track.name }}</div>
<a
@click.stop="navigate('artist')"
class="funkwhale link artist"
>
{{ track.artist.name }}
</a>
<a
@click.stop="navigate('user')"
class="funkwhale link user"
>
{{ t('vui.by-user', { username: user.username}) }}
</a>
</div>
<div>
<fw-options-button />
</div>
</div>
</template>
<style lang="scss">
@import './style.scss'
</style>
.funkwhale {
&.activity {
padding: 12px 6px;
color: var(--fw-gray-500);
cursor: pointer;
display: grid;
grid-template-columns: auto 1fr auto;
gap: 12px;
+ .funkwhale.activity {
border-top: 1px solid var(--fw-grey-300);
}
> .activity-image {
position: relative;
width: 40px;
aspect-ratio: 1;
overflow: hidden;
border-radius: var(--fw-border-radius);
> img {
width: 100%;
aspect-ratio: 1;
object-fit: cover;
}
> .play-button {
position: absolute;
top: 0;
left: 0;
width: 100%;
aspect-ratio: 1;
margin: 0;
background: rgba(255, 255, 255, .5);
border: 0;
opacity: 0;
}
}
&:hover {
.play-button {
opacity: 1;
}
}
> .activity-content {
display: flex;
flex-direction: column;
align-items: flex-start;
> .track-title {
color: var(--fw-grey-900);
font-weight: 700;
line-height: 1.5em;
html.dark & {
color: var(--fw-grey-300);
}
}
> .artist {
--fw-link-color: var(--fw-grey-900);
line-height: 1.5em;
font-size: 0.857rem;
html.dark & {
--fw-link-color: var(--fw-grey-300);
}
}
> .user {
--fw-link-color: var(--fw-grey-500);
line-height: 1.5em;
font-size: 0.8125rem;
}
}
}
}
......@@ -72,7 +72,7 @@ if (import.meta.env.PROD) {
@click.stop="navigate('user')"
class="funkwhale link"
>
{{ t('vui.playlist-by', playlist.user) }}
{{ t('vui.by-user', playlist.user) }}
</a>
<template #footer>
......
......@@ -11,6 +11,8 @@ export { default as FwAlbumCard } from './card/album/Card.vue'
export { default as FwRadioCard } from './card/radio/Card.vue'
export { default as FwCard } from './card/Card.vue'
export { default as FwActivity } from './activity/Activity.vue'
// Pills
export { default as FwPill } from './pill/Pill.vue'
......
......@@ -3,4 +3,4 @@ vui:
albums: '{n} album | {n} albums'
tracks: '{n} track | {n} tracks'
episodes: '{n} episode | {n} episodes'
playlist-by: 'by {username}'
by-user: "by {'@'}{username}"
......@@ -5,6 +5,7 @@ a {
&:not(.VPLink):not(.vp-doc .header-anchor):not(.VPDocAsideOutline .outline-link):not(.VPNavBarTitle .title):not(.VPDocFooter .pager-link) {
color: var(--fw-link-color);
cursor: pointer;
&:hover,
&.is-hovered {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment