From b002ba6008acf8d18a4a95955a6dca38eee1b682 Mon Sep 17 00:00:00 2001 From: Devlin Junker Date: Mon, 16 Oct 2023 13:12:30 -0700 Subject: [PATCH 1/3] start documentation rewrite Signed-off-by: Devlin Junker --- css/explore.css | 47 -------------- docs/developer.md | 17 ++++- docs/features/plugins.md | 134 +++++++++++++++++++-------------------- 3 files changed, 81 insertions(+), 117 deletions(-) diff --git a/css/explore.css b/css/explore.css index b9894e425..155ff450e 100644 --- a/css/explore.css +++ b/css/explore.css @@ -16,51 +16,4 @@ height: 100%; } -#explore { - height: 100%; - width: 100%; - padding: 45px 0 45px 45px; -} - -#explore .grid-item { - width: 300px; - border: 2px solid var(--color-border); - border-radius: var(--border-radius-large); - margin: 0 24px 24px 0; - padding: 24px; -} - -#explore .grid-item .explore-title { - background-repeat: no-repeat; - background-position: 0 center; - background-size: 24px; - padding-left: 32px; -} - -#explore .grid-item .explore-title a { - word-wrap: break-word; -} - -#explore .grid-item .explore-title a:hover, -#explore .grid-item .explore-title a:focus { - text-decoration: underline; -} - -#explore .grid-item .explore-logo { - text-align: center; - margin-top: 25px; -} - -#explore .grid-item .explore-logo img { - width: 100%; -} - -#explore .grid-item .explore-subscribe { - margin-top: 16px; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - /*# sourceMappingURL=explore.css.map */ diff --git a/docs/developer.md b/docs/developer.md index 0d8f26f04..16cae9750 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -27,11 +27,22 @@ Check the Nextcloud [documentation](https://docs.nextcloud.com/server/latest/dev When your setup is running, clone the news repository in the `apps/` directory inside the server. -Change into the news directory and run make to build the app, you will need php, composer, node, npm and maybe more. +Change into the news directory and run `make` to build the app, you will need php, composer, node, npm and maybe more. -Now you can basically use the news app and test your changes. +Now you can basically use the news app and test any changes you make on your local development environment. Check out the `appinfo/routes.php` file and `lib/controller/` directory for details on API controllers. Or check out `package.json` for npm scripts and the `src/` directory for the front end Vue Application. -## Running Integration tests locally +### Frontend Tips/Organization +- We use the Nextcloud Vue component library for most of the form controls and navigation +- Vuex is used for state management, this is similar to Redux and has Actions/Mutations and Getters +- We are using the Nextcloud Webpack Vue configuration and have enabled Typescript support and importing in the Vue components +- We use ESLint and StyleLint for ensuring correct formatting of the Scripts and HTML + +## Testing +Please make sure to run all tests before submitting any pull requests. + +### Frontend Unit Tests +Frontend unit tests are written with Jest and can be run with `npm run test`. +### API and CLI Integration Tests We use [bats](https://bats-core.readthedocs.io/en/stable/) to run integration tests against the API and the cli. Check how to install bats on your system in the [official documentation](https://bats-core.readthedocs.io/en/stable/installation.html). diff --git a/docs/features/plugins.md b/docs/features/plugins.md index dcc8c2c51..c4a362f92 100644 --- a/docs/features/plugins.md +++ b/docs/features/plugins.md @@ -9,52 +9,93 @@ There are essentially three different use cases for plugins: * Dropping in additional CSS or JavaScript ## The Basics -Whatever plugin you want to create, you first need to create a basic structure. A plugin is basically just an app, so you can take advantage of the full [Nextcloud app API](https://docs.nextcloud.org/server/latest/developer_manual/app/index.html). If you want you can [take a look at the developer docs](https://docs.nextcloud.org/server/latest/developer_manual/app/index.html) or [dig into the tutorial](https://docs.nextcloud.org/server/latest/developer_manual/app/tutorial.html). +Whatever plugin you want to create, you first need to create a basic structure. A plugin is basically just an app, so you can take advantage of the full [Nextcloud app API](https://docs.nextcloud.org/server/latest/developer_manual/app/index.html). [Take a look at the developer docs](https://docs.nextcloud.com/server/latest/developer_manual/app_development/index.html) or [dig into the tutorial](https://docs.nextcloud.com/server/latest/developer_manual/app_development/tutorial.html). However, if you just want to start slow, the full process is described below. -First create the following directories and files: +First create a skeleton app using the [web interface](https://apps.nextcloud.com/developer/apps/generate) + +The application name affects the name and namespace of your plugin and only one app can exist using the same name. Choose wisely. This will become the directory name in the Nextcloud `apps/` directory * **newsplugin/** * **appinfo/** * **app.php** * **info.xml** -The first folder name affects the name and namespace of your plugin and only one app can exist using the same name. Choose wisely. - -First let's add some meta ata about our app. Open the **newsplugin/appinfo/info.xml** and add the following contents: - -```xml - - - newsplugin - Example News Plugin - This plugin allows you to share articles via Twitter - AGPL - Your Name Here - 0.0.1 - - - - - - +**Note**: You must license your app under the [AGPL 3 or later](https://www.gnu.org/licenses/agpl-3.0.en.html) to comply with the News app's license. Don't forget to add the license as plain text file if you want to distribute your app! + +Then we want to make sure that our code is only run if the News app is enabled. To do that put the following PHP code into the **newsplugin/lib/AppInfo/Application.php** file: + +```php +getContainer(); + + $container->registerService('NewsContainer', function($c) { + $app = new News(); + return $app->getContainer(); + }); + + $container->registerService(OCA\News\Service\FeedService::class, function($c) { + // use the feed service from the news app, you can use all + // defined classes but its recommended that you stick to the + // mapper and service classes since they are less likely to change + return $c->query('NewsContainer')->query(OCA\News\Service\FeedService::class); + }); + } + } ``` +Using automatic container assembly you can then use it from your code by simply adding the type to your constructors. + + + + +# TODO: Update the following + If your plugin integrates with another Nextcloud app, make sure to also require it be installed. If you depend on the Bookmarks app for instance use: ```php @@ -159,47 +200,6 @@ Then open the **newspluing/css/style.css** file and add the following CSS: Reload the News app and click the three dots menu, sit back and enjoy :) -## Server-Side Plugin -A Server-Side plugin is a plugin that uses the same infrastructure as the News app for its own purposes. An example would be a plugin that makes the starred entries of a user available via an interface or a bookmark app that also shows starred articles as bookmarks. - -It's very easy to interface with the News app. Because all Classes are registered in the **news/app/application.php** it takes almost no effort to use the same infrastructure. - -**Note**: Keep in mind that these classes are essentially private which means they might break if the News app changes. There is no real public API so use at your own risk ;) - -Since you don't want to extend the app but use its resources, its advised that you don't inherit from the **Application** class but rather include it in your own container in **newsplugin/appinfo/application.php**: - -```php -getContainer(); - - $container->registerService('NewsContainer', function($c) { - $app = new News(); - return $app->getContainer(); - }); - - $container->registerService(OCA\News\Service\FeedService::class, function($c) { - // use the feed service from the news app, you can use all - // defined classes but its recommended that you stick to the - // mapper and service classes since they are less likely to change - return $c->query('NewsContainer')->query(OCA\News\Service\FeedService::class); - }); - } - -} -``` - -Using automatic container assembly you can then use it from your code by simply adding the type to your constructors. - ### Examples Client-side plugins: From a2405284087e2264f66753774d0ab31fc869f64b Mon Sep 17 00:00:00 2001 From: Devlin Junker Date: Mon, 16 Oct 2023 13:13:03 -0700 Subject: [PATCH 2/3] fix bug using php template for warning message Signed-off-by: Devlin Junker --- src/App.vue | 16 +++++ src/components/feed-display/FeedItemRow.vue | 2 +- src/main.js | 6 +- templates/part.content.warnings.php | 66 ++------------------- 4 files changed, 26 insertions(+), 64 deletions(-) diff --git a/src/App.vue b/src/App.vue index c78609414..5b818d6d8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,6 +3,16 @@
{{ app.error }} + +
X @@ -104,6 +114,12 @@ export default Vue.extend({ display: flex; } + #warning-box a { + color: #3a84e4; + text-decoration: underline; + font-size: small; + } + .route-container { height: 100%; } diff --git a/src/components/feed-display/FeedItemRow.vue b/src/components/feed-display/FeedItemRow.vue index 8742dff6a..4bea3d45f 100644 --- a/src/components/feed-display/FeedItemRow.vue +++ b/src/components/feed-display/FeedItemRow.vue @@ -247,6 +247,6 @@ export default Vue.extend({ } .feed-item-row .button-container .eye-check-icon { - color: var(--color-primary-light); + color: var(--color-placeholder-dark); } diff --git a/src/main.js b/src/main.js index 9a70d470f..c7314d17b 100644 --- a/src/main.js +++ b/src/main.js @@ -41,7 +41,7 @@ Vue.config.errorHandler = handleErrors export default new Vue({ router, store, - el: '#q-app', + el: '#content', render: (h) => h(App), }) @@ -51,4 +51,6 @@ export default new Vue({ function closeCronWarning() { document.getElementById('cron-warning').style.display = 'none' } -document.getElementById('close-cron-warning').onclick = closeCronWarning +// document.getElementById('close-cron-warning').onclick = closeCronWarning + +window.store = store diff --git a/templates/part.content.warnings.php b/templates/part.content.warnings.php index f68933dba..db9b2f218 100644 --- a/templates/part.content.warnings.php +++ b/templates/part.content.warnings.php @@ -1,62 +1,6 @@ - - - -
- -
- X -
-
+ +
From 7c5299d24b9e367b2f9878e680b438c94590fa0e Mon Sep 17 00:00:00 2001 From: Devlin Junker Date: Mon, 16 Oct 2023 13:48:01 -0700 Subject: [PATCH 3/3] cleanup old cron stuff and make cron-warning.js part of build so it can be committed Signed-off-by: Devlin Junker --- src/main-cron-warning.js | 11 +++++++++++ src/main.js | 9 +-------- templates/part.content.warnings.php | 2 +- webpack.js | 6 ++++++ 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 src/main-cron-warning.js diff --git a/src/main-cron-warning.js b/src/main-cron-warning.js new file mode 100644 index 000000000..298fa3b61 --- /dev/null +++ b/src/main-cron-warning.js @@ -0,0 +1,11 @@ +// Send error to Vuex State for displaying in Vue Application +window.store.commit('SET_ERROR', { + toString: () => t('news', 'Ajax or webcron mode detected! Your feeds will not be updated!'), + links: [{ + url: 'https://docs.nextcloud.org/server/latest/admin_manual/configuration_server/background_jobs_configuration.html#cron', + text: t('news', 'How to set up the operating system cron'), + }, { + url: 'https://github.com/nextcloud/news-updater', + text: t('news', 'Install and set up a faster parallel updater that uses the News app\'s update API'), + }], +}) diff --git a/src/main.js b/src/main.js index c7314d17b..97e48b442 100644 --- a/src/main.js +++ b/src/main.js @@ -45,12 +45,5 @@ export default new Vue({ render: (h) => h(App), }) -/** - * Closes warning messages generated by PHP code - */ -function closeCronWarning() { - document.getElementById('cron-warning').style.display = 'none' -} -// document.getElementById('close-cron-warning').onclick = closeCronWarning - +// Make store accessible for setting cron warning (also for plugins in the future) window.store = store diff --git a/templates/part.content.warnings.php b/templates/part.content.warnings.php index db9b2f218..cc7890a87 100644 --- a/templates/part.content.warnings.php +++ b/templates/part.content.warnings.php @@ -1,6 +1,6 @@
diff --git a/webpack.js b/webpack.js index 25c295596..55e836ef5 100644 --- a/webpack.js +++ b/webpack.js @@ -8,6 +8,12 @@ webpackConfig.entry['admin-settings'] = path.join( 'main-admin.js', ) +webpackConfig.entry['cron-warning'] = path.join( + __dirname, + 'src', + 'main-cron-warning.js', +) + webpackConfig = merge(webpackConfig, { resolve: { extensions: ['.ts'],