Skip to content

Commit 3e2d9e4

Browse files
committed
feat: new lyrics editor and tests
1 parent 4d8fa2b commit 3e2d9e4

12 files changed

Lines changed: 722 additions & 67 deletions

File tree

package-lock.json

Lines changed: 53 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"devDependencies": {
3535
"@7nohe/laravel-typegen": "^0.6.1",
3636
"@eslint/js": "^9.7.0",
37+
"@faker-js/faker": "^9.8.0",
3738
"@iconify-json/cil": "^1.2.2",
3839
"@iconify-json/circum": "^1.1.11",
3940
"@iconify-json/formkit": "^1.2.2",
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<script setup lang="ts">
2+
import type { LrcLibResult } from '@/types/types';
3+
4+
import { toFormattedDuration } from '@/service/util';
5+
import { useLyricStore } from '@/stores/LyricStore';
6+
import { storeToRefs } from 'pinia';
7+
import { computed } from 'vue';
8+
9+
import ButtonIcon from '@/components/inputs/ButtonIcon.vue';
10+
import ChipTag from '@/components/labels/ChipTag.vue';
11+
12+
import ProiconsEye from '~icons/proicons/eye';
13+
import PrimeSave from '~icons/prime/save';
14+
15+
const { dirtyLyric } = storeToRefs(useLyricStore());
16+
17+
const props = defineProps<{ data: LrcLibResult }>();
18+
const emit = defineEmits(['preview', 'select']);
19+
20+
const tags = computed(() => {
21+
return [
22+
{
23+
name: toFormattedDuration(props.data.duration),
24+
},
25+
{
26+
name: props.data.syncedLyrics ? 'Synced' : 'Plain',
27+
class: props.data.syncedLyrics ? '!bg-violet-600 dark:!bg-white dark:text-neutral-900 shadow-md' : '!bg-neutral-800 opacity-70',
28+
},
29+
];
30+
});
31+
</script>
32+
<template>
33+
<div
34+
:class="[
35+
'relative flex flex-wrap justify-between items-center gap-2',
36+
'rounded-lg shadow p-3 w-full transition',
37+
'bg-neutral-50 dark:bg-primary-dark-800/70 dark:hover:bg-violet-700/70 hover:bg-primary-800',
38+
'text-neutral-600 dark:text-neutral-100',
39+
`ring-[0.125rem] ${data.id === dirtyLyric?.id ? 'ring-violet-700/60' : 'ring-transparent dark:ring-neutral-700/20'}`,
40+
]"
41+
>
42+
<section class="flex justify-between gap-2 w-full items-center">
43+
<h3 class="flex-1 truncate min-w-[30%] text-gray-900 dark:text-white" :title="data.trackName">
44+
{{ data.trackName }}
45+
</h3>
46+
<ButtonIcon
47+
class="!h-6 !w-6 ring-0 transition !p-1 rounded-md"
48+
type="button"
49+
:variant="'transparent'"
50+
:title="data.id === dirtyLyric?.id ? 'Already Selected' : 'Select'"
51+
:disabled="data.id === dirtyLyric?.id"
52+
@click="$emit('select')"
53+
>
54+
<template #icon>
55+
<PrimeSave class="w-4 h-4" />
56+
</template>
57+
</ButtonIcon>
58+
<ButtonIcon
59+
v-if="data.syncedLyrics"
60+
class="!h-6 !w-6 ring-0 transition !p-1 rounded-md"
61+
type="button"
62+
:variant="'transparent'"
63+
:title="'Preview'"
64+
@click="$emit('preview')"
65+
>
66+
<template #icon>
67+
<ProiconsEye class="w-4 h-4" />
68+
</template>
69+
</ButtonIcon>
70+
</section>
71+
<section class="flex flex-wrap justify-between gap-x-4 gap-y-2 w-full items-start text-sm">
72+
<span class="flex gap-2 items-center w-full flex-1">
73+
<span class="flex gap-1 truncate flex-1">
74+
<h4 class="text-nowrap text-start truncate" title="Album">
75+
{{ data.albumName }}
76+
</h4>
77+
78+
<h4>-</h4>
79+
<h4 class="text-ellipsis text-wrap line-clamp-1 min-w-fit" title="Artist">
80+
{{ data.artistName }}
81+
</h4>
82+
</span>
83+
84+
<span class="hidden sm:flex gap-1 max-h-[22px] justify-end overflow-clip [overflow-clip-margin:4px]">
85+
<ChipTag
86+
v-for="(tag, index) in tags"
87+
:key="index"
88+
:label="tag.name"
89+
:textClass="'text-xs'"
90+
:colour="
91+
tag.class ??
92+
'bg-neutral-200 leading-none text-neutral-500 shadow dark:bg-neutral-900 hover:bg-violet-600 hover:text-neutral-50 hover:dark:bg-violet-600/90'
93+
"
94+
/>
95+
</span>
96+
</span>
97+
98+
<span class="sm:hidden w-full flex flex-wrap gap-1 overflow-clip [overflow-clip-margin:4px]">
99+
<ChipTag
100+
v-for="(tag, index) in tags"
101+
:key="index"
102+
:label="tag.name"
103+
:textClass="'text-xs'"
104+
:colour="
105+
tag.class ?? 'bg-neutral-200 leading-none text-neutral-500 shadow dark:bg-neutral-900 hover:bg-violet-600 hover:text-neutral-50 hover:dark:bg-violet-600/90'
106+
"
107+
/>
108+
</span>
109+
</section>
110+
</div>
111+
</template>

0 commit comments

Comments
 (0)