- Removing Local playlists and playlist items
- Unsubscribe from feeds
- Closes #56
- Closes #85
This commit is contained in:
Shiny Nematoda 2022-12-31 19:23:14 +00:00
parent affb0e33f6
commit 7cc847146d
7 changed files with 94 additions and 36 deletions

View file

@ -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']

View file

@ -1,3 +1,3 @@
{
"date": "2022-12-13"
"date": "2022-12-31"
}

View file

@ -13,12 +13,20 @@ 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) {
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));
}
}
</script>
@ -35,7 +43,7 @@ function addSub() {
@click="
results.getAlbum('/playlist?list=' + artist.state.playlistId)
" />
<span class="us-box subs" :data-active="isSub" @click="addSub">{{
<span class="us-box subs" :data-active="isSub" @click="Sub">{{
artist.state.subscriberCount || 0
}}</span>
</div>

View file

@ -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';

View file

@ -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(() => {
<button
class="bi bi-shuffle clickable"
@click="shuffleAdd"></button>
<button
v-if="results.items?.songs?.title.startsWith('Local • ')"
class="bi bi-trash3 clickable"
@click="
useRemovePlaylist(
results.items?.songs?.title?.replace('Local • ', ''),
)
"></button>
</div>
</Transition>
</template>
@ -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)" />
</div>
<a
v-if="artist.state.playlistId"

View file

@ -4,12 +4,14 @@ import { ref, onMounted } from 'vue';
import { getJsonAuth } from '@/scripts/fetch.js';
import { useRand } from '@/scripts/colors.js';
import { useStore } from '@/scripts/util.js';
import { useUpdatePlaylist } from '@/scripts/db.js';
import { useArtist } from '@/stores/results.js';
import { useResults, useArtist } from '@/stores/results.js';
import { useData, usePlayer } from '@/stores/player.js';
const rand = useRand(),
data = useData(),
results = useResults(),
player = usePlayer(),
artist = useArtist();
@ -22,7 +24,7 @@ const props = defineProps({
art: String,
playlistId: String,
}),
emit = defineEmits(['open-song', 'remove']);
emit = defineEmits(['open-song', 'nxt-song', 'remove']);
const show = ref(false);
@ -49,9 +51,12 @@ const openSong = el => {
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">
<Transition name="fade">
<div v-if="show" class="popup ign">
<!-- TODO: Check if user is admin -->
<span
v-if="playlistId"
class="bi bi-dash-lg clickable ign"
@click="Remove"></span>
<span class="bi bi-broadcast ign" @click="$emit('nxt-song')"></span>
<span class="bi bi-plus-lg clickable ign" @click="addSong"></span>
<span class="bi bi-share clickable ign" @click="Share"></span>
</div>

View file

@ -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'),