Skip to content
Snippets Groups Projects
Commit 5d4a4ca1 authored by Christoph Stahl's avatar Christoph Stahl
Browse files

Code cleanup and implemented the last missing features (i think)

parent bb1a0e65
Branches
No related tags found
No related merge requests found
Showing
with 348 additions and 187 deletions
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title> <title>Syng Rocks!</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
......
public/favicon.ico

4.19 KiB | W: 32px | H: 32px

public/favicon.ico

4.56 KiB | W: 128px | H: 128px

public/favicon.ico
public/favicon.ico
public/favicon.ico
public/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
...@@ -7,6 +7,8 @@ import $ from 'jquery' ...@@ -7,6 +7,8 @@ import $ from 'jquery'
import MobileLayout from './components/MobileLayout.vue' import MobileLayout from './components/MobileLayout.vue'
import DesktopLayout from './components/DesktopLayout.vue' import DesktopLayout from './components/DesktopLayout.vue'
import WelcomeReveal from './components/WelcomeReveal.vue' import WelcomeReveal from './components/WelcomeReveal.vue'
import GetUserName from './components/GetUserName.vue'
import Footer from './components/Footer.vue'
const router = useRouter() const router = useRouter()
...@@ -23,6 +25,9 @@ const state = ref({ ...@@ -23,6 +25,9 @@ const state = ref({
'secret': undefined, 'secret': undefined,
'current_entry': undefined, 'current_entry': undefined,
'current_name': undefined, 'current_name': undefined,
'searching': false,
'last_msg': "",
'join_msg': undefined
}) })
onMounted(() => { onMounted(() => {
...@@ -39,13 +44,17 @@ function setServer(server) { state.value.server = server } ...@@ -39,13 +44,17 @@ function setServer(server) { state.value.server = server }
function setSearchTerm(searchTerm) { state.value.search.searchTerm = searchTerm } function setSearchTerm(searchTerm) { state.value.search.searchTerm = searchTerm }
function search() { function search() {
state.value.searching = true
state.socket.emit("search", {"query": state.value.search.searchTerm }) state.socket.emit("search", {"query": state.value.search.searchTerm })
} }
function append(entry) {_append(entry, state.value.name) } function append(entry) {
_append(entry, state.value.name)
}
function _append(entry, name) { function _append(entry, name) {
if(name == "" || name == undefined) { if(name == "" || name == undefined) {
state.value.current_entry = entry state.value.current_entry = entry
state.value.current_name = ""
$("#getusername").foundation("open") $("#getusername").foundation("open")
} else { } else {
$("#getusername").foundation("close") $("#getusername").foundation("close")
...@@ -55,13 +64,32 @@ function _append(entry, name) { ...@@ -55,13 +64,32 @@ function _append(entry, name) {
} }
} }
function close_name() {
$("#getusername").foundation("close")
state.value.current_entry = undefined
state.value.current_name = undefined
}
function connect() { function connect() {
state.socket = io(state.value.server) state.socket = io(state.value.server)
registerSocketEvents(state.socket) registerSocketEvents(state.socket)
} }
function skipCurrent() {
state.socket.emit("skip-current")
}
function moveUp(uuid) {
state.socket.emit("moveUp", {"uuid": uuid})
}
function skip(uuid) {
state.socket.emit("skip", {"uuid": uuid})
}
function registerSocketEvents(socket) { function registerSocketEvents(socket) {
socket.on("search-results", (results) => { socket.on("search-results", (results) => {
state.value.searching = false
state.value.search.searchResults = results.results state.value.search.searchResults = results.results
}) })
...@@ -75,6 +103,11 @@ function registerSocketEvents(socket) { ...@@ -75,6 +103,11 @@ function registerSocketEvents(socket) {
socket.on("register-admin", (response) => { socket.on("register-admin", (response) => {
state.value.admin = response.success state.value.admin = response.success
}) })
socket.on("msg", (response) => {
state.value.last_msg = response.msg
$("#msg").foundation("open")
})
} }
function joinRoom() { function joinRoom() {
...@@ -86,59 +119,90 @@ function joinRoom() { ...@@ -86,59 +119,90 @@ function joinRoom() {
state.socket.emit("register-admin", {"secret": state.value.secret}) state.socket.emit("register-admin", {"secret": state.value.secret})
} }
} else { } else {
console.log("no such room") state.value.join_msg = "<strong>No such room!</strong> <br/>" +
"Please use the correct room code your organizer provided you.<br/>" +
"To host your own syng powered karaoke parties, please download and " +
"install <a href='https://git.k-fortytwo.de/christofsteel/syng2.git' " +
"target='_blank'>Syng</a> and run it with <pre>syng-client " +
state.value.server + "</pre>"
} }
}) })
} }
</script> </script>
<script>
</script>
<template> <template>
<div class="page"> <div class="page">
<div class="row" id="main-content"> <div class="row" id="main-content">
<MobileLayout v-show="state.is_small" :state="state" @update:searchTerm="setSearchTerm" @search="search" @append="append" /> <MobileLayout
<DesktopLayout v-show="!state.is_small" :state="state" @update:searchTerm="setSearchTerm" @search="search" @append="append" /> v-show="state.is_small"
<WelcomeReveal v-if="!state.joined" :room="state.room" :server="state.server" @connect="connect" @update:room="setRoomCode" @update:name="setName" @update:server="setServer" @update:secret="setSecret" /> :state="state"
<div class="reveal" id="getusername" data-reveal data-close-on-esc="false" data-close-on-click="false" > @update:searchTerm="setSearchTerm"
<h1>Please enter your name</h1> @search="search"
<label>Name @append="append"
<input type="text" @input="(evt) => setCurrentName(evt.target.value)" placeholder="Arno Nym"> @skip="skip"
</label> @skipCurrent="skipCurrent"
<button class="button" @click="() => _append(state.current_entry, state.current_name)">Ok</button> @moveUp="moveUp"
<button class="button" @click="append">Abort</button> />
<DesktopLayout
v-show="!state.is_small"
:state="state"
@update:searchTerm="setSearchTerm"
@search="search"
@append="append"
@skip="skip"
@skipCurrent="skipCurrent"
@moveUp="moveUp"
/>
<WelcomeReveal
v-if="!state.joined"
:room="state.room"
:server="state.server"
:joinMsg="state.join_msg"
@connect="connect"
@update:room="setRoomCode"
@update:name="setName"
@update:server="setServer"
@update:secret="setSecret"
/>
<GetUserName
:current_name="state.current_name"
:current_entry="state.current_entry"
@update:currentName="setCurrentName"
@append="_append(state.current_entry, state.current_name)"
@close_name="close_name"
/>
<div class="reveal" id="msg" data-reveal>
{{ state.last_msg }}
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
</div> </div>
<footer> <Footer
Name: <span class="userName" @focusout="(evt) => setName(evt.target.textContent)" contenteditable>{{ state.name }}</span> :name="state.name"
</footer> @update:name="setName"
/>
</div> </div>
</template> </template>
<style scoped> <style scoped>
footer { .page {
position: fixed; height:100vh;
bottom: 0; background: url('assets/syng.png') fixed;
height: 50px; background-color: #8a8a8a;
line-height: 50px; background-size: auto 50%;
width: 100%; background-repeat: no-repeat;
padding-left: 10px; background-position: center;
background-color: #008000; }
font-weight: bold;
color: #ffffff; .page {
font-size: 1.5rem; height: 100%;
margin: auto; position: relative;
} }
footer > .userName {
border: none;
border-bottom: 1px dashed #00F000;
background-color: #008000;
min-width: 5em;
display: inline-block;
height: 70%;
text-align: center;
#main-content {
height: calc(100vh - 50px);
max-height: 100vh;
max-width: 100vw;
} }
</style> </style>
...@@ -9,15 +9,6 @@ li { ...@@ -9,15 +9,6 @@ li {
max-width: 100% !important; max-width: 100% !important;
} }
body {
height:100vh;
}
.page {
height: 100%;
position: relative;
}
.header { .header {
background-color: #008000; background-color: #008000;
font-weight: bold; font-weight: bold;
...@@ -30,11 +21,6 @@ body { ...@@ -30,11 +21,6 @@ body {
margin-bottom: .5rem; margin-bottom: .5rem;
} }
.splitter {
display: flex;
height: 100%;
}
.comp-column { .comp-column {
max-height: 100vh; max-height: 100vh;
flex:1; flex:1;
...@@ -42,29 +28,6 @@ body { ...@@ -42,29 +28,6 @@ body {
flex-direction: column; flex-direction: column;
} }
#left-side {
margin: 0.2em 0.1em 0.2em 0.2em;
}
#middle {
margin: 0.2em 0.1em 0.1em 0.2em;
}
#right-side {
margin: 0.2em 0.2em 0.1em 0.2em;
}
#main-content {
height: calc(100vh - 50px);
max-height: 100vh;
max-width: 100vw;
}
.tabs-container {
flex: 1;
position: relative;
overflow: auto;
}
.tabs-panel { .tabs-panel {
height: 100%; height: 100%;
} }
...@@ -80,10 +43,6 @@ body { ...@@ -80,10 +43,6 @@ body {
overflow-y: auto; overflow-y: auto;
} }
#recent {
flex-direction: column-reverse;
}
.performer, .album { .performer, .album {
font-size: smaller; font-size: smaller;
font-style: italic; font-style: italic;
...@@ -93,10 +52,6 @@ body { ...@@ -93,10 +52,6 @@ body {
font-weight: bold; font-weight: bold;
} }
.input-group {
margin-bottom: 0;
}
.menu li { .menu li {
padding:0.4em; padding:0.4em;
} }
...@@ -105,13 +60,6 @@ body { ...@@ -105,13 +60,6 @@ body {
padding: 0; padding: 0;
} }
#search-results div {
vertical-align: middle;
height: 100%
}
.tabs-panel { .tabs-panel {
padding: 0; padding: 0;
} }
...@@ -124,33 +72,13 @@ body { ...@@ -124,33 +72,13 @@ body {
background-color: #f6f6f6; background-color: #f6f6f6;
} }
.current {
background-color: #008000 !important;
}
.button, button:focus { .button, button:focus {
background-color: #008000; background-color: #008000;
} }
#recent .eta {
display: none;
.current::before, #large-current::before{
content: "Now Playing";
text-align: center;
font-weight: bold;
}
.eta {
float: right;
}
.eta::before {
content: "in ";
}
.eta::after {
content: " min";
} }
.artist::after{ .artist::after{
...@@ -161,19 +89,6 @@ body { ...@@ -161,19 +89,6 @@ body {
background-color: #3b3b3b; background-color: #3b3b3b;
} }
body {
background: url(syng.png) fixed;
background-color: #8a8a8a;
background-size: auto 50%;
background-repeat: no-repeat;
background-position: center;
}
.warning {
padding: 10px;
background-color: #a53b2a;
}
.tabs { .tabs {
border: none; border: none;
} }
...@@ -210,11 +125,3 @@ div.tabs .tabs-title { ...@@ -210,11 +125,3 @@ div.tabs .tabs-title {
margin-bottom: 0.1em; margin-bottom: 0.1em;
background-color: #3b3b3b; background-color: #3b3b3b;
} }
.bulk-upload-label {
margin-bottom: 0px;
}
.button-group .button {
/* margin-left: 0.5em; */
}
...@@ -4,14 +4,26 @@ import QueueDesktop from './QueueDesktop.vue' ...@@ -4,14 +4,26 @@ import QueueDesktop from './QueueDesktop.vue'
import RecentDesktop from './RecentDesktop.vue' import RecentDesktop from './RecentDesktop.vue'
const props = defineProps(['state']); const props = defineProps(['state']);
const emit = defineEmits(['update:searchTerm', 'search', 'append']) const emit = defineEmits(['update:searchTerm', 'search', 'append', 'skip', 'skipCurrent', 'moveUp'])
</script> </script>
<template> <template>
<div class="splitter"> <div class="splitter">
<SearchDesktop :search="state.search" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" @append="(entry) => $emit('append', entry)" /> <SearchDesktop :search="state.search" :searching="state.searching" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" @append="(entry) => $emit('append', entry)" />
<QueueDesktop :queue="state.queue" :admin="state.admin" /> <QueueDesktop
:queue="state.queue"
:admin="state.admin"
@skip="(uuid) => $emit('skip', uuid)"
@moveUp="(uuid) => $emit('moveUp', uuid)"
@skipCurrent="$emit('skipCurrent')"
/>
<RecentDesktop :recent="state.recent" :admin="state.admin" /> <RecentDesktop :recent="state.recent" :admin="state.admin" />
</div> </div>
</template> </template>
<style scoped>
.splitter {
display: flex;
height: 100%;
}
</style>
<script> <script setup>
export default { import { computed } from 'vue'
props: ['admin', 'entry', 'current'] const props = defineProps(['admin', 'entry', 'current', 'firstStartedAt', 'offset', 'currentTime'])
const emits = defineEmits(['skip', 'skipCurrent', 'moveUp'])
function skip() {
if(props.current) {
emits("skipCurrent")
} else {
emits("skip", props.entry.uuid)
}
}
const eta = computed(() =>{
let now = props.currentTime
let startTime = new Date(props.firstStartedAt * 1000)
let playBackSeconds = (now - startTime) / 1000
let etaSeconds = Math.round(props.offset - playBackSeconds)
if (isNaN(etaSeconds)) {
return "error"
} else {
return new Date(etaSeconds * 1000).toISOString().substring(11,19)
} }
})
</script> </script>
<template> <template>
...@@ -11,16 +33,41 @@ export default { ...@@ -11,16 +33,41 @@ export default {
<span class="artist">{{ entry.artist }}</span> <span class="artist">{{ entry.artist }}</span>
<span class="title">{{ entry.title }}</span><br /> <span class="title">{{ entry.title }}</span><br />
<span class="performer">{{ entry.performer }}</span> <span class="performer">{{ entry.performer }}</span>
<span v-if="!current" class="eta">{{ eta }}</span>
</div> </div>
<div v-if="admin" class="cell small-3"> <div v-if="admin" class="cell small-3">
<button class="button alert fright" v-if="!current"> <button class="button alert fright" @click="skip">
<font-awesome-icon icon="fa-solid fa-step-forward" />
</button>
<button class="button alert fright">
<font-awesome-icon icon="fa-solid fa-times" /> <font-awesome-icon icon="fa-solid fa-times" />
</button> </button>
<button
class="button alert fright"
v-if="!current"
@click="$emit('moveUp', entry.uuid)" >
<font-awesome-icon icon="fa-solid fa-arrow-up" />
</button>
</div> </div>
</div> </div>
</li> </li>
</template> </template>
<style scoped>
.current {
background-color: #008000 !important;
}
.current::before, #large-current::before{
content: "Now Playing";
text-align: center;
font-weight: bold;
}
.eta {
float: right;
}
.eta::before {
content: "in ";
}
</style>
<script setup>
const props = defineProps(['name'])
const emits = defineEmits(['update:name'])
</script>
<template>
<footer>
Name: <span
class="userName"
@keyup.enter="(evt) => evt.target.blur()"
@focusout="(evt) => $emit('update:name', evt.target.textContent)"
contenteditable
>
{{ name }}
</span>
</footer>
</template>
<style scoped>
footer {
position: fixed;
bottom: 0;
height: 50px;
line-height: 50px;
width: 100%;
padding-left: 10px;
background-color: #008000;
font-weight: bold;
color: #ffffff;
font-size: 1.5rem;
margin: auto;
}
footer > .userName {
border: none;
border-bottom: 1px dashed #00F000;
background-color: #008000;
min-width: 5em;
display: inline-block;
height: 70%;
text-align: center;
}
</style>
<script setup>
</script>
<template>
<button type="button" class="alert button">Delete</button>
</template>
<style scoped>
</style>
<script setup>
const props = defineProps(["current_name","current_entry"])
const emits = defineEmits(["update:currentName", "append", "close_name"])
</script>
<template>
<div class="reveal" id="getusername" @keyup.enter="$emit('append')" data-reveal >
<h1>Please enter your name</h1>
<label>Name
<input
type="text"
@input="(evt) => $emit('update:currentName', evt.target.value)"
placeholder="Arno Nym"
:value="current_name"
>
</label>
<div class="grid-x">
<div class="cell medium-6 small-12 btn">
<button
class="button expanded"
@click="$emit('append')"
>
Ok
</button>
</div>
<div class="cell medium-6 small-12 btn">
<button class="button expanded alert" @click="$emit('close_name')">Cancel</button>
</div>
</div>
</div>
</template>
<style scoped>
.btn {
padding: 3px;
}
</style>
...@@ -5,7 +5,7 @@ import RecentTab from './RecentTab.vue' ...@@ -5,7 +5,7 @@ import RecentTab from './RecentTab.vue'
import TabHeader from './TabHeader.vue' import TabHeader from './TabHeader.vue'
const props = defineProps(['state']); const props = defineProps(['state']);
const emit = defineEmits(['update:searchTerm', 'search', 'append' ]) const emit = defineEmits(['update:searchTerm', 'search', 'append', 'skip', 'skipCurrent', 'moveUp'])
</script> </script>
...@@ -18,8 +18,14 @@ const emit = defineEmits(['update:searchTerm', 'search', 'append' ]) ...@@ -18,8 +18,14 @@ const emit = defineEmits(['update:searchTerm', 'search', 'append' ])
<TabHeader link="#recent-list" icon="fa-history" /> <TabHeader link="#recent-list" icon="fa-history" />
</div> </div>
<div class="tabs-container" data-tabs-content="main-tab"> <div class="tabs-container" data-tabs-content="main-tab">
<SearchTab :search="state.search" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" @append="(entry) => $emit('append', entry)"/> <SearchTab :search="state.search" :searching="state.searching" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" @append="(entry) => $emit('append', entry)"/>
<QueueTab :queue="state.queue" :admin="state.admin" /> <QueueTab
:queue="state.queue"
:admin="state.admin"
@skip="(uuid) => $emit('skip', uuid)"
@moveUp="(uuid) => $emit('moveUp', uuid)"
@skipCurrent="$emit('skipCurrent')"
/>
<RecentTab :recent="state.recent" :admin="state.admin" /> <RecentTab :recent="state.recent" :admin="state.admin" />
</div> </div>
</div> </div>
...@@ -31,12 +37,7 @@ const emit = defineEmits(['update:searchTerm', 'search', 'append' ]) ...@@ -31,12 +37,7 @@ const emit = defineEmits(['update:searchTerm', 'search', 'append' ])
display: flex; display: flex;
height: 100vh; height: 100vh;
} }
.comp-column {
max-height: 100vh;
flex:1;
display: flex;
flex-direction: column;
}
.tabs-container { .tabs-container {
flex: 1; flex: 1;
position: relative; position: relative;
......
...@@ -2,11 +2,23 @@ ...@@ -2,11 +2,23 @@
import QueueInner from './QueueInner.vue' import QueueInner from './QueueInner.vue'
const props = defineProps(['queue', 'admin']); const props = defineProps(['queue', 'admin']);
const emits = defineEmits(['skip', 'skipCurrent', 'moveUp'])
</script> </script>
<template> <template>
<div class="comp-column" id="middle"> <div class="comp-column">
<div class="header">Queue</div> <div class="header">Queue</div>
<QueueInner :queue="queue" :admin="admin" /> <QueueInner
:queue="queue"
:admin="admin"
@skip="(uuid) => $emit('skip', uuid)"
@moveUp="(uuid) => $emit('moveUp', uuid)"
@skipCurrent="$emit('skipCurrent')"
/>
</div> </div>
</template> </template>
<style scoped>
.comp-column {
margin: 0.2em 0.1em 0.1em 0.2em;
}
</style>
<script setup> <script setup>
import { onMounted, reactive } from 'vue'
import Entry from './Entry.vue' import Entry from './Entry.vue'
const props = defineProps(['queue', 'admin']); const props = defineProps(['queue', 'admin']);
const emits = defineEmits(['skip', 'skipCurrent', 'moveUp'])
let currentTime = reactive({time: Date.now()})
function updateNow() {
currentTime.time = Date.now()
}
onMounted(() => {
updateNow()
setInterval(updateNow.bind(this), 1000)
})
function offset(index) {
let _offset = 0
for(let i = 0; i < index; i++) {
_offset += props.queue[i].duration
}
return _offset
}
</script> </script>
<template> <template>
<div class="vsplit"> <div class="vsplit">
<div id="queue-list-wrapper" class="results"> <div id="queue-list-wrapper" class="results">
<ul id="queue" class="vertical menu"> <ul id="queue" class="vertical menu">
<Entry v-for="(entry, index) in queue" :entry="entry" :current="index == 0" :admin="admin" /> <Entry
<li v-show="admin"> v-for="(entry, index) in queue"
<div class="row"> :entry="entry"
<div class="columns small-12"> :current="index == 0"
<a class="button" download="queue.json" rv-href="queue.data">Save</a> :admin="admin"
<label for="small-bulk-upload" class="button bulk-upload-label">Bulk Append</label> :firstStartedAt="queue[0].started_at"
<input type="file" id="small-bulk-upload" rv-on-change="queue.bulk_append" class="show-for-sr"> :currentTime="currentTime.time"
</div> :offset="offset(index)"
</div> @skip="(uuid) => $emit('skip', uuid)"
</li> @skipCurrent="$emit('skipCurrent')"
@moveUp="(uuid) => $emit('moveUp', uuid)"
/>
</ul> </ul>
</div> </div>
</div> </div>
......
...@@ -2,10 +2,17 @@ ...@@ -2,10 +2,17 @@
import QueueInner from './QueueInner.vue' import QueueInner from './QueueInner.vue'
const props = defineProps(['queue', 'admin']); const props = defineProps(['queue', 'admin']);
const emits = defineEmits(['skip', 'skipCurrent', 'moveUp'])
</script> </script>
<template> <template>
<div class="tabs-panel" id="queue-list"> <div class="tabs-panel" id="queue-list">
<QueueInner :queue="queue" :admin="admin" /> <QueueInner
:queue="queue"
:admin="admin"
@skip="(uuid) => $emit('skip', uuid)"
@moveUp="(uuid) => $emit('moveUp', uuid)"
@skipCurrent="$emit('skipCurrent')"
/>
</div> </div>
</template> </template>
...@@ -4,8 +4,13 @@ import RecentInner from './RecentInner.vue' ...@@ -4,8 +4,13 @@ import RecentInner from './RecentInner.vue'
const props = defineProps(['recent', 'admin']) const props = defineProps(['recent', 'admin'])
</script> </script>
<template> <template>
<div class="comp-column" id="right-side"> <div class="comp-column">
<div class="header">Recent</div> <div class="header">Recent</div>
<RecentInner :recent="recent" /> <RecentInner :recent="recent" />
</div> </div>
</template> </template>
<style scoped>
.comp-column {
margin: 0.2em 0.2em 0.1em 0.2em;
}
</style>
...@@ -7,8 +7,13 @@ const props = defineProps(['recent']) ...@@ -7,8 +7,13 @@ const props = defineProps(['recent'])
<div class="vsplit"> <div class="vsplit">
<div id="recent-list-wrapper" class="results"> <div id="recent-list-wrapper" class="results">
<ul id="recent" class="vertical menu"> <ul id="recent" class="vertical menu">
<Entry v-for="entry in recent" :entry="entry" /> <Entry v-for="entry in recent" :entry="entry" :firstStartedAt="0" :currentTime="0" :offset="0" />
</ul> </ul>
</div> </div>
</div> </div>
</template> </template>
<style scoped>
#recent {
flex-direction: column-reverse;
}
</style>
...@@ -11,7 +11,7 @@ const emits = defineEmits(['append']) ...@@ -11,7 +11,7 @@ const emits = defineEmits(['append'])
<span class="album">{{result.album}}</span> <span class="album">{{result.album}}</span>
</div> </div>
<div class="cell small-3"> <div class="cell small-3">
<a class="button alert fright" :href="result.id" v-if="result.source == 'youtube'"> <a class="button alert fright" target="_blank" rel="noreferrer noopener" :href="result.id" v-if="result.source == 'youtube'">
<font-awesome-icon icon="fa-brands fa-youtube" /> <font-awesome-icon icon="fa-brands fa-youtube" />
</a> </a>
<button class="button fright" @click="$emit('append')"> <button class="button fright" @click="$emit('append')">
......
...@@ -2,16 +2,22 @@ ...@@ -2,16 +2,22 @@
import SearchResults from './SearchResults.vue' import SearchResults from './SearchResults.vue'
import SearchBar from './SearchBar.vue' import SearchBar from './SearchBar.vue'
const props = defineProps(['search']); const props = defineProps(['search', 'searching']);
const emit = defineEmits(['update:searchTerm', 'search', 'append']) const emit = defineEmits(['update:searchTerm', 'search', 'append'])
</script> </script>
<template> <template>
<div class="comp-column" id="left-side"> <div class="comp-column">
<div class="header">Search</div> <div class="header">Search</div>
<div class="vsplit"> <div class="vsplit">
<SearchBar :searchTerm="search.searchTerm" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" /> <SearchBar :searchTerm="search.searchTerm" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" />
<SearchResults :searchResults="search.searchResults" @append="(entry) => $emit('append', entry)" /> <SearchResults :searchResults="search.searchResults" :searching="searching" @append="(entry) => $emit('append', entry)" />
</div> </div>
</div> </div>
</template> </template>
<style scoped>
.comp-column {
margin: 0.2em 0.1em 0.2em 0.2em;
}
</style>
<script setup> <script setup>
import Result from './Result.vue' import Result from './Result.vue'
const props = defineProps(['searchResults']); const props = defineProps(['searchResults', 'searching']);
const emits = defineEmits(['append']) const emits = defineEmits(['append'])
</script> </script>
<template> <template>
<div id="search-results" class="results"> <div id="search-results" class="results">
<ul class="vertical menu"> <ul class="vertical menu">
<Result v-for="result in searchResults" :result="result" @append="$emit('append', result)" /> <li v-if="searching">Searching...</li>
<Result v-else v-for="result in searchResults" :result="result" @append="$emit('append', result)" />
</ul> </ul>
</div> </div>
</template> </template>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import SearchBar from './SearchBar.vue' import SearchBar from './SearchBar.vue'
import SearchResults from './SearchResults.vue' import SearchResults from './SearchResults.vue'
const props = defineProps(['search']); const props = defineProps(['search', 'searching']);
const emit = defineEmits(['update:searchTerm', 'search', 'append']) const emit = defineEmits(['update:searchTerm', 'search', 'append'])
</script> </script>
...@@ -10,7 +10,7 @@ const emit = defineEmits(['update:searchTerm', 'search', 'append']) ...@@ -10,7 +10,7 @@ const emit = defineEmits(['update:searchTerm', 'search', 'append'])
<div class="tabs-panel is-active" id="simplesearch"> <div class="tabs-panel is-active" id="simplesearch">
<div class="vsplit"> <div class="vsplit">
<SearchBar :searchTerm="search.searchTerm" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" @append="(entry) => $emit('append', entry)" /> <SearchBar :searchTerm="search.searchTerm" @update:searchTerm="(val) => $emit('update:searchTerm', val)" @search="$emit('search')" @append="(entry) => $emit('append', entry)" />
<SearchResults :searchResults="search.searchResults" @append="(entry) => $emit('append', entry)" /> <SearchResults :searchResults="search.searchResults" :searching="searching" @append="(entry) => $emit('append', entry)" />
</div> </div>
</div> </div>
</template> </template>
...@@ -3,7 +3,7 @@ import { onMounted, onBeforeUnmount } from 'vue' ...@@ -3,7 +3,7 @@ import { onMounted, onBeforeUnmount } from 'vue'
import $ from 'jquery' import $ from 'jquery'
const emits = defineEmits(['connect', 'update:room', 'update:name', 'update:server', 'update:secret']) const emits = defineEmits(['connect', 'update:room', 'update:name', 'update:server', 'update:secret'])
const props = defineProps(['room', 'server']) const props = defineProps(['room', 'server', 'joinMsg'])
onMounted(() => { onMounted(() => {
$(document).foundation(); $(document).foundation();
...@@ -15,7 +15,7 @@ onBeforeUnmount(() => { ...@@ -15,7 +15,7 @@ onBeforeUnmount(() => {
}) })
</script> </script>
<template> <template>
<div class="reveal" id="welcome" data-reveal data-close-on-esc="false" data-close-on-click="false"> <div class="reveal" id="welcome" @keyup.enter="$emit('connect')" data-reveal data-close-on-esc="false" data-close-on-click="false">
<h1>Welcome to Syng</h1> <h1>Welcome to Syng</h1>
<p> <p>
Please enter the room code and your name Please enter the room code and your name
...@@ -45,6 +45,8 @@ onBeforeUnmount(() => { ...@@ -45,6 +45,8 @@ onBeforeUnmount(() => {
</div> </div>
</div> </div>
</div> </div>
<p v-html="joinMsg">
</p>
<button class="button expanded" @click="$emit('connect')">Connect</button> <button class="button expanded" @click="$emit('connect')">Connect</button>
</div> </div>
</template> </template>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment