mirror of
https://codeberg.org/Hyperpipe/Hyperpipe
synced 2025-06-27 20:58:01 +02:00
parent
212a0e6dd6
commit
b023b67e04
10 changed files with 502 additions and 325 deletions
743
package-lock.json
generated
743
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -10,12 +10,12 @@
|
|||
"lint": "prettier --check ."
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap-icons": "^1.10.5",
|
||||
"bootstrap-icons": "^1.11.1",
|
||||
"dompurify": "^3.0.5",
|
||||
"mux.js": "^6.3.0",
|
||||
"peerjs": "^1.4.7",
|
||||
"peerjs": "^1.5.0",
|
||||
"pinia": "^2.1.6",
|
||||
"shaka-player": "^4.4.0",
|
||||
"shaka-player": "^4.4.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"vue": "^3.2.38"
|
||||
},
|
||||
|
@ -23,6 +23,6 @@
|
|||
"@vitejs/plugin-vue": "^4.3.4",
|
||||
"prettier": "^3.0.3",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-pwa": "^0.16.4"
|
||||
"vite-plugin-pwa": "^0.16.5"
|
||||
}
|
||||
}
|
||||
|
|
26
src/App.vue
26
src/App.vue
|
@ -93,6 +93,31 @@ function parseUrl() {
|
|||
}
|
||||
}
|
||||
|
||||
function setupKeys() {
|
||||
window.addEventListener('keydown', e => {
|
||||
if (
|
||||
!e.shiftKey ||
|
||||
e.repeat ||
|
||||
'string' == typeof e.target.value
|
||||
) return
|
||||
|
||||
switch (e.code) {
|
||||
case 'Space':
|
||||
player.toggle('play')
|
||||
break;
|
||||
case 'Slash':
|
||||
nav.show()
|
||||
break;
|
||||
case 'KeyN':
|
||||
data.nextTrack()
|
||||
break;
|
||||
case 'KeyP':
|
||||
data.prevTrack()
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function playThis(t) {
|
||||
const i = data.state.urls.indexOf(t);
|
||||
data.play(data.state.urls[i]);
|
||||
|
@ -134,6 +159,7 @@ onMounted(() => {
|
|||
/* Setup IndexedDB for storing custom playlists */
|
||||
useSetupDB();
|
||||
|
||||
setupKeys();
|
||||
parseUrl();
|
||||
|
||||
console.log('Mounted <App>!');
|
||||
|
|
|
@ -10,7 +10,8 @@ import { useAlert } from '@/stores/misc';
|
|||
|
||||
const player = usePlayer(),
|
||||
data = useData(),
|
||||
store = useStore();
|
||||
store = useStore(),
|
||||
a = useAlert();
|
||||
|
||||
const audio = ref(null);
|
||||
|
||||
|
@ -61,7 +62,7 @@ async function Stream() {
|
|||
window.offline = new shaka.offline.Storage(audioPlayer);
|
||||
window.offline.configure({
|
||||
offline: {
|
||||
progressCallback: (data, prog) => console.log(data, prog),
|
||||
progressCallback: ({ appMetadata: { title, artist } }, prog) => a.add(`${title} by ${artist}: ${Math.floor(prog*100)}%`),
|
||||
trackSelectionCallback: tracks => [
|
||||
tracks
|
||||
.sort((a, b) => a.bandwidth - b.bandwidth)
|
||||
|
@ -112,7 +113,7 @@ async function Stream() {
|
|||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
useAlert.add('error: ' + e.code);
|
||||
a.add('Error: ' + err.code);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,38 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useNav, useI18n } from '@/stores/misc.js';
|
||||
|
||||
const { t } = useI18n(),
|
||||
show = ref(false),
|
||||
nav = useNav();
|
||||
nav = useNav(),
|
||||
searchEl = ref(null);
|
||||
|
||||
function search(e) {
|
||||
nav.state.search = e.target.value;
|
||||
nav.state.page = 'home';
|
||||
e.target.blur();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => nav.state.show,
|
||||
e => {
|
||||
if (e === true) setTimeout(() => searchEl.value.focus(), 0)
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
class="bi bi-search popup-wrap"
|
||||
@mouseenter="show = true"
|
||||
@mouseleave="show = false"
|
||||
@keydown.enter="show = !show">
|
||||
@mouseenter="nav.state.show = true"
|
||||
@mouseleave="nav.state.show = false"
|
||||
@keydown.enter="nav.show()">
|
||||
<Transition name="fade">
|
||||
<div v-show="show" class="popup">
|
||||
<div v-show="nav.state.show" class="popup">
|
||||
<input
|
||||
type="search"
|
||||
ref="searchEl"
|
||||
name="searchEl"
|
||||
aria-label="Search Input"
|
||||
:placeholder="t('title.search') + '...'"
|
||||
@change="search"
|
||||
|
|
|
@ -9,12 +9,13 @@ import {
|
|||
} from '@/scripts/fetch.js';
|
||||
|
||||
import { useData, usePlayer } from '@/stores/player.js';
|
||||
import { useI18n } from '@/stores/misc.js';
|
||||
import { useI18n, useAlert } from '@/stores/misc.js';
|
||||
|
||||
const { t } = useI18n(),
|
||||
data = useData(),
|
||||
player = usePlayer(),
|
||||
store = useStore();
|
||||
store = useStore(),
|
||||
a = useAlert();
|
||||
|
||||
const showme = reactive({
|
||||
menu: false,
|
||||
|
@ -44,8 +45,11 @@ async function Offline() {
|
|||
url: data.state.url,
|
||||
artist: data.state.artist,
|
||||
artistUrl: data.state.artistUrl,
|
||||
}).promise.catch(e => {
|
||||
console.error(e)
|
||||
a.add('Error: ' + e.code)
|
||||
});
|
||||
} else console.error('no offline storage found');
|
||||
} else a.add('offline storage not found');
|
||||
}
|
||||
|
||||
async function Like() {
|
||||
|
|
|
@ -12,7 +12,7 @@ export function useDash(streams, len) {
|
|||
else {
|
||||
mimeTypes.push(stream.mimeType);
|
||||
mimes.push([]);
|
||||
mimes.at(-1).push(stream);
|
||||
mimes[mimeTypes.length - 1].push(stream);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ function useElems(json) {
|
|||
export function useXML(json) {
|
||||
json = JSON.parse(JSON.stringify(json));
|
||||
|
||||
let xml = '<?xml version="1.0" encoding="utf-8" ?>';
|
||||
let xml = '<?xml version="1.0" encoding="utf-8"?>';
|
||||
xml += useElems(json);
|
||||
|
||||
return xml;
|
||||
|
|
|
@ -139,9 +139,12 @@ export const useNav = defineStore('nav', () => {
|
|||
const state = reactive({
|
||||
search: '',
|
||||
page: 'home',
|
||||
show: false,
|
||||
});
|
||||
|
||||
return { state };
|
||||
const show = () => state.show = !state.show
|
||||
|
||||
return { state, show };
|
||||
});
|
||||
|
||||
export const useI18n = defineStore('i18n', () => {
|
||||
|
|
|
@ -95,7 +95,7 @@ export const useData = defineStore('data', () => {
|
|||
}
|
||||
}
|
||||
|
||||
function playNext(u) {
|
||||
function playNext() {
|
||||
const i = state.urls.findIndex(s => s.url === state.url);
|
||||
|
||||
if (player.state.loop == 2) getSong(state.url);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue