summaryrefslogtreecommitdiff
path: root/pse-dashboard/src/views/SubscriptionsView.vue
diff options
context:
space:
mode:
Diffstat (limited to 'pse-dashboard/src/views/SubscriptionsView.vue')
-rw-r--r--pse-dashboard/src/views/SubscriptionsView.vue270
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>
+