diff options
author | Orangerot <purple@orangerot.dev> | 2024-06-19 00:14:49 +0200 |
---|---|---|
committer | Orangerot <purple@orangerot.dev> | 2024-06-27 12:11:14 +0200 |
commit | 5b8851b6c268d0e93c158908fbfae9f8473db5ff (patch) | |
tree | 7010eb85d86fa2da06ea4ffbcdb01a685d502ae8 /pse-dashboard/src/views/SubscriptionsView.vue |
Diffstat (limited to 'pse-dashboard/src/views/SubscriptionsView.vue')
-rw-r--r-- | pse-dashboard/src/views/SubscriptionsView.vue | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/pse-dashboard/src/views/SubscriptionsView.vue b/pse-dashboard/src/views/SubscriptionsView.vue new file mode 100644 index 0000000..045b5f1 --- /dev/null +++ b/pse-dashboard/src/views/SubscriptionsView.vue @@ -0,0 +1,270 @@ +<script setup> +import { DashboardLayout, FloatingLabelInput, LoadingConditional, SubscriptionEntry } from '@/components'; +import { useLogger } from '@/logger.js' +import { ref, onMounted } from 'vue'; +import { getTitles, putSubscriptions, postSubscriptions } from '@/api/pse-squared.js' +import { Modal } from 'bootstrap'; + +const titles = ref(null); +const received = ref(false); + +const newSubscription = ref(); +const deletedSubscriptions = ref([]); + +const { subscriptionAdded } = useLogger(); + +// if called from pseudo-protocol: show dialog to add subscription up front +onMounted(() => { + loadData(); + + const urlParams = new URLSearchParams(window.location.search); + + const addSubModal = new Modal("#add-sub"); + if (urlParams.has('add')) { + newSubscription.value = decodeURIComponent(urlParams.get('add')) + .replace("web+pod://", ""); + addSubModal.show(); + } +}); + +// fetches all titles of the subscribed podcasts and sets visibility +async function loadData() { + try { + const response = await getTitles(); + + received.value = true; + titles.value = response.data; + } catch(err) { } +} + +// makes a addition request based in the url in the input field/pseudo protocoll +async function addSubscription() { + received.value = false; + await putSubscriptions([newSubscription.value]); + + // log.append({type: "info", message: "Subscription got added to your list!"}); + subscriptionAdded(); + newSubscription.value = ""; + + await loadData(); +} + +// toggles the selection of all subscriptions +function selectAllSubscriptions() { + if ( deletedSubscriptions.value.length > 0 ) { + deletedSubscriptions.value = []; + } else { + deletedSubscriptions.value = titles.value; + } +} + +// makes a deletion request from all selected podcasts +async function unsubscribeFromSelected() { + received.value = false; + + await postSubscriptions({ + add: [], + remove: deletedSubscriptions.value.map(e => e.url) + }); + deletedSubscriptions.value = []; + + await loadData(); +} + +// the modal gets open by the id from the html attributes defined in the Subscription +// component. +function unsubscribeSingle(sub) { + deletedSubscriptions.value = [sub]; +} + +</script> +<template> + <DashboardLayout> + <h1 class="h1 mb-4"> + {{ $t("message.yourSubscriptions") }} + </h1> + + <!-- add a new subscription by url --> + <form + class="input-group mb-3" + @submit.prevent="addSubscription" + > + <FloatingLabelInput + v-model="newSubscription" + :label="$t('message.newSubscription')" + /> + <button + class="btn btn-success" + type="submit" + > + {{ $t("message.addSubscription") }} + </button> + </form> + + <LoadingConditional :waiting-for="received"> + <!-- user does not have subscriptions yet --> + <p v-if="titles.length == 0"> + {{ $t("message.noSubscriptions") }} + </p> + + <!-- display subscriptions --> + <div v-else> + <button + class="btn m-2 btn-success" + @click="selectAllSubscriptions" + > + {{ $t('message.selectAll') }} + </button> + <button + class="btn m-2 btn-primary" + :class="{disabled: deletedSubscriptions.length == 0}" + data-bs-toggle="modal" + data-bs-target="#delete-subs" + > + {{ $t('message.unsubscribeSelected') }} + </button> + + <div id="episodes-accordion"> + <div + v-for="sub in titles" + :key="sub.url" + class="form-check" + > + <input + v-model="deletedSubscriptions" + class="form-check-input mt-4" + type="checkbox" + :value="sub" + > + <SubscriptionEntry + :sub="sub" + @unsubscribe="unsubscribeSingle" + /> + </div> + </div> + </div> + </LoadingConditional> + </DashboardLayout> + + <!-- Modal for adding subscription with pseudo-protocol --> + <div + id="add-sub" + class="modal" + tabindex="-1" + > + <div class="modal-dialog modal-dialog-centered"> + <div class="modal-content"> + <!-- Title of Modal --> + <div class="modal-header"> + <h5 class="modal-title"> + {{ $t('message.newSubscription') }} + </h5> + <button + type="button" + class="btn-close" + data-bs-dismiss="modal" + aria-label="Close" + /> + </div> + + <!-- display URL of Podcast to subcribe to --> + <div class="modal-body"> + <FloatingLabelInput + v-model="newSubscription" + :label="$t('message.newSubscription')" + /> + </div> + + <!-- buttons to dismiss or accept the new subscription --> + <div class="modal-footer"> + <button + type="button" + class="btn btn-secondary" + data-bs-dismiss="modal" + > + {{ $t('message.close') }} + </button> + <button + type="button" + data-bs-dismiss="modal" + class="btn btn-primary" + @click="addSubscription" + > + {{ $t('message.addSubscription') }} + </button> + </div> + </div> + </div> + </div> + + <!-- Modal for confirming deletion of subscriptions --> + <div + id="delete-subs" + class="modal" + tabindex="-1" + > + <div class="modal-dialog modal-dialog-centered"> + <div class="modal-content"> + <!-- Title of Modal --> + <div class="modal-header"> + <h5 class="modal-title"> + {{ $t('message.unsubscribePodcasts') }} + </h5> + <button + type="button" + class="btn-close" + data-bs-dismiss="modal" + aria-label="Close" + /> + </div> + + <!-- list podcasts to unsubscribe from --> + <div class="modal-body"> + <div + class="alert alert-warning d-flex align-items-center" + role="alert" + > + <i class="fs-2 me-3 fa fa-warning" /> + <div> + {{ $t('message.unsubscribePodcastsWarning') }} + </div> + </div> + + <ul> + <li + v-for="sub in deletedSubscriptions" + :key="sub.url" + > + {{ sub.title || sub.url }} + <span class="opacity-50"> + ({{ $t('message.episode', sub.episodes.length) }}) + </span> + </li> + </ul> + </div> + + <!-- buttons to dismiss or finaly unsubscribe --> + <div class="modal-footer"> + <button + type="button" + class="btn btn-secondary" + data-bs-dismiss="modal" + > + {{ $t('message.close') }} + </button> + <button + type="button" + data-bs-dismiss="modal" + class="btn btn-primary" + @click="unsubscribeFromSelected" + > + {{ $t('message.unsubscribePodcasts') }} + </button> + </div> + </div> + </div> + </div> +</template> +<style scoped> +</style> + |