1
0
mirror of https://github.com/chylex/Nextcloud-News.git synced 2025-02-22 20:46:04 +01:00

[Vue Rewrite] Enable Typescript Vue Components ()

* compiling typescript with webpack

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* working typescript component

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* clean up indentation and linting

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* remove calendar-js

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* revert indentation and remove commented out lines

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* clean up warning

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* cleanup + add comments

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* fix warnings and add more comments

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* cleanup unecessary changes to webpack and add comments

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* fix package

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* update changelog and fix comment

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* cleanup

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* remove unecessary line

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* remove vue-class-component library + others

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* clean up babel-loader

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>

* remove fork-ts-checker plugin

Signed-off-by: Devlin Junker <devlin.junker@gmail.com>
This commit is contained in:
devlinjunker 2022-07-04 01:07:48 -07:00 committed by GitHub
parent 40d9c352ab
commit f1668df03f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 7647 additions and 3874 deletions

View File

@ -1,10 +1,26 @@
module.exports = {
extends: [
'@nextcloud',
],
rules: {
'jsdoc/check-alignment': 'off',
'vue/html-indent': 'off',
'indent': ['error', 4]
},
root: true,
parser: 'vue-eslint-parser',
parserOptions: {
parser: {
ts: '@typescript-eslint/parser',
},
ecmaVersion: 2020,
},
extends: [
'eslint:recommended',
'plugin:vue/base',
'plugin:vue/essential',
'@vue/standard',
'@vue/typescript/recommended',
'@nextcloud',
],
ignorePatterns: ['*.d.ts'],
rules: {
'node/no-unpublished-import': 'off', // necessary for vue-property-decorator (not published?)
// TODO: remove these indentation rules during reformat (expects tab char \t but right now code base uses spaces)
'vue/html-indent': 'off',
indent: ['error', 4],
},
}

3
.gitignore vendored
View File

