summaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/AddFeed.vue148
-rw-r--r--src/components/Explore.vue78
-rw-r--r--src/components/Sidebar.vue164
3 files changed, 390 insertions, 0 deletions
diff --git a/src/components/AddFeed.vue b/src/components/AddFeed.vue
new file mode 100644
index 000000000..2adacd8ad
--- /dev/null
+++ b/src/components/AddFeed.vue
@@ -0,0 +1,148 @@
+<template>
+ <Modal @close="$emit('close')">
+ <div id="new-feed" news-add-feed="Navigation.feed">
+
+ <form ng-submit="Navigation.createFeed(Navigation.feed)"
+ ng-init="Navigation.feed.autoDiscover=true"
+ name="feedform">
+ <fieldset ng-disabled="Navigation.addingFeed" style="padding: 16px">
+ <input type="text"
+ :value="feed"
+ ng-model="Navigation.feed.url"
+ ng-class="{'ng-invalid':
+ !Navigation.addingFeed &&
+ Navigation.feedUrlExists(Navigation.feed.url)
+ }"
+ :placeholder="t('news','Web address')"
+ name="address"
+ pattern="[^\s]+"
+ required
+ autofocus>
+
+ <p class="error"
+ ng-show="!Navigation.addingFeed &&
+ Navigation.feedUrlExists(Navigation.feed.url)">
+ {{ t('news', 'Feed exists already!') }}
+ </p>
+
+ <!-- select a folder -->
+ <CheckboxRadioSwitch :checked.sync="createNewFolder" type="switch">
+ {{ t('news', 'New folder') }}?
+ </CheckboxRadioSwitch>
+
+ <Multiselect v-if="!createNewFolder" v-model="folder" :options="folders" track-by="id" label="name"/>
+
+ <!-- add a folder -->
+ <input type="text"
+ ng-model="Navigation.feed.newFolder"
+ ng-class="{'ng-invalid':
+ !Navigation.addingFeed &&
+ !Navigation.addingFeed &&
+ Navigation.showNewFolder &&
+ Navigation.folderNameExists(
+ Navigation.feed.newFolder
+ )
+ }"
+ :placeholder="t('news','Folder name')"
+ name="folderName"
+ v-if="createNewFolder"
+ style="width: 90%"
+ required>
+
+
+ <p class="error" ng-show="!Navigation.addingFeed &&
+ Navigation.folderNameExists(Navigation.feed.newFolder)">
+ {{ t('news', 'Folder exists already!') }}
+ </p>
+
+ <!-- basic auth -->
+
+ <CheckboxRadioSwitch :checked.sync="withBasicAuth" type="switch">
+ {{ t('news', 'Credentials') }}?
+ </CheckboxRadioSwitch>
+
+ <div v-if="withBasicAuth" class="add-feed-basicauth">
+ <p class="warning">{{
+ t('news',
+ 'HTTP Basic Auth credentials must be stored unencrypted! Everyone with access to the server or database will be able to access them!')
+ }}></p>
+ <input type="text"
+ ng-model="Navigation.feed.user"
+ :placeholder="t('news','Username')"
+ name="user"
+ autofocus>
+
+ <input type="password"
+ ng-model="Navigation.feed.password"
+ :placeholder="t('news','Password')"
+ name="password" autocomplete="new-password">
+ </div>
+
+ <CheckboxRadioSwitch :checked.sync="autoDiscover" type="switch">
+ {{ t('news', 'Auto discover Feed') }}?
+ </CheckboxRadioSwitch>
+
+ <Button :wide="true" type="primary" @click="addFeed()" ng-disabled="
+ Navigation.feedUrlExists(Navigation.feed.url) ||
+ (
+ Navigation.showNewFolder &&
+ Navigation.folderNameExists(folder.name)
+ )">
+ {{t('news','Subscribe')}}
+ </Button>
+ </fieldset>
+ </form>
+ </div>
+ </Modal>
+</template>
+
+<script>
+import Modal from '@nextcloud/vue/dist/Components/Modal'
+import CheckboxRadioSwitch from '@nextcloud/vue/dist/Components/CheckboxRadioSwitch'
+import Button from '@nextcloud/vue/dist/Components/Button'
+import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
+
+export default {
+ components: {
+ Modal,
+ CheckboxRadioSwitch,
+ Button,
+ Multiselect
+ },
+ computed: {
+ folders() {
+ return this.$store.state.folders
+ }
+ },
+ methods: {
+ newFolder() {
+ this.createNewFolder = true;
+ },
+ abortNewFolder() {
+ this.createNewFolder = false;
+ },
+ addFeed() {
+ this.$store.dispatch('addFeed', {feedReq: { url: this.feed, folder: this.folder, autoDiscover: true}})
+ }
+ },
+ props: {
+ feed: '',
+ folder: {},
+ autoDiscover: true,
+ withBasicAuth: false,
+ createNewFolder: false
+ },
+ emits: ['close']
+}
+</script>
+
+<style scoped>
+
+ input {
+ width: 100%;
+ }
+ .multiselect {
+ width: 100%;
+ }
+
+</style>
diff --git a/src/components/Explore.vue b/src/components/Explore.vue
new file mode 100644
index 000000000..5738649cf
--- /dev/null
+++ b/src/components/Explore.vue
@@ -0,0 +1,78 @@
+<template>
+ <div id="explore">
+ <AddFeed v-if="showAddFeed" @close="closeShowAddFeed()" :feed="feed"></AddFeed>
+ <div class="grid-container">
+ <div v-for="entry in explorableSites" class="explore-feed grid-item">
+ <h2 class="explore-title" v-if="entry.favicon"
+ :style="{ backgroundImage: 'url(' + entry.favicon + ')'}">
+ <a target="_blank" rel="noreferrer" :href="entry.url">{{ entry.title }}</a>
+ </h2>
+ <h2 class="icon-rss explore-title" v-if="!entry.favicon">
+ {{ entry.title }}
+ </h2>
+ <div class="explore-content">
+ <p>{{ entry.description }}</p>
+
+ <div class="explore-logo">
+ <img :src="entry.image">
+ </div>
+ </div>
+ <Button @click="subscribe(entry.feed)">
+ {{ t('news', 'Subscribe to') }} {{ entry.title }}
+ </Button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import Modal from '@nextcloud/vue/dist/Components/Modal'
+import Button from '@nextcloud/vue/dist/Components/Button'
+import axios from "@nextcloud/axios";
+import AddFeed from "./AddFeed";
+import {generateUrl} from "@nextcloud/router";
+
+export default {
+ components: {
+ Modal,
+ Button,
+ AddFeed
+ },
+ props: {
+ explorableSites: {
+ type: Array,
+ default: () => [],
+ required: true,
+ },
+ showAddFeed: false,
+ feed: ''
+ },
+ methods: {
+ async sites() {
+ const settings = await axios.get(generateUrl("/apps/news/settings"));
+ console.log(settings.data);
+ console.log(settings.data.settings.exploreUrl);
+
+ const exploreUrl = settings.data.settings.exploreUrl + 'feeds.en.json';
+ const explore = await axios.get(exploreUrl);
+ console.log(explore.data);
+
+ Object.keys(explore.data).forEach(key =>
+ explore.data[key].forEach(value =>
+ this.explorableSites.push(value)
+ )
+ );
+ },
+ async subscribe(feed) {
+ this.feed = feed;
+ this.showAddFeed = true;
+ },
+ closeShowAddFeed() {
+ this.showAddFeed = false;
+ }
+ },
+ created() {
+ this.sites();
+ }
+}
+</script>
diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue
new file mode 100644
index 000000000..33923f89b
--- /dev/null
+++ b/src/components/Sidebar.vue
@@ -0,0 +1,164 @@
+<template>
+ <AppNavigation>
+ <AddFeed v-if="showAddFeed" @close="closeShowAddFeed()"></AddFeed>
+ <AppNavigationNew
+ :text="t('news','Subscribe')"
+ button-id="new-feed-button"
+ button-class="icon-add"
+ @click="showShowAddFeed()"/>
+
+ <ul id="locations" class="with-icon">
+
+ <AppNavigationNewItem :title="t('news','New folder')"
+ icon="icon-add-folder"
+ @new-item="newFolder">
+ </AppNavigationNewItem>
+
+ <AppNavigationItem :title="t('news','Unread articles')" icon="icon-rss">
+ <template #actions>
+ <ActionButton icon="icon-checkmark" @click="alert('Edit')">
+ t('news','Mark read')
+ </ActionButton>
+ </template>
+ <template #counter>
+ <CounterBubble>5</CounterBubble>
+ </template>
+ </AppNavigationItem>
+ <AppNavigationItem :title="t('news','All articles')" icon="icon-rss">
+ <template #actions>
+ <ActionButton icon="icon-checkmark" @click="alert('Edit')">
+ t('news','Mark read')
+ </ActionButton>
+ </template>
+ </AppNavigationItem>
+ <AppNavigationItem :title="t('news','Starred')" icon="icon-starred">
+ <template #counter>
+ <CounterBubble>35</CounterBubble>
+ </template>
+ </AppNavigationItem>
+
+ <AppNavigationItem v-for="folder in folders" :title="folder.name" icon="icon-folder"
+ :allowCollapse="true">
+ <template #default>
+ <AppNavigationItem v-for="feed in folder.feeds" :title="feed.title" >
+ <template #icon>
+ <img :src="feed.faviconLink" v-if="feed.faviconLink" alt="feedIcon">
+ <div class="icon-rss" v-if="!feed.faviconLink"></div>
+ </template>
+ <template #actions>
+ <ActionButton icon="icon-checkmark" @click="alert('Mark read')">
+ {{ t('news', 'Mark read') }}
+ </ActionButton>
+ <ActionButton icon="icon-pinned" @click="alert('Rename')">
+ {{ t('news', 'Unpin from top') }}
+ </ActionButton>
+ <ActionButton icon="icon-caret-dark" @click="deleteFolder(folder)">
+ {{ t('news', 'Newest first') }}
+ </ActionButton>
+ <ActionButton icon="icon-caret-dark" @click="deleteFolder(folder)">
+ {{ t('news', 'Oldest first') }}
+ </ActionButton>
+ <ActionButton icon="icon-caret-dark" @click="deleteFolder(folder)">
+ {{ t('news', 'Default order') }}
+ </ActionButton>
+ <ActionButton icon="icon-full-text-disabled" @click="deleteFolder(folder)">
+ {{ t('news', 'Enable full text') }}
+ </ActionButton>
+ <ActionButton icon="icon-full-text-enabled" @click="deleteFolder(folder)">
+ {{ t('news', 'Disable full text') }}
+ </ActionButton>
+ <ActionButton icon="icon-updatemode-default" @click="deleteFolder(folder)">
+ {{ t('news', 'Unread updated') }}
+ </ActionButton>
+ <ActionButton icon="icon-updatemode-unread" @click="deleteFolder(folder)">
+ {{ t('news', 'Ignore updated') }}
+ </ActionButton>
+ <ActionButton icon="icon-icon-rss" @click="deleteFolder(folder)">
+ {{ t('news', 'Open feed URL') }}
+ </ActionButton>
+ <ActionButton icon="icon-icon-rename" @click="deleteFolder(folder)">
+ {{ t('news', 'Rename') }}
+ </ActionButton>
+ <ActionButton icon="icon-delete" @click="deleteFolder(folder)">
+ {{ t('news', 'Delete') }}
+ </ActionButton>
+ </template>
+ </AppNavigationItem>
+ </template>
+ <template #counter v-if="folder.feedCount > 0">
+ <CounterBubble>{{ folder.feedCount }}</CounterBubble>
+ </template>
+ <template #actions>
+ <ActionButton icon="icon-checkmark" @click="alert('Mark read')">
+ {{ t('news', 'Mark read') }}
+ </ActionButton>
+ <ActionButton icon="icon-rename" @click="alert('Rename')">
+ {{ t('news', 'Rename') }}
+ </ActionButton>
+ <ActionButton icon="icon-delete" @click="deleteFolder(folder)">
+ {{ t('news', 'Delete') }}
+ </ActionButton>
+ </template>
+ </AppNavigationItem>
+
+ <AppNavigationItem :title="t('news','Explore')"
+ icon="icon-link"
+ :to="{ name: 'explore' }">
+ <template #counter>
+ <CounterBubble>35</CounterBubble>
+ </template>
+ </AppNavigationItem>
+ </ul>
+ </AppNavigation>
+</template>
+
+<script>
+import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation'
+import AppNavigationNew from '@nextcloud/vue/dist/Components/AppNavigationNew'
+import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
+import AppNavigationNewItem from '@nextcloud/vue/dist/Components/AppNavigationNewItem'
+import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter'
+import CounterBubble from '@nextcloud/vue/dist/Components/CounterBubble'
+import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
+import AddFeed from "./AddFeed";
+
+export default {
+ components: {
+ AppNavigation,
+ AppNavigationNew,
+ AppNavigationItem,
+ AppNavigationNewItem,
+ AppNavigationCounter,
+ CounterBubble,
+ ActionButton,
+ AddFeed
+ },
+ props: {
+ showAddFeed: false,
+ },
+ computed: {
+ folders() {
+ return this.$store.state.folders
+ },
+ },
+ methods: {
+ newFolder(value) {
+ const folderName = value.trim();
+ const folder = {name: folderName};
+ this.$store.dispatch('addFolder', {folder})
+ },
+ deleteFolder(folder) {
+ this.$store.dispatch('deleteFolder', {folder})
+ window.location.reload(true);
+ },
+ showShowAddFeed() {
+ this.showAddFeed = true;
+ },
+ closeShowAddFeed() {
+ this.showAddFeed = false;
+ }
+ },
+ created() {
+ }
+}
+</script>