diff options
-rw-r--r-- | .eslintrc.js | 15 | ||||
-rw-r--r-- | package-lock.json | 47 | ||||
-rw-r--r-- | package.json | 5 | ||||
-rw-r--r-- | src/components/AddFeed.vue | 6 | ||||
-rw-r--r-- | src/components/Explore.vue | 5 | ||||
-rw-r--r-- | src/components/Sidebar.vue | 251 | ||||
-rw-r--r-- | src/store/feed.ts | 74 | ||||
-rw-r--r-- | src/store/folder.ts | 70 | ||||
-rw-r--r-- | src/store/index.ts | 148 | ||||
-rw-r--r-- | src/types/Feed.ts | 9 | ||||
-rw-r--r-- | src/types/Feed.vue | 6 | ||||
-rw-r--r-- | src/types/Folder.ts (renamed from src/types/Folder.vue) | 4 | ||||
-rw-r--r-- | tsconfig.json | 2 | ||||
-rw-r--r-- | webpack.js | 9 |
14 files changed, 354 insertions, 297 deletions
diff --git a/.eslintrc.js b/.eslintrc.js index 53f17a942..53abb5d1f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,6 +17,21 @@ module.exports = { '@vue/standard', '@vue/typescript/recommended', '@nextcloud', + 'plugin:@typescript-eslint/recommended', ], ignorePatterns: ['*.d.ts'], + rules: { + 'no-console': ['warn'], + '@typescript-eslint/no-var-requires': 'off', + // TODO: Trouble importing .ts files into .vue files for some reason? + 'import/extensions': 'off', + 'n/no-missing-import': 'off', + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.ts'], + }, + }, + }, } diff --git a/package-lock.json b/package-lock.json index 48ae5985e..44f4c681c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,7 @@ "eslint": "^8.6.0", "eslint-config-standard": "^17.0.0", "eslint-import-resolver-webpack": "^0.12.2", - "eslint-plugin-import": "^2.22.0", + "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsdoc": "^39.2.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.0.0", @@ -88,7 +88,8 @@ "vue-template-compiler": "^2.6.14", "vue2-datepicker": "^3.11.0", "webpack": "^5.72.1", - "webpack-cli": "^4.9.2" + "webpack-cli": "^4.9.2", + "webpack-merge": "^5.8.0" }, "engines": { "node": "^16.0.0", @@ -14885,6 +14886,15 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/terser": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", @@ -15161,14 +15171,6 @@ "node": ">=10.13.0" } }, - "node_modules/ts-loader/node_modules/tapable": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/tsconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", @@ -16240,15 +16242,6 @@ "node": ">=6.11.5" } }, - "node_modules/webpack/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/webpack/node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -27425,6 +27418,12 @@ } } }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, "terser": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", @@ -27607,10 +27606,6 @@ "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } - }, - "tapable": { - "version": "2.2.1", - "dev": true } } }, @@ -28232,12 +28227,6 @@ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index 079dead08..282494d84 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "eslint": "^8.6.0", "eslint-config-standard": "^17.0.0", "eslint-import-resolver-webpack": "^0.12.2", - "eslint-plugin-import": "^2.22.0", + "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsdoc": "^39.2.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.0.0", @@ -124,7 +124,8 @@ "vue-template-compiler": "^2.6.14", "vue2-datepicker": "^3.11.0", "webpack": "^5.72.1", - "webpack-cli": "^4.9.2" + "webpack-cli": "^4.9.2", + "webpack-merge": "^5.8.0" }, "jest": { "preset": "ts-jest", diff --git a/src/components/AddFeed.vue b/src/components/AddFeed.vue index cd5e60fe2..2284f7d07 100644 --- a/src/components/AddFeed.vue +++ b/src/components/AddFeed.vue @@ -111,8 +111,10 @@ import NcModal from '@nextcloud/vue/dist/Components/NcModal.js' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect.js' -import { Folder } from '../types/Folder.vue' -import { Feed } from '../types/Feed.vue' +// eslint-disable-next-line +import { Folder } from '../types/Folder' +// eslint-disable-next-line +import { Feed } from '../types/Feed' type AddFeedState = { folder: Folder; diff --git a/src/components/Explore.vue b/src/components/Explore.vue index 20b9106ff..28adf38ca 100644 --- a/src/components/Explore.vue +++ b/src/components/Explore.vue @@ -38,7 +38,8 @@ import axios from '@nextcloud/axios' import AddFeed from './AddFeed.vue' import * as router from '@nextcloud/router' import { ExploreSite } from '../types/ExploreSite.vue' -import { Feed } from '../types/Feed.vue' +// eslint-disable-next-line +import { Feed } from '../types/Feed' const ExploreComponent = Vue.extend({ components: { @@ -47,7 +48,7 @@ const ExploreComponent = Vue.extend({ }, data: () => { const exploreSites: ExploreSite[] = [] - const feed: Feed = {} + const feed: Feed = {} as any const showAddFeed = false return { diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 95ace9064..2e91c115d 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -6,125 +6,123 @@ button-class="icon-add" @click="showShowAddFeed()" /> - <ul id="locations" class="with-icon"> - <NcAppNavigationNewItem :title="t('news', 'New folder')" - icon="icon-add-folder" - @new-item="newFolder" /> + <NcAppNavigationNewItem :title="t('news', 'New folder')" + icon="icon-add-folder" + @new-item="newFolder" /> - <NcAppNavigationItem :title="t('news', 'Unread articles')" icon="icon-rss"> - <template #actions> - <NcActionButton icon="icon-checkmark" @click="alert('TODO: Mark Read')"> - t('news','Mark read') - </NcActionButton> - </template> - <template #counter> - <CounterBubble>5</CounterBubble> - </template> - </NcAppNavigationItem> - <NcAppNavigationItem :title="t('news', 'All articles')" icon="icon-rss"> - <template #actions> - <ActionButton icon="icon-checkmark" @click="alert('TODO: Edit')"> - t('news','Mark read') - </ActionButton> - </template> - </NcAppNavigationItem> - <NcAppNavigationItem :title="t('news', 'Starred')" icon="icon-starred"> - <template #counter> - <NcCounterBubble>35</NcCounterBubble> - </template> - </NcAppNavigationItem> + <NcAppNavigationItem :title="t('news', 'Unread articles')" icon="icon-rss"> + <template #actions> + <NcActionButton icon="icon-checkmark" @click="alert('TODO: Mark Read')"> + t('news','Mark read') + </NcActionButton> + </template> + <template #counter> + <CounterBubble>5</CounterBubble> + </template> + </NcAppNavigationItem> + <NcAppNavigationItem :title="t('news', 'All articles')" icon="icon-rss"> + <template #actions> + <ActionButton icon="icon-checkmark" @click="alert('TODO: Edit')"> + t('news','Mark read') + </ActionButton> + </template> + </NcAppNavigationItem> + <NcAppNavigationItem :title="t('news', 'Starred')" icon="icon-starred"> + <template #counter> + <NcCounterBubble>35</NcCounterBubble> + </template> + </NcAppNavigationItem> - <NcAppNavigationItem v-for="topLevelItem in topLevelNav" - :key="topLevelItem.name" - :title="topLevelItem.name" - icon="icon-folder" - :allow-collapse="true"> - <template #default> - <NcAppNavigationItem v-for="feed in topLevelItem.feeds" - :key="feed.name" - :title="feed.title"> - <template #icon> - <img v-if="feed.faviconLink" - :src="feed.faviconLink" - alt="feedIcon"> - <div v-if="!feed.faviconLink" class="icon-rss" /> - </template> - <template #actions> - <NcActionButton icon="icon-checkmark" - @click="alert('TODO: Mark read')"> - {{ t("news", "Mark read") }} - </NcActionButton> - <NcActionButton icon="icon-pinned" - @click="alert('TODO: Unpin from top')"> - {{ t("news", "Unpin from top") }} - </NcActionButton> - <NcActionButton icon="icon-caret-dark" - @click="alert('TODO: Newest First')"> - {{ t("news", "Newest first") }} - </NcActionButton> - <NcActionButton icon="icon-caret-dark" - @click="alert('TODO: Oldest first')"> - {{ t("news", "Oldest first") }} - </NcActionButton> - <NcActionButton icon="icon-caret-dark" - @click="alert('TODO: Default Order')"> - {{ t("news", "Default order") }} - </NcActionButton> - <NcActionButton icon="icon-full-text-disabled" - @click="alert('TODO: Enable Full Text')"> - {{ t("news", "Enable full text") }} - </NcActionButton> - <NcActionButton icon="icon-full-text-enabled" - @click="alert('TODO: DIsable Full Text')"> - {{ t("news", "Disable full text") }} - </NcActionButton> - <NcActionButton icon="icon-updatemode-default" - @click="alert('TODO: Unread Updated')"> - {{ t("news", "Unread updated") }} - </NcActionButton> - <NcActionButton icon="icon-updatemode-unread" - @click="alert('TOODO: Ignore UPdated')"> - {{ t("news", "Ignore updated") }} - </NcActionButton> - <NcActionButton icon="icon-icon-rss" - @click="alert('TODO: Open Feed URL')"> - {{ t("news", "Open feed URL") }} - </NcActionButton> - <NcActionButton icon="icon-icon-rename" - @click="alert('TODO: Rename')"> - {{ t("news", "Rename") }} - </NcActionButton> - <NcActionButton icon="icon-delete" - @click="alert('TODO: Delete Feed')"> - {{ t("news", "Delete") }} - </NcActionButton> - </template> - </NcAppNavigationItem> - </template> - <template v-if="topLevelItem.feedCount > 0" #counter> - <CounterBubble>{{ topLevelItem.feedCount }}</CounterBubble> - </template> - <template #actions> - <NcActionButton icon="icon-checkmark" @click="alert('TODO: Mark read')"> - {{ t("news", "Mark read") }} - </NcActionButton> - <NcActionButton icon="icon-rename" @click="alert('TODO: Rename')"> - {{ t("news", "Rename") }} - </NcActionButton> - <NcActionButton icon="icon-delete" @click="deleteFolder(topLevelItem)"> - {{ t("news", "Delete") }} - </NcActionButton> - </template> - </NcAppNavigationItem> + <NcAppNavigationItem v-for="topLevelItem in topLevelNav" + :key="topLevelItem.name" + :title="topLevelItem.name" + icon="icon-folder" + :allow-collapse="true"> + <template #default> + <NcAppNavigationItem v-for="feed in topLevelItem.feeds" + :key="feed.name" + :title="feed.title"> + <template #icon> + <img v-if="feed.faviconLink" + :src="feed.faviconLink" + alt="feedIcon"> + <div v-if="!feed.faviconLink" class="icon-rss" /> + </template> + <template #actions> + <NcActionButton icon="icon-checkmark" + @click="alert('TODO: Mark read')"> + {{ t("news", "Mark read") }} + </NcActionButton> + <NcActionButton icon="icon-pinned" + @click="alert('TODO: Unpin from top')"> + {{ t("news", "Unpin from top") }} + </NcActionButton> + <NcActionButton icon="icon-caret-dark" + @click="alert('TODO: Newest First')"> + {{ t("news", "Newest first") }} + </NcActionButton> + <NcActionButton icon="icon-caret-dark" + @click="alert('TODO: Oldest first')"> + {{ t("news", "Oldest first") }} + </NcActionButton> + <NcActionButton icon="icon-caret-dark" + @click="alert('TODO: Default Order')"> + {{ t("news", "Default order") }} + </NcActionButton> + <NcActionButton icon="icon-full-text-disabled" + @click="alert('TODO: Enable Full Text')"> + {{ t("news", "Enable full text") }} + </NcActionButton> + <NcActionButton icon="icon-full-text-enabled" + @click="alert('TODO: DIsable Full Text')"> + {{ t("news", "Disable full text") }} + </NcActionButton> + <NcActionButton icon="icon-updatemode-default" + @click="alert('TODO: Unread Updated')"> + {{ t("news", "Unread updated") }} + </NcActionButton> + <NcActionButton icon="icon-updatemode-unread" + @click="alert('TOODO: Ignore UPdated')"> + {{ t("news", "Ignore updated") }} + </NcActionButton> + <NcActionButton icon="icon-icon-rss" + @click="alert('TODO: Open Feed URL')"> + {{ t("news", "Open feed URL") }} + </NcActionButton> + <NcActionButton icon="icon-icon-rename" + @click="alert('TODO: Rename')"> + {{ t("news", "Rename") }} + </NcActionButton> + <NcActionButton icon="icon-delete" + @click="alert('TODO: Delete Feed')"> + {{ t("news", "Delete") }} + </NcActionButton> + </template> + </NcAppNavigationItem> + </template> + <template v-if="topLevelItem.feedCount > 0" #counter> + <CounterBubble>{{ topLevelItem.feedCount }}</CounterBubble> + </template> + <template #actions> + <NcActionButton icon="icon-checkmark" @click="alert('TODO: Mark read')"> + {{ t("news", "Mark read") }} + </NcActionButton> + <NcActionButton icon="icon-rename" @click="alert('TODO: Rename')"> + {{ t("news", "Rename") }} + </NcActionButton> + <NcActionButton icon="icon-delete" @click="deleteFolder(topLevelItem)"> + {{ t("news", "Delete") }} + </NcActionButton> + </template> + </NcAppNavigationItem> - <NcAppNavigationItem :title="t('news', 'Explore')" - icon="icon-link" - :to="{ name: 'explore' }"> - <template #counter> - <NcCounterBubble>35</NcCounterBubble> - </template> - </NcAppNavigationItem> - </ul> + <NcAppNavigationItem :title="t('news', 'Explore')" + icon="icon-link" + :to="{ name: 'explore' }"> + <template #counter> + <NcCounterBubble>35</NcCounterBubble> + </template> + </NcAppNavigationItem> </NcAppNavigation> </template> @@ -132,6 +130,7 @@ import Vuex from 'vuex' import Vue from 'vue' + import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js' import NcAppNavigationNew from '@nextcloud/vue/dist/Components/NcAppNavigationNew.js' import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js' @@ -139,21 +138,23 @@ import NcAppNavigationNewItem from '@nextcloud/vue/dist/Components/NcAppNavigati // import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter' import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' -import AddFeed from './AddFeed.vue' -import { Folder } from '../types/Folder.vue' -import { Feed } from '../types/Feed.vue' // import { ROUTES } from '../routes.js' -import { ACTIONS, AppState } from '../store/index.ts' + +import AddFeed from './AddFeed.vue' + +import { ACTIONS, AppState } from '../store/index' +import { Folder } from '../types/Folder' +import { Feed } from '../types/Feed' const SideBarState: any = { - topLevelNav(state: AppState) { - const navItems = state.feeds.filter((feed: Feed) => { + topLevelNav(state: AppState): any[] { + const navItems: any[] = state.feeds.filter((feed: Feed) => { return feed.folderId === undefined || feed.folderId === null - }).concat(state.folders) + }) + navItems.concat(state.folders) - console.log(navItems); - return navItems; + return navItems }, } diff --git a/src/store/feed.ts b/src/store/feed.ts new file mode 100644 index 000000000..aaf9a96f0 --- /dev/null +++ b/src/store/feed.ts @@ -0,0 +1,74 @@ +import axios from "@nextcloud/axios"; +import { generateUrl } from "@nextcloud/router"; + +import { ActionParams, AppState } from 'src/store' +import { Feed } from '../types/Feed' + +export const FEED_MUTATION_TYPES = { + SET_FEEDS: 'SET_FEEDS', +} + +export const FEED_ACTION_TYPES = { + ADD_FEED: 'ADD_FEED', + FETCH_FEEDS: 'FETCH_FEEDS', +} + +const feedUrl = generateUrl("/apps/news/feeds") + +export const FEED_ACTIONS = { + async [FEED_ACTION_TYPES.FETCH_FEEDS] ({ commit }: ActionParams) { + const feeds = await axios.get( + generateUrl("/apps/news/feeds") + ); + + commit(FEED_MUTATION_TYPES.SET_FEEDS, feeds.data.feeds); + }, + [FEED_ACTION_TYPES.ADD_FEED] ({ commit }: ActionParams, { feedReq }: { feedReq: { url: string; folder?: { id: number } } }) { + console.log(feedReq) + let url = feedReq.url.trim(); + if (!url.startsWith('http')) { + url = 'https://' + url; + } + + /** + if (title !== undefined) { + title = title.trim(); + } + */ + + let feed: Feed = { + url: url, + folderId: feedReq.folder?.id || 0, + title: undefined, + unreadCount: 0, + autoDiscover: undefined // TODO + }; + + // this.add(feed); + // this.updateFolderCache(); + + axios.post(feedUrl, { + url: feed.url, + parentFolderId: feed.folderId, + title: null, + user: null, + password: null, + fullDiscover: feed.autoDiscover + }).then(() => { + commit('addFeed', feed) + }); + } +} + +export const FEED_MUTATIONS = { + [FEED_MUTATION_TYPES.SET_FEEDS] (state: AppState, feeds: Feed[]) { + feeds.forEach(it => { + state.feeds.push(it) + const folder = state.folders.find(folder => folder.id === it.folderId) + if (folder) { + folder.feeds.push(it) + folder.feedCount += it.unreadCount + } + }) + }, +}
\ No newline at end of file diff --git a/src/store/folder.ts b/src/store/folder.ts new file mode 100644 index 000000000..735676ea0 --- /dev/null +++ b/src/store/folder.ts @@ -0,0 +1,70 @@ +import axios from "@nextcloud/axios"; +import { generateUrl } from "@nextcloud/router"; + +import { AppState, ActionParams } from 'src/store' +import { Folder } from '../types/Folder' + +export const FOLDER_MUTATION_TYPES = { + SET_FOLDERS: 'SET_FOLDERS', + DELETE_FOLDER: 'DELETE_FOLDER' +} + +export const FOLDER_ACTION_TYPES = { + FETCH_FOLDERS: 'FETCH_FOLDERS', + ADD_FOLDERS: 'ADD_FOLDER', + DELETE_FOLDER: 'DELETE_FOLDER' +} + +const folderUrl = generateUrl("/apps/news/folders") + +export const FOLDER_ACTIONS = { + + async [FOLDER_ACTION_TYPES.FETCH_FOLDERS] ({ commit }: ActionParams) { + const folders = await axios.get( + generateUrl("/apps/news/folders") + ); + + commit(FOLDER_MUTATION_TYPES.SET_FOLDERS, folders.data.folders); + }, + [FOLDER_ACTION_TYPES.ADD_FOLDERS] ({ commit }: ActionParams, { folder }: { folder: Folder}) { + console.log(folder) + axios.post(folderUrl, {folderName: folder.name}).then( + response => commit(FOLDER_MUTATION_TYPES.SET_FOLDERS, response.data.folders) + ); + }, + [FOLDER_ACTION_TYPES.DELETE_FOLDER] ({ commit }: ActionParams, { folder }: { folder: Folder}) { + /** + this.getByFolderId(folderId).forEach(function (feed) { + promises.push(self.reversiblyDelete(feed.id, false, true)); + }); + this.updateUnreadCache(); + */ + axios.delete(folderUrl + '/' + folder.id).then(() => commit(FOLDER_MUTATION_TYPES.DELETE_FOLDER, folder)) + }, + // loadFolder({commit}) { + // console.log('loading folders') + // axios.get(folderUrl).then( + // response => { + // commit('addFolders', response.data.folders); + // axios.get(feedUrl).then( + // response => commit('addFeeds', response.data.feeds) + // ) + // } + // ) + // }, +} + + +export const FOLDER_MUTATIONS = { + [FOLDER_MUTATION_TYPES.SET_FOLDERS] (state: AppState, folders: Folder[]) { + folders.forEach(it => { + it.feedCount = 0 + it.feeds = [] + state.folders.push(it) + }) + }, + [FOLDER_MUTATION_TYPES.DELETE_FOLDER] (state: AppState, folder: Folder) { + const index = state.folders.indexOf(folder); + state.folders.splice(index, 1); + } +}
\ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts index 3d1c5948c..177e23a94 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,35 +1,24 @@ -import axios from "@nextcloud/axios"; -import { generateUrl } from "@nextcloud/router"; import { Commit } from "vuex"; +import { Folder } from '../types/Folder' +import { Feed } from '../types/Feed' +import { FEED_MUTATION_TYPES, FEED_ACTION_TYPES, FEED_MUTATIONS, FEED_ACTIONS } from "./feed"; +import { FOLDER_MUTATION_TYPES, FOLDER_ACTION_TYPES, FOLDER_MUTATIONS, FOLDER_ACTIONS } from "./folder"; + export const MUTATIONS = { - SET_FEEDS: 'SET_FEEDS', - SET_FOLDERS: 'SET_FOLDERS' + ... FEED_MUTATION_TYPES, + ... FOLDER_MUTATION_TYPES } export const ACTIONS = { - FETCH_FEEDS: 'FETCH_FEEDS', - FETCH_FOLDERS: 'FETCH_FOLDERS' -} - -type Feed = { - folderId?: number; - unreadCount: number; - url: string; - title?: string; - autoDiscover?: boolean; - faviconLink?: string; + ... FEED_ACTION_TYPES, + ... FOLDER_ACTION_TYPES } -type Folder = { - feeds: any[]; - feedCount: number; - name: string; - id: number; -} +export type ActionParams = { commit: Commit }; export type AppState = { - feeds: any[]; + feeds: Feed[]; folders: Folder[]; items: any[]; } @@ -40,111 +29,6 @@ const state: AppState = { items: [] } as AppState -const mutations = { - [MUTATIONS.SET_FEEDS] (state: AppState, feeds: Feed[]) { - feeds.forEach(it => { - state.feeds.push(it) - const folder = state.folders.find(folder => folder.id === it.folderId) - if (folder) { - folder.feeds.push(it) - folder.feedCount += it.unreadCount - } - }) - }, - [MUTATIONS.SET_FOLDERS] (state: AppState, folders: Folder[]) { - folders.forEach(it => { - it.feedCount = 0 - it.feeds = [] - state.folders.push(it) - }) - }, -} - - -const feedUrl = generateUrl("/apps/news/feeds") -const folderUrl = generateUrl("/apps/news/folders") - - -type ActionParams = { commit: Commit }; - -const actions = { - async [ACTIONS.FETCH_FEEDS] ({ commit }: ActionParams) { - const feeds = await axios.get( - generateUrl("/apps/news/feeds") - ); - - commit(MUTATIONS.SET_FEEDS, feeds.data.feeds); - }, - async [ACTIONS.FETCH_FOLDERS] ({ commit }: ActionParams) { - const folders = await axios.get( - generateUrl("/apps/news/folders") - ); - - commit(MUTATIONS.SET_FOLDERS, folders.data.folders); - }, - addFolder({ commit }: ActionParams, { folder }: { folder: Folder}) { - console.log(folder) - axios.post(folderUrl, {folderName: folder.name}).then( - response => commit(MUTATIONS.SET_FOLDERS, response.data.folders) - ); - }, - deleteFolder({ commit }: ActionParams, { folder }: { folder: Folder}) { - /** - this.getByFolderId(folderId).forEach(function (feed) { - promises.push(self.reversiblyDelete(feed.id, false, true)); - }); - this.updateUnreadCache(); - */ - axios.delete(folderUrl + '/' + folder.id).then() - }, - // loadFolder({commit}) { - // console.log('loading folders') - // axios.get(folderUrl).then( - // response => { - // commit('addFolders', response.data.folders); - // axios.get(feedUrl).then( - // response => commit('addFeeds', response.data.feeds) - // ) - // } - // ) - // }, - addFeed({ commit }: ActionParams, { feedReq }: { feedReq: { url: string; folder?: { id: number } } }) { - console.log(feedReq) - let url = feedReq.url.trim(); - if (!url.startsWith('http')) { - url = 'https://' + url; - } - - /** - if (title !== undefined) { - title = title.trim(); - } - */ - - let feed: Feed = { - url: url, - folderId: feedReq.folder?.id || 0, - title: undefined, - unreadCount: 0, - autoDiscover: undefined // TODO - }; - - // this.add(feed); - // this.updateFolderCache(); - - axios.post(feedUrl, { - url: feed.url, - parentFolderId: feed.folderId, - title: null, - user: null, - password: null, - fullDiscover: feed.autoDiscover - }).then(() => { - commit('addFeed', feed) - }); - } -} - const getters = { feeds (state: AppState) { return state.feeds; @@ -154,6 +38,16 @@ const getters = { }, } +const mutations = { + ... FEED_MUTATIONS, + ... FOLDER_MUTATIONS +} + +const actions = { + ... FEED_ACTIONS, + ... FOLDER_ACTIONS +} + export default { state, mutations, diff --git a/src/types/Feed.ts b/src/types/Feed.ts new file mode 100644 index 000000000..d03ce5e0b --- /dev/null +++ b/src/types/Feed.ts @@ -0,0 +1,9 @@ +export type Feed = { + folderId?: number; + unreadCount: number; + url: string; + title?: string; + autoDiscover?: boolean; + faviconLink?: string; +} + diff --git a/src/types/Feed.vue b/src/types/Feed.vue deleted file mode 100644 index ece4a569e..000000000 --- a/src/types/Feed.vue +++ /dev/null @@ -1,6 +0,0 @@ -<script lang="ts"> -export type Feed = { - url?: string; - folderId?: number; -} -</script> diff --git a/src/types/Folder.vue b/src/types/Folder.ts index 254b4a20f..02b25cb8d 100644 --- a/src/types/Folder.vu |