@ -47,6 +47,9 @@ RCS/*
# netbeans
nbproject
# vscode
.vscode
# phpStorm
.idea

View File

@ -6,6 +6,7 @@ The format is mostly based on [Keep a Changelog](https://keepachangelog.com/en/1
## [19.x.x]
### Changed
- Vue Rewrite
- Add Typescript
## [18.x.x]
### Changed

View File

@ -1,6 +1,6 @@
module.exports = {
plugins: [
'@babel/plugin-syntax-dynamic-import',
],
presets: ['@babel/preset-env'],
plugins: [
'@babel/plugin-syntax-dynamic-import',
],
presets: ['@babel/preset-env'],
}

11218
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,35 +38,46 @@
},
"private": true,
"homepage": "https://github.com/nextcloud/news",
"dependencies": {
"@nextcloud/axios": "^1.10.0",
"@nextcloud/dialogs": "^3.1.2",
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^5.3.1",
"vue": "^2.6.14",
"vue-router": "^3.5.3",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.11.1",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.11.0",
"@nextcloud/babel-config": "^1.0.0",
"@nextcloud/browserslist-config": "^2.2.0",
"@nextcloud/eslint-config": "^6.1.2",
"@nextcloud/eslint-config": "^8.0.0",
"@nextcloud/eslint-plugin": "^2.0.0",
"@nextcloud/stylelint-config": "^2.1.2",
"@nextcloud/webpack-vue-config": "^5.1.0",
"babel-loader": "^8.1.0",
"@types/webpack-env": "^1.17.0",
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"@vue/eslint-config-standard": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"css-loader": "^6.7.1",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint": "^8.6.0",
"eslint-config-standard": "^17.0.0",
"eslint-import-resolver-webpack": "^0.12.2",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jsdoc": "^37.9.7",
"eslint-plugin-jsdoc": "^39.2.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^7.20.0",
"eslint-plugin-vue": "^8.7.1",
"eslint-webpack-plugin": "^3.1.1",
"file-loader": "^6.0.0",
"jasmine-core": "^3.5.0",
"jquery": "^3.5.1",
"jshint": "^2.11.1",
"karma": "^5.0.9",
"karma": "^6.4.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.0.2",
"karma-firefox-launcher": "^1.3.0",
@ -84,19 +95,13 @@
"stylelint-config-recommended-scss": "^5.0.2",
"stylelint-config-recommended-vue": "^1.4.0",
"stylelint-webpack-plugin": "^2.1.0",
"ts-loader": "^9.3.0",
"typescript": "^4.7.2",
"url-loader": "^4.1.0",
"vue-loader": "^15.9.3",
"vue-template-compiler": "^2.6.11",
"vue-eslint-parser": "^9.0.2",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.72.1",
"webpack-cli": "^4.9.2"
},
"dependencies": {
"@nextcloud/axios": "^1.10.0",
"@nextcloud/dialogs": "^3.1.2",
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^5.3.1",
"vue": "^2.6.14",
"vue-router": "^3.5.3",
"vuex": "^3.6.2"
}
}

View File

@ -21,6 +21,5 @@ export default {
created() {
this.$store.dispatch('loadFolder')
},
}
</script>

View File

@ -2,15 +2,15 @@
<div id="explore">
<AddFeed v-if="showAddFeed" :feed="feed" @close="closeShowAddFeed()" />
<div class="grid-container">
<div v-for="entry in explorableSites"
<div v-for="entry in exploreSites"
:key="entry.title"
class="explore-feed grid-item">
<h2 v-if="entry.favicon"
class="explore-title"
:style="{ backgroundImage: 'url(' + entry.favicon + ')' }">
<a target="_blank" rel="noreferrer" :href="entry.url">{{
entry.title
}}</a>
<a target="_blank" rel="noreferrer" :href="entry.url">
{{ entry.title }}
</a>
</h2>
<h2 v-if="!entry.favicon" class="icon-rss explore-title">
{{ entry.title }}
@ -30,58 +30,56 @@
</div>
</template>
<script>
/* eslint-disable vue/require-prop-type-constructor */
// import Modal from '@nextcloud/vue/dist/Components/Modal'
<script lang="ts">
import Vue from 'vue'
import Button from '@nextcloud/vue/dist/Components/Button'
import axios from '@nextcloud/axios'
import AddFeed from './AddFeed'
import AddFeed from './AddFeed.vue'
import { generateUrl } from '@nextcloud/router'
export default {
const ExploreComponent = Vue.extend({
components: {
// Modal,
Button,
AddFeed,
},
props: {
feed: '',
},
data() {
data: () => {
const exploreSites: any[] = []
const feed: any = {}
const showAddFeed = false
return {
explorableSites: [],
showAddFeed: false,
exploreSites,
feed,
showAddFeed,
}
},
created() {
this.sites()
},
methods: {
async sites() {
const settings = await axios.get(
generateUrl('/apps/news/settings')
)
// console.log(settings.data)
// console.log(settings.data.settings.exploreUrl)
const settings = await axios.get(generateUrl('/apps/news/settings'))
const exploreUrl
= settings.data.settings.exploreUrl + 'feeds.en.json'
const exploreUrl = settings.data.settings.exploreUrl + 'feeds.en.json'
const explore = await axios.get(exploreUrl)
Object.keys(explore.data).forEach((key) =>
explore.data[key].forEach((value) =>
this.explorableSites.push(value)
)
explore.data[key].forEach((value: any) =>
this.exploreSites.push(value),
),
)
},
async subscribe(feed) {
// this.feed = feed
async subscribe(feed: any) {
this.feed = feed
this.showAddFeed = true
},
closeShowAddFeed() {
this.showAddFeed = false
},
},
}
})
export default ExploreComponent
</script>

View File

@ -11,8 +11,7 @@
icon="icon-add-folder"
@new-item="newFolder" />
<AppNavigationItem :title="t('news', 'Unread articles')"
icon="icon-rss">
<AppNavigationItem :title="t('news', 'Unread articles')" icon="icon-rss">
<template #actions>
<ActionButton icon="icon-checkmark" @click="alert('Edit')">
t('news','Mark read')
@ -22,16 +21,14 @@
<CounterBubble>5</CounterBubble>
</template>
</AppNavigationItem>
<AppNavigationItem :title="t('news', 'All articles')"
icon="icon-rss">
<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">
<AppNavigationItem :title="t('news', 'Starred')" icon="icon-starred">
<template #counter>
<CounterBubble>35</CounterBubble>
</template>
@ -53,12 +50,10 @@
<div v-if="!feed.faviconLink" class="icon-rss" />
</template>
<template #actions>
<ActionButton icon="icon-checkmark"
@click="alert('Mark read')">
<ActionButton icon="icon-checkmark" @click="alert('Mark read')">
{{ t("news", "Mark read") }}
</ActionButton>
<ActionButton icon="icon-pinned"
@click="alert('Rename')">
<ActionButton icon="icon-pinned" @click="alert('Rename')">
{{ t("news", "Unpin from top") }}
</ActionButton>
<ActionButton icon="icon-caret-dark"
@ -89,16 +84,14 @@
@click="deleteFolder(folder)">
{{ t("news", "Ignore updated") }}
</ActionButton>
<ActionButton icon="icon-icon-rss"
@click="deleteFolder(folder)">
<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)">
<ActionButton icon="icon-delete" @click="deleteFolder(folder)">
{{ t("news", "Delete") }}
</ActionButton>
</template>
@ -108,15 +101,13 @@
<CounterBubble>{{ folder.feedCount }}</CounterBubble>
</template>
<template #actions>
<ActionButton icon="icon-checkmark"
@click="alert('Mark read')">
<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)">
<ActionButton icon="icon-delete" @click="deleteFolder(folder)">
{{ t("news", "Delete") }}
</ActionButton>
</template>
@ -142,7 +133,7 @@ import AppNavigationNewItem from '@nextcloud/vue/dist/Components/AppNavigationNe
// 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'
import AddFeed from './AddFeed.vue'
export default {
components: {
@ -155,7 +146,7 @@ export default {
ActionButton,
AddFeed,
},
data() {
data: () => {
return {
showAddFeed: false,
}
@ -165,7 +156,9 @@ export default {
return this.$store.state.folders
},
},
created() {},
created() {
// TODO?
},
methods: {
newFolder(value) {
const folderName = value.trim()
@ -182,6 +175,9 @@ export default {
closeShowAddFeed() {
this.showAddFeed = false
},
alert(msg) {
window.alert(msg)
},
},
}
</script>

View File

@ -1,10 +1,10 @@
import Vue from 'vue'
import App from './App'
import App from './App.vue'
import VueRouter from 'vue-router'
import Explore from './components/Explore'
import Explore from './components/Explore.vue'
import { generateUrl } from '@nextcloud/router'
import Vuex from 'vuex'
import Vuex, { Store } from 'vuex'
import axios from '@nextcloud/axios'
import { Tooltip } from '@nextcloud/vue'
@ -36,7 +36,7 @@ const router = new VueRouter({
routes,
})
const store = new Vuex.Store({
const store = new Store({
state: {
folders: [],
feeds: [],
@ -52,10 +52,12 @@ const store = new Vuex.Store({
feeds.forEach((it) => {
state.feeds.push(it)
const folder = state.folders.find(
(folder) => folder.id === it.folderId
(folder) => folder.id === it.folderId,
)
folder.feeds.push(it)
folder.feedCount += it.unreadCount
if (folder) {
folder.feeds.push(it)
folder.feedCount += it.unreadCount
}
})
},
},
@ -64,7 +66,7 @@ const store = new Vuex.Store({
axios
.post(folderUrl, { folderName: folder.name })
.then((response) =>
commit('addFolders', response.data.folders)
commit('addFolders', response.data.folders),
)
},
deleteFolder({ commit }, { folder }) {
@ -72,7 +74,6 @@ const store = new Vuex.Store({
this.getByFolderId(folderId).forEach(function (feed) {
promises.push(self.reversiblyDelete(feed.id, false, true));
});
this.updateUnreadCache();
*/
axios.delete(folderUrl + '/' + folder.id).then()
@ -83,7 +84,7 @@ const store = new Vuex.Store({
axios
.get(feedUrl)
.then((response) =>
commit('addFeeds', response.data.feeds)
commit('addFeeds', response.data.feeds),
)
})
},

18
src/shims-tsx.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
/**
* Initially copied from typescript+vue2 project generated by @vue/cli-plugin v5.0.0
*/
import Vue, { VNode } from "vue";
declare global {
namespace JSX {
interface Element extends VNode { }
interface ElementClass extends Vue { }
interface IntrinsicElements {
[elem: string]: any;
}
}
t;
n;
OC;
OCA;
};

11
src/shims-vue.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
/**
* Initially copied from typescript+vue2 project generated by @vue/cli-plugin v5.0.0
*/
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
};
declare module '@nextcloud/vue/dist/Components/Button' {
};

48
tsconfig.json Normal file
View File

@ -0,0 +1,48 @@
/**
* Initially copied from typescript+vue2 project generated by @vue/cli-plugin v5.0.0
*/
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env",
// TODO: Add these back when we add unit testing
// "mocha",
// "chai"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/*.ts",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}

View File

@ -1,3 +1,20 @@
const webpackConfig = require('@nextcloud/webpack-vue-config')
// Add TS Loader for processing typescript in vue templates
webpackConfig.module.rules.push({
test: /.ts$/,
exclude: [/node_modules/],
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
appendTsSuffixTo: [
'\\.vue$',
],
},
},
],
})
module.exports = webpackConfig