From b5f919ac8eb2a1c20e26582fdfd377d687710d8f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 12 Jul 2019 11:39:58 +0200 Subject: WIP plugins: update plugin --- .../plugin-list-installed.component.html | 5 ++- .../plugin-list-installed.component.scss | 4 ++ .../plugin-list-installed.component.ts | 43 +++++++++++++++++++++- .../+admin/plugins/shared/plugin-api.service.ts | 13 ++++++- client/src/app/core/plugins/plugin.service.ts | 6 ++- .../src/app/shared/buttons/button.component.html | 4 +- .../src/app/shared/buttons/button.component.scss | 6 +++ client/src/app/shared/buttons/button.component.ts | 1 + .../app/shared/misc/small-loader.component.html | 2 +- client/src/app/shared/misc/utils.ts | 18 +++++++++ 10 files changed, 94 insertions(+), 8 deletions(-) (limited to 'client/src') diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html index d4501490f..f10b4eb8d 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html @@ -26,8 +26,11 @@ Homepage + - + diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss index f250404ed..7641c507b 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss @@ -35,3 +35,7 @@ @include peertube-button-link; @include button-with-icon(21px, 0, -2px); } + +.update-button[disabled="true"] /deep/ .action-button { + cursor: default !important; +} diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts index 26a9a616e..67a11c3a8 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts @@ -6,6 +6,7 @@ import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pa import { ConfirmService, Notifier } from '@app/core' import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' import { ActivatedRoute, Router } from '@angular/router' +import { compareSemVer } from '@app/shared/misc/utils' @Component({ selector: 'my-plugin-list-installed', @@ -26,6 +27,9 @@ export class PluginListInstalledComponent implements OnInit { sort = 'name' plugins: PeerTubePlugin[] = [] + updating: { [name: string]: boolean } = {} + + PluginType = PluginType constructor ( private i18n: I18n, @@ -49,7 +53,7 @@ export class PluginListInstalledComponent implements OnInit { this.pagination.currentPage = 1 this.plugins = [] - this.router.navigate([], { queryParams: { pluginType: this.pluginType }}) + this.router.navigate([], { queryParams: { pluginType: this.pluginType } }) this.loadMorePlugins() } @@ -82,6 +86,18 @@ export class PluginListInstalledComponent implements OnInit { return this.i18n('You don\'t have themes installed yet.') } + isUpdateAvailable (plugin: PeerTubePlugin) { + return plugin.latestVersion && compareSemVer(plugin.latestVersion, plugin.version) > 0 + } + + getUpdateLabel (plugin: PeerTubePlugin) { + return this.i18n('Update to {{version}}', { version: plugin.latestVersion }) + } + + isUpdating (plugin: PeerTubePlugin) { + return !!this.updating[this.getUpdatingKey(plugin)] + } + async uninstall (plugin: PeerTubePlugin) { const res = await this.confirmService.confirm( this.i18n('Do you really want to uninstall {{pluginName}}?', { pluginName: plugin.name }), @@ -102,7 +118,32 @@ export class PluginListInstalledComponent implements OnInit { ) } + async update (plugin: PeerTubePlugin) { + const updatingKey = this.getUpdatingKey(plugin) + if (this.updating[updatingKey]) return + + this.updating[updatingKey] = true + + this.pluginService.update(plugin.name, plugin.type) + .pipe() + .subscribe( + res => { + this.updating[updatingKey] = false + + this.notifier.success(this.i18n('{{pluginName}} updated.', { pluginName: plugin.name })) + + Object.assign(plugin, res) + }, + + err => this.notifier.error(err.message) + ) + } + getShowRouterLink (plugin: PeerTubePlugin) { return [ '/admin', 'plugins', 'show', this.pluginService.nameToNpmName(plugin.name, plugin.type) ] } + + private getUpdatingKey (plugin: PeerTubePlugin) { + return plugin.name + plugin.type + } } diff --git a/client/src/app/+admin/plugins/shared/plugin-api.service.ts b/client/src/app/+admin/plugins/shared/plugin-api.service.ts index 1d33cd179..89f190675 100644 --- a/client/src/app/+admin/plugins/shared/plugin-api.service.ts +++ b/client/src/app/+admin/plugins/shared/plugin-api.service.ts @@ -9,7 +9,7 @@ import { ComponentPagination } from '@app/shared/rest/component-pagination.model import { ResultList } from '@shared/models' import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' import { ManagePlugin } from '@shared/models/plugins/manage-plugin.model' -import { InstallPlugin } from '@shared/models/plugins/install-plugin.model' +import { InstallOrUpdatePlugin } from '@shared/models/plugins/install-plugin.model' import { RegisterSettingOptions } from '@shared/models/plugins/register-setting.model' @Injectable() @@ -89,8 +89,17 @@ export class PluginApiService { .pipe(catchError(res => this.restExtractor.handleError(res))) } + update (pluginName: string, pluginType: PluginType) { + const body: ManagePlugin = { + npmName: this.nameToNpmName(pluginName, pluginType) + } + + return this.authHttp.post(PluginApiService.BASE_APPLICATION_URL + '/update', body) + .pipe(catchError(res => this.restExtractor.handleError(res))) + } + install (npmName: string) { - const body: InstallPlugin = { + const body: InstallOrUpdatePlugin = { npmName } diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts index 86bde2d02..c6ba3dd17 100644 --- a/client/src/app/core/plugins/plugin.service.ts +++ b/client/src/app/core/plugins/plugin.service.ts @@ -48,7 +48,9 @@ export class PluginService { .toPromise() } - addPlugin (plugin: ServerConfigPlugin) { + addPlugin (plugin: ServerConfigPlugin, isTheme = false) { + const pathPrefix = isTheme ? '/themes' : '/plugins' + for (const key of Object.keys(plugin.clientScripts)) { const clientScript = plugin.clientScripts[key] @@ -58,7 +60,7 @@ export class PluginService { this.scopes[scope].push({ plugin, clientScript: { - script: environment.apiUrl + `/plugins/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`, + script: environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`, scopes: clientScript.scopes } }) diff --git a/client/src/app/shared/buttons/button.component.html b/client/src/app/shared/buttons/button.component.html index b6df67102..d2b0eb81a 100644 --- a/client/src/app/shared/buttons/button.component.html +++ b/client/src/app/shared/buttons/button.component.html @@ -1,4 +1,6 @@ - + + + {{ label }} diff --git a/client/src/app/shared/buttons/button.component.scss b/client/src/app/shared/buttons/button.component.scss index 99d7f51c1..4cc2b0573 100644 --- a/client/src/app/shared/buttons/button.component.scss +++ b/client/src/app/shared/buttons/button.component.scss @@ -1,6 +1,12 @@ @import '_variables'; @import '_mixins'; +my-small-loader /deep/ .root { + display: inline-block; + margin: 0 3px 0 0; + width: 20px; +} + .action-button { @include peertube-button-link; @include button-with-icon(21px, 0, -2px); diff --git a/client/src/app/shared/buttons/button.component.ts b/client/src/app/shared/buttons/button.component.ts index cf334e8d5..cac5ad210 100644 --- a/client/src/app/shared/buttons/button.component.ts +++ b/client/src/app/shared/buttons/button.component.ts @@ -12,6 +12,7 @@ export class ButtonComponent { @Input() className = 'grey-button' @Input() icon: GlobalIconName = undefined @Input() title: string = undefined + @Input() loading = false getTitle () { return this.title || this.label diff --git a/client/src/app/shared/misc/small-loader.component.html b/client/src/app/shared/misc/small-loader.component.html index 5a7cea738..7886f8918 100644 --- a/client/src/app/shared/misc/small-loader.component.html +++ b/client/src/app/shared/misc/small-loader.component.html @@ -1,3 +1,3 @@ -
+
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts index 85fc1c3a0..098496d45 100644 --- a/client/src/app/shared/misc/utils.ts +++ b/client/src/app/shared/misc/utils.ts @@ -134,6 +134,23 @@ function scrollToTop () { window.scroll(0, 0) } +// Thanks https://stackoverflow.com/a/16187766 +function compareSemVer (a: string, b: string) { + const regExStrip0 = /(\.0+)+$/ + const segmentsA = a.replace(regExStrip0, '').split('.') + const segmentsB = b.replace(regExStrip0, '').split('.') + + const l = Math.min(segmentsA.length, segmentsB.length) + + for (let i = 0; i < l; i++) { + const diff = parseInt(segmentsA[ i ], 10) - parseInt(segmentsB[ i ], 10) + + if (diff) return diff + } + + return segmentsA.length - segmentsB.length +} + export { sortBy, durationToString, @@ -144,6 +161,7 @@ export { getAbsoluteAPIUrl, dateToHuman, immutableAssign, + compareSemVer, objectToFormData, objectLineFeedToHtml, removeElementFromArray, -- cgit v1.2.3