diff --git a/.woodpecker.yml b/.woodpecker.yml index 41c03da..0e3f437 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -6,7 +6,7 @@ pipeline: - npm run build when: path: - exclude: [ '*.md', '.gitea/*' ] + exclude: ['*.md', '.gitea/*'] event: ['push', 'pull_request'] docker: @@ -22,7 +22,7 @@ pipeline: when: branch: main path: - exclude: [ '*.md', '.gitea/*' ] + exclude: ['*.md', '.gitea/*'] event: ['push'] deploy: @@ -35,5 +35,5 @@ pipeline: when: branch: main path: - exclude: [ '*.md', '.gitea/*' ] + exclude: ['*.md', '.gitea/*'] event: ['push'] diff --git a/src/assets/version.json b/src/assets/version.json index 1bedf09..f479ccb 100644 --- a/src/assets/version.json +++ b/src/assets/version.json @@ -1,3 +1,3 @@ { - "date": "2022-12-13" + "date": "2022-12-31" } diff --git a/src/components/Artist.vue b/src/components/Artist.vue index 62710a0..6becdcd 100644 --- a/src/components/Artist.vue +++ b/src/components/Artist.vue @@ -13,11 +13,19 @@ const subs = JSON.parse(store.subs ? store.subs : '[]'), hash = artist.state.hash, isSub = ref(subs.includes(hash)); -function addSub() { - if (artist.state.title && !isSub.value) { - subs.push(hash); - store.setItem('subs', JSON.stringify(subs)); - isSub.value = true; +function Sub() { + if (artist.state.title) { + if (isSub.value) { + subs.splice(subs.indexOf(hash), 1); + store.setItem('subs', JSON.stringify(subs)); + isSub.value = false; + } else { + subs.push(hash); + store.setItem('subs', JSON.stringify(subs)); + isSub.value = true; + } + + alert(JSON.stringify(subs)); } } @@ -35,7 +43,7 @@ function addSub() { @click=" results.getAlbum('/playlist?list=' + artist.state.playlistId) " /> - {{ + {{ artist.state.subscriberCount || 0 }} diff --git a/src/components/NewPlaylist.vue b/src/components/NewPlaylist.vue index 5614d73..e61e4a3 100644 --- a/src/components/NewPlaylist.vue +++ b/src/components/NewPlaylist.vue @@ -62,7 +62,7 @@ const Open = key => { results.resetItems(); results.setItem('songs', { title: 'Local • ' + key, - items: res.urls.map(i => ({ ...i, ...{ thumbnail: '/1x1.png' } })), + items: res.urls.map(i => ({ ...i, ...{ playlistId: key } })), }); nav.state.page = 'home'; diff --git a/src/components/Search.vue b/src/components/Search.vue index 84c7aa8..4ba39cd 100644 --- a/src/components/Search.vue +++ b/src/components/Search.vue @@ -7,7 +7,7 @@ import AlbumItem from './AlbumItem.vue'; import { getJsonPiped, getPipedQuery } from '@/scripts/fetch.js'; import { useRoute, useWrap } from '@/scripts/util.js'; -import { useCreatePlaylist } from '@/scripts/db.js'; +import { useCreatePlaylist, useRemovePlaylist } from '@/scripts/db.js'; import { useResults, useArtist } from '@/stores/results.js'; import { useData } from '@/stores/player.js'; @@ -48,6 +48,32 @@ const shuffleAdd = () => { emit('play-urls', copy); }, + openSong = (song, nxt = false) => { + if (results.items?.songs?.title && !nxt) { + data.state.urls = results.items.songs.items.map(i => ({ + url: i.url || '/watch?v=' + song.id, + title: i.title, + thumbnails: [{ url: i.thumbnail }], + })); + + data.getSong(song.url || '/watch?v=' + song.id); + } else { + emit('play-urls', [ + { + url: song.url || '/watch?v=' + song.id, + title: song.title || song.name, + thumbnails: [ + { + url: + song.thumbnail || + song.thumbnails[1]?.url || + song.thumbnails[0]?.url, + }, + ], + }, + ]); + } + }, removeSong = i => { console.log(i); @@ -222,6 +248,15 @@ onDeactivated(() => { + + @@ -259,25 +294,14 @@ onDeactivated(() => { :channel="song.uploaderUrl || '/channel/' + song.subId" :play="song.url || '/watch?v=' + song.id" :art=" - song.thumbnail || song.thumbnails[1]?.url || song.thumbnails[0]?.url + song.thumbnail || + song.thumbnails?.[1]?.url || + song.thumbnails?.[0]?.url || + '/1x1.png' " @remove="removeSong" - @open-song=" - $emit('play-urls', [ - { - url: song.url || '/watch?v=' + song.id, - title: song.title || song.name, - thumbnails: [ - { - url: - song.thumbnail || - song.thumbnails[1]?.url || - song.thumbnails[0]?.url, - }, - ], - }, - ]) - " /> + @open-song="openSong(song)" + @nxt-song="openSong(song, true)" /> { emit('open-song', props.play); }, Remove = () => { - const auth = useStore().getItem('auth'); + const auth = useStore().getItem('auth'), + isRemote = results.items?.songs?.title?.startsWith('Playlist - '); - if (auth && confirm('Are you sure?')) { + if (!confirm('Are you sure?')) return; + + if (isRemote && auth) { getJsonAuth('/user/playlists/remove', { method: 'POST', headers: { @@ -68,7 +73,10 @@ const openSong = el => { if (json.message == 'ok') emit('remove', props.index); } else alert(json.error); }); - } + } else + useUpdatePlaylist(props.playlistId, props.index, () => + emit('remove', props.index), + ); }, Share = async () => { if ('share' in navigator) { @@ -119,11 +127,11 @@ onMounted(() => { @mouseleave="show = false"> diff --git a/src/scripts/db.js b/src/scripts/db.js index 3f25ca1..90b8339 100644 --- a/src/scripts/db.js +++ b/src/scripts/db.js @@ -40,7 +40,8 @@ export function useUpdatePlaylist(key, obj, cb = () => null) { const itm = e.target.result; if (itm) { - itm.urls.push(obj); + if ('number' == typeof obj) itm.urls.splice(obj, 1); + else if ('object' == typeof obj) itm.urls.push(obj); store.put(itm); cb(true); } @@ -77,6 +78,23 @@ export function useCreatePlaylist(key, obj, cb = () => null) { } else alert('No indexedDB Created'); } +export function useRemovePlaylist(key, cb = () => null) { + if (window.db && key) { + const store = window.db + .transaction(['playlist'], 'readwrite') + .objectStore('playlist'), + req = store.delete(key); + + req.onerror = e => { + console.error('Error removing playlist ', e); + }; + + req.onsuccess = () => { + cb(); + }; + } +} + export function useGetPlaylist(key, cb = () => null) { if (window.db && key) { const store = window.db.transaction(['playlist']).objectStore('playlist'),