diff options
Diffstat (limited to 'client/src/app/+admin')
21 files changed, 114 insertions, 93 deletions
diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts index fd648a425..8d1c3eadb 100644 --- a/client/src/app/+admin/admin.module.ts +++ b/client/src/app/+admin/admin.module.ts | |||
@@ -3,6 +3,7 @@ import { SelectButtonModule } from 'primeng/selectbutton' | |||
3 | import { TableModule } from 'primeng/table' | 3 | import { TableModule } from 'primeng/table' |
4 | import { NgModule } from '@angular/core' | 4 | import { NgModule } from '@angular/core' |
5 | import { SharedAbuseListModule } from '@app/shared/shared-abuse-list' | 5 | import { SharedAbuseListModule } from '@app/shared/shared-abuse-list' |
6 | import { SharedActorImageModule } from '@app/shared/shared-actor-image' | ||
6 | import { SharedFormModule } from '@app/shared/shared-forms' | 7 | import { SharedFormModule } from '@app/shared/shared-forms' |
7 | import { SharedGlobalIconModule } from '@app/shared/shared-icons' | 8 | import { SharedGlobalIconModule } from '@app/shared/shared-icons' |
8 | import { SharedMainModule } from '@app/shared/shared-main' | 9 | import { SharedMainModule } from '@app/shared/shared-main' |
@@ -38,6 +39,7 @@ import { JobService, LogsComponent, LogsService, SystemComponent } from './syste | |||
38 | import { DebugComponent, DebugService } from './system/debug' | 39 | import { DebugComponent, DebugService } from './system/debug' |
39 | import { JobsComponent } from './system/jobs/jobs.component' | 40 | import { JobsComponent } from './system/jobs/jobs.component' |
40 | import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersComponent, UserUpdateComponent } from './users' | 41 | import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersComponent, UserUpdateComponent } from './users' |
42 | import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module' | ||
41 | 43 | ||
42 | @NgModule({ | 44 | @NgModule({ |
43 | imports: [ | 45 | imports: [ |
@@ -49,6 +51,8 @@ import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersCom | |||
49 | SharedGlobalIconModule, | 51 | SharedGlobalIconModule, |
50 | SharedAbuseListModule, | 52 | SharedAbuseListModule, |
51 | SharedVideoCommentModule, | 53 | SharedVideoCommentModule, |
54 | SharedAccountAvatarModule, | ||
55 | SharedActorImageModule, | ||
52 | 56 | ||
53 | TableModule, | 57 | TableModule, |
54 | SelectButtonModule, | 58 | SelectButtonModule, |
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html index 622d464e4..633de9677 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.html +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | <ng-template pTemplate="header"> | 25 | <ng-template pTemplate="header"> |
26 | <tr> | 26 | <tr> |
27 | <th style="width: 150px;">Actions</th> | 27 | <th style="width: 150px;" i18n>Actions</th> |
28 | <th i18n>Follower handle</th> | 28 | <th i18n>Follower handle</th> |
29 | <th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th> | 29 | <th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th> |
30 | <th style="width: 100px;" i18n pSortableColumn="score">Score <p-sortIcon field="score"></p-sortIcon></th> | 30 | <th style="width: 100px;" i18n pSortableColumn="score">Score <p-sortIcon field="score"></p-sortIcon></th> |
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html index cf87ec05f..f4e6a60fe 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.html +++ b/client/src/app/+admin/follows/following-list/following-list.component.html | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | <ng-template pTemplate="header"> | 32 | <ng-template pTemplate="header"> |
33 | <tr> | 33 | <tr> |
34 | <th style="width: 150px;">Action</th> | 34 | <th style="width: 150px;" i18n>Action</th> |
35 | <th i18n>Host</th> | 35 | <th i18n>Host</th> |
36 | <th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th> | 36 | <th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th> |
37 | <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 37 | <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
diff --git a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html index a654e51a6..f3bcca497 100644 --- a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html +++ b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.html | |||
@@ -24,7 +24,7 @@ | |||
24 | <ng-template pTemplate="header"> | 24 | <ng-template pTemplate="header"> |
25 | <tr> | 25 | <tr> |
26 | <th style="width: 40px;"></th> | 26 | <th style="width: 40px;"></th> |
27 | <th style="width: 150px;">Action</th> | 27 | <th style="width: 150px;" i18n>Action</th> |
28 | <th style="width: 160px;" i18n *ngIf="isDisplayingRemoteVideos()">Strategy</th> | 28 | <th style="width: 160px;" i18n *ngIf="isDisplayingRemoteVideos()">Strategy</th> |
29 | <th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th > | 29 | <th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th > |
30 | <th style="width: 100px;" i18n *ngIf="isDisplayingRemoteVideos()">Total size</th> | 30 | <th style="width: 100px;" i18n *ngIf="isDisplayingRemoteVideos()">Total size</th> |
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html index 128f4962d..f5cf93adb 100644 --- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html +++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html | |||
@@ -34,12 +34,7 @@ | |||
34 | <td> | 34 | <td> |
35 | <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> | 35 | <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> |
36 | <div class="chip two-lines"> | 36 | <div class="chip two-lines"> |
37 | <img | 37 | <my-account-avatar [account]="accountBlock.blockedAccount"></my-account-avatar> |
38 | class="avatar" | ||
39 | [src]="accountBlock.blockedAccount.avatar?.path" | ||
40 | (error)="switchToDefaultAvatar($event)" | ||
41 | alt="Avatar" | ||
42 | > | ||
43 | <div> | 38 | <div> |
44 | {{ accountBlock.blockedAccount.displayName }} | 39 | {{ accountBlock.blockedAccount.displayName }} |
45 | <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span> | 40 | <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span> |
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts index 82c371f4d..d6aca10e7 100644 --- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts +++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts | |||
@@ -164,7 +164,8 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV | |||
164 | baseUrl: `${environment.originServerUrl}/videos/embed/${entry.video.uuid}`, | 164 | baseUrl: `${environment.originServerUrl}/videos/embed/${entry.video.uuid}`, |
165 | title: false, | 165 | title: false, |
166 | warningTitle: false | 166 | warningTitle: false |
167 | }) | 167 | }), |
168 | entry.video.name | ||
168 | ) | 169 | ) |
169 | } | 170 | } |
170 | 171 | ||
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html index fa4a8edfd..d360c3c51 100644 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html +++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html | |||
@@ -5,7 +5,7 @@ | |||
5 | <my-feed [syndicationItems]="syndicationItems"></my-feed> | 5 | <my-feed [syndicationItems]="syndicationItems"></my-feed> |
6 | </h1> | 6 | </h1> |
7 | 7 | ||
8 | <em>This view also shows comments from muted accounts.</em> | 8 | <em i18n>This view also shows comments from muted accounts.</em> |
9 | 9 | ||
10 | <p-table | 10 | <p-table |
11 | [value]="comments" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" | 11 | [value]="comments" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" |
@@ -86,12 +86,8 @@ | |||
86 | <td> | 86 | <td> |
87 | <a [href]="videoComment.account.localUrl" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> | 87 | <a [href]="videoComment.account.localUrl" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> |
88 | <div class="chip two-lines"> | 88 | <div class="chip two-lines"> |
89 | <img | 89 | <my-account-avatar [account]="videoComment.account"></my-account-avatar> |
90 | class="avatar" | 90 | <div> |
91 | [src]="videoComment.accountAvatarUrl" | ||
92 | alt="" | ||
93 | > | ||
94 | <div> | ||
95 | {{ videoComment.account.displayName }} | 91 | {{ videoComment.account.displayName }} |
96 | <span>{{ videoComment.by }}</span> | 92 | <span>{{ videoComment.by }}</span> |
97 | </div> | 93 | </div> |
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss index d208944fe..c9262da09 100644 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss +++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss | |||
@@ -1,17 +1,9 @@ | |||
1 | @import 'mixins'; | 1 | @import 'mixins'; |
2 | 2 | ||
3 | h1 { | 3 | my-feed { |
4 | my-feed { | 4 | margin-left: 5px; |
5 | margin-left: 5px; | 5 | display: inline-block; |
6 | display: inline-block; | 6 | width: 15px; |
7 | |||
8 | ::ng-deep { | ||
9 | my-global-icon { | ||
10 | width: 15px !important; | ||
11 | top: 0 !important; | ||
12 | } | ||
13 | } | ||
14 | } | ||
15 | } | 7 | } |
16 | 8 | ||
17 | my-global-icon { | 9 | my-global-icon { |
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 82a965313..9cbec03a1 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 | |||
@@ -23,7 +23,7 @@ | |||
23 | </a> | 23 | </a> |
24 | 24 | ||
25 | <div class="buttons"> | 25 | <div class="buttons"> |
26 | <my-edit-button *ngIf="pluginType !== PluginType.THEME" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> | 26 | <my-edit-button *ngIf="!isTheme(plugin)" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> |
27 | 27 | ||
28 | <my-button class="update-button" *ngIf="isUpdateAvailable(plugin)" (click)="update(plugin)" [loading]="isUpdating(plugin)" | 28 | <my-button class="update-button" *ngIf="isUpdateAvailable(plugin)" (click)="update(plugin)" [loading]="isUpdating(plugin)" |
29 | [label]="getUpdateLabel(plugin)" icon="refresh" [attr.disabled]="isUpdating(plugin)" | 29 | [label]="getUpdateLabel(plugin)" icon="refresh" [attr.disabled]="isUpdating(plugin)" |
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 c78b19585..1a95980ae 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 | |||
@@ -31,8 +31,6 @@ export class PluginListInstalledComponent implements OnInit { | |||
31 | plugins: PeerTubePlugin[] = [] | 31 | plugins: PeerTubePlugin[] = [] |
32 | updating: { [name: string]: boolean } = {} | 32 | updating: { [name: string]: boolean } = {} |
33 | 33 | ||
34 | PluginType = PluginType | ||
35 | |||
36 | onDataSubject = new Subject<any[]>() | 34 | onDataSubject = new Subject<any[]>() |
37 | 35 | ||
38 | constructor ( | 36 | constructor ( |
@@ -104,6 +102,10 @@ export class PluginListInstalledComponent implements OnInit { | |||
104 | return !!this.updating[this.getUpdatingKey(plugin)] | 102 | return !!this.updating[this.getUpdatingKey(plugin)] |
105 | } | 103 | } |
106 | 104 | ||
105 | isTheme (plugin: PeerTubePlugin) { | ||
106 | return plugin.type === PluginType.THEME | ||
107 | } | ||
108 | |||
107 | async uninstall (plugin: PeerTubePlugin) { | 109 | async uninstall (plugin: PeerTubePlugin) { |
108 | const res = await this.confirmService.confirm( | 110 | const res = await this.confirmService.confirm( |
109 | $localize`Do you really want to uninstall ${plugin.name}?`, | 111 | $localize`Do you really want to uninstall ${plugin.name}?`, |
@@ -128,6 +130,16 @@ export class PluginListInstalledComponent implements OnInit { | |||
128 | const updatingKey = this.getUpdatingKey(plugin) | 130 | const updatingKey = this.getUpdatingKey(plugin) |
129 | if (this.updating[updatingKey]) return | 131 | if (this.updating[updatingKey]) return |
130 | 132 | ||
133 | if (this.isMajorUpgrade(plugin)) { | ||
134 | const res = await this.confirmService.confirm( | ||
135 | $localize`This is a major plugin upgrade. Please go on the plugin homepage to check potential release notes.`, | ||
136 | $localize`Upgrade`, | ||
137 | $localize`Proceed upgrade` | ||
138 | ) | ||
139 | |||
140 | if (res === false) return | ||
141 | } | ||
142 | |||
131 | this.updating[updatingKey] = true | 143 | this.updating[updatingKey] = true |
132 | 144 | ||
133 | this.pluginApiService.update(plugin.name, plugin.type) | 145 | this.pluginApiService.update(plugin.name, plugin.type) |
@@ -156,4 +168,13 @@ export class PluginListInstalledComponent implements OnInit { | |||
156 | private getUpdatingKey (plugin: PeerTubePlugin) { | 168 | private getUpdatingKey (plugin: PeerTubePlugin) { |
157 | return plugin.name + plugin.type | 169 | return plugin.name + plugin.type |
158 | } | 170 | } |
171 | |||
172 | private isMajorUpgrade (plugin: PeerTubePlugin) { | ||
173 | if (!plugin.latestVersion) return false | ||
174 | |||
175 | const latestMajor = plugin.latestVersion.split('.')[0] | ||
176 | const currentMajor = plugin.version.split('.')[0] | ||
177 | |||
178 | return latestMajor > currentMajor | ||
179 | } | ||
159 | } | 180 | } |
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html index 1b5fe45c6..727633399 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html | |||
@@ -3,7 +3,7 @@ | |||
3 | </div> | 3 | </div> |
4 | 4 | ||
5 | <div class="search-bar"> | 5 | <div class="search-bar"> |
6 | <input type="text" (input)="onSearchChange($event)" i18n-placeholder placeholder="Search..."/> | 6 | <input type="text" (input)="onSearchChange($event)" i18n-placeholder placeholder="Search..." autofocus /> |
7 | </div> | 7 | </div> |
8 | 8 | ||
9 | <div class="alert alert-info" i18n *ngIf="pluginInstalled"> | 9 | <div class="alert alert-info" i18n *ngIf="pluginInstalled"> |
@@ -20,8 +20,8 @@ | |||
20 | <my-global-icon iconName="search"></my-global-icon> | 20 | <my-global-icon iconName="search"></my-global-icon> |
21 | 21 | ||
22 | <ng-container i18n> | 22 | <ng-container i18n> |
23 | {{ pagination.totalItems }} {pagination.totalItems, plural, =1 {result} other {results}} for "{{ search }}" | 23 | {{ pagination.totalItems }} {pagination.totalItems, plural, =1 {result} other {results}} for {{ search }}" |
24 | </ng-container> | 24 | </ng-container> |
25 | </ng-container> | 25 | </ng-container> |
26 | </div> | 26 | </div> |
27 | 27 | ||
@@ -48,6 +48,8 @@ | |||
48 | <span *ngIf="plugin.installed" class="badge badge-success">Installed</span> | 48 | <span *ngIf="plugin.installed" class="badge badge-success">Installed</span> |
49 | 49 | ||
50 | <div class="buttons"> | 50 | <div class="buttons"> |
51 | <my-edit-button *ngIf="plugin.installed === true && !isThemeSearch()" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> | ||
52 | |||
51 | <my-button class="update-button" *ngIf="plugin.installed === false" (click)="install(plugin)" [loading]="isInstalling(plugin)" | 53 | <my-button class="update-button" *ngIf="plugin.installed === false" (click)="install(plugin)" [loading]="isInstalling(plugin)" |
52 | label="Install" icon="cloud-download" [attr.disabled]="isInstalling(plugin)" | 54 | label="Install" icon="cloud-download" [attr.disabled]="isInstalling(plugin)" |
53 | ></my-button> | 55 | ></my-button> |
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts index 4c571dee4..d2c179aba 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts | |||
@@ -3,7 +3,7 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators' | |||
3 | import { Component, OnInit } from '@angular/core' | 3 | import { Component, OnInit } from '@angular/core' |
4 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service' | 5 | import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service' |
6 | import { ComponentPagination, ConfirmService, hasMoreItems, Notifier } from '@app/core' | 6 | import { ComponentPagination, ConfirmService, hasMoreItems, Notifier, PluginService } from '@app/core' |
7 | import { PeerTubePluginIndex } from '@shared/models/plugins/peertube-plugin-index.model' | 7 | import { PeerTubePluginIndex } from '@shared/models/plugins/peertube-plugin-index.model' |
8 | import { PluginType } from '@shared/models/plugins/plugin.type' | 8 | import { PluginType } from '@shared/models/plugins/plugin.type' |
9 | 9 | ||
@@ -39,6 +39,7 @@ export class PluginSearchComponent implements OnInit { | |||
39 | private searchSubject = new Subject<string>() | 39 | private searchSubject = new Subject<string>() |
40 | 40 | ||
41 | constructor ( | 41 | constructor ( |
42 | private pluginService: PluginService, | ||
42 | private pluginApiService: PluginApiService, | 43 | private pluginApiService: PluginApiService, |
43 | private notifier: Notifier, | 44 | private notifier: Notifier, |
44 | private confirmService: ConfirmService, | 45 | private confirmService: ConfirmService, |
@@ -119,6 +120,14 @@ export class PluginSearchComponent implements OnInit { | |||
119 | return this.pluginApiService.getPluginOrThemeHref(this.pluginType, name) | 120 | return this.pluginApiService.getPluginOrThemeHref(this.pluginType, name) |
120 | } | 121 | } |
121 | 122 | ||
123 | getShowRouterLink (plugin: PeerTubePluginIndex) { | ||
124 | return [ '/admin', 'plugins', 'show', this.pluginService.nameToNpmName(plugin.name, this.pluginType) ] | ||
125 | } | ||
126 | |||
127 | isThemeSearch () { | ||
128 | return this.pluginType === PluginType.THEME | ||
129 | } | ||
130 | |||
122 | async install (plugin: PeerTubePluginIndex) { | 131 | async install (plugin: PeerTubePluginIndex) { |
123 | if (this.installing[plugin.npmName]) return | 132 | if (this.installing[plugin.npmName]) return |
124 | 133 | ||
diff --git a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.html b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.html index cb2894568..ad65293d4 100644 --- a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.html +++ b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.html | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | <form *ngIf="hasRegisteredSettings()" role="form" (ngSubmit)="formValidated()" [formGroup]="form"> | 8 | <form *ngIf="hasRegisteredSettings()" role="form" (ngSubmit)="formValidated()" [formGroup]="form"> |
9 | <div class="form-group" *ngFor="let setting of registeredSettings"> | 9 | <div class="form-group" *ngFor="let setting of registeredSettings"> |
10 | <my-dynamic-form-field [form]="form" [setting]="setting" [formErrors]="formErrors"></my-dynamic-form-field> | 10 | <my-dynamic-form-field [hidden]="isSettingHidden(setting)" [form]="form" [setting]="setting" [formErrors]="formErrors"></my-dynamic-form-field> |
11 | </div> | 11 | </div> |
12 | 12 | ||
13 | <input type="submit" i18n value="Update plugin settings" [disabled]="!form.valid"> | 13 | <input type="submit" i18n value="Update plugin settings" [disabled]="!form.valid"> |
diff --git a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts index 4e60ca290..ca9ad9922 100644 --- a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts | |||
@@ -2,7 +2,7 @@ import { Subscription } from 'rxjs' | |||
2 | import { map, switchMap } from 'rxjs/operators' | 2 | import { map, switchMap } from 'rxjs/operators' |
3 | import { Component, OnDestroy, OnInit } from '@angular/core' | 3 | import { Component, OnDestroy, OnInit } from '@angular/core' |
4 | import { ActivatedRoute } from '@angular/router' | 4 | import { ActivatedRoute } from '@angular/router' |
5 | import { Notifier } from '@app/core' | 5 | import { Notifier, PluginService } from '@app/core' |
6 | import { BuildFormArgument } from '@app/shared/form-validators' | 6 | import { BuildFormArgument } from '@app/shared/form-validators' |
7 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 7 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' |
8 | import { PeerTubePlugin, RegisterServerSettingOptions } from '@shared/models' | 8 | import { PeerTubePlugin, RegisterServerSettingOptions } from '@shared/models' |
@@ -19,10 +19,12 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
19 | pluginTypeLabel: string | 19 | pluginTypeLabel: string |
20 | 20 | ||
21 | private sub: Subscription | 21 | private sub: Subscription |
22 | private npmName: string | ||
22 | 23 | ||
23 | constructor ( | 24 | constructor ( |
24 | protected formValidatorService: FormValidatorService, | 25 | protected formValidatorService: FormValidatorService, |
25 | private pluginService: PluginApiService, | 26 | private pluginService: PluginService, |
27 | private pluginAPIService: PluginApiService, | ||
26 | private notifier: Notifier, | 28 | private notifier: Notifier, |
27 | private route: ActivatedRoute | 29 | private route: ActivatedRoute |
28 | ) { | 30 | ) { |
@@ -32,9 +34,9 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
32 | ngOnInit () { | 34 | ngOnInit () { |
33 | this.sub = this.route.params.subscribe( | 35 | this.sub = this.route.params.subscribe( |
34 | routeParams => { | 36 | routeParams => { |
35 | const npmName = routeParams['npmName'] | 37 | this.npmName = routeParams['npmName'] |
36 | 38 | ||
37 | this.loadPlugin(npmName) | 39 | this.loadPlugin(this.npmName) |
38 | } | 40 | } |
39 | ) | 41 | ) |
40 | } | 42 | } |
@@ -46,7 +48,7 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
46 | formValidated () { | 48 | formValidated () { |
47 | const settings = this.form.value | 49 | const settings = this.form.value |
48 | 50 | ||
49 | this.pluginService.updatePluginSettings(this.plugin.name, this.plugin.type, settings) | 51 | this.pluginAPIService.updatePluginSettings(this.plugin.name, this.plugin.type, settings) |
50 | .subscribe( | 52 | .subscribe( |
51 | () => { | 53 | () => { |
52 | this.notifier.success($localize`Settings updated.`) | 54 | this.notifier.success($localize`Settings updated.`) |
@@ -60,18 +62,27 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
60 | return Array.isArray(this.registeredSettings) && this.registeredSettings.length !== 0 | 62 | return Array.isArray(this.registeredSettings) && this.registeredSettings.length !== 0 |
61 | } | 63 | } |
62 | 64 | ||
65 | isSettingHidden (setting: RegisterServerSettingOptions) { | ||
66 | const script = this.pluginService.getRegisteredSettingsScript(this.npmName) | ||
67 | |||
68 | if (!script?.isSettingHidden) return false | ||
69 | |||
70 | return script.isSettingHidden({ setting, formValues: this.form.value }) | ||
71 | } | ||
72 | |||
63 | private loadPlugin (npmName: string) { | 73 | private loadPlugin (npmName: string) { |
64 | this.pluginService.getPlugin(npmName) | 74 | this.pluginAPIService.getPlugin(npmName) |
65 | .pipe(switchMap(plugin => { | 75 | .pipe(switchMap(plugin => { |
66 | return this.pluginService.getPluginRegisteredSettings(plugin.name, plugin.type) | 76 | return this.pluginAPIService.getPluginRegisteredSettings(plugin.name, plugin.type) |
67 | .pipe(map(data => ({ plugin, registeredSettings: data.registeredSettings }))) | 77 | .pipe(map(data => ({ plugin, registeredSettings: data.registeredSettings }))) |
68 | })) | 78 | })) |
69 | .subscribe( | 79 | .subscribe( |
70 | ({ plugin, registeredSettings }) => { | 80 | async ({ plugin, registeredSettings }) => { |
71 | this.plugin = plugin | 81 | this.plugin = plugin |
72 | this.registeredSettings = registeredSettings | ||
73 | 82 | ||
74 | this.pluginTypeLabel = this.pluginService.getPluginTypeLabel(this.plugin.type) | 83 | this.registeredSettings = await this.translateSettings(registeredSettings) |
84 | |||
85 | this.pluginTypeLabel = this.pluginAPIService.getPluginTypeLabel(this.plugin.type) | ||
75 | 86 | ||
76 | this.buildSettingsForm() | 87 | this.buildSettingsForm() |
77 | }, | 88 | }, |
@@ -104,4 +115,27 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
104 | return registered.default | 115 | return registered.default |
105 | } | 116 | } |
106 | 117 | ||
118 | private async translateSettings (settings: RegisterServerSettingOptions[]) { | ||
119 | for (const setting of settings) { | ||
120 | for (const key of [ 'label', 'html', 'descriptionHTML' ]) { | ||
121 | if (setting[key]) setting[key] = await this.pluginService.translateBy(this.npmName, setting[key]) | ||
122 | } | ||
123 | |||
124 | if (Array.isArray(setting.options)) { | ||
125 | const newOptions = [] | ||
126 | |||
127 | for (const o of setting.options) { | ||
128 | newOptions.push({ | ||
129 | value: o.value, | ||
130 | label: await this.pluginService.translateBy(this.npmName, o.label) | ||
131 | }) | ||
132 | } | ||
133 | |||
134 | setting.options = newOptions | ||
135 | } | ||
136 | } | ||
137 | |||
138 | return settings | ||
139 | } | ||
140 | |||
107 | } | 141 | } |
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 fad30576b..d91fccc09 100644 --- a/client/src/app/+admin/plugins/shared/plugin-api.service.ts +++ b/client/src/app/+admin/plugins/shared/plugin-api.service.ts | |||
@@ -94,7 +94,6 @@ export class PluginApiService { | |||
94 | 94 | ||
95 | return this.authHttp.get<RegisteredServerSettings>(path) | 95 | return this.authHttp.get<RegisteredServerSettings>(path) |
96 | .pipe( | 96 | .pipe( |
97 | switchMap(res => this.translateSettingsLabel(npmName, res)), | ||
98 | catchError(res => this.restExtractor.handleError(res)) | 97 | catchError(res => this.restExtractor.handleError(res)) |
99 | ) | 98 | ) |
100 | } | 99 | } |
@@ -141,19 +140,4 @@ export class PluginApiService { | |||
141 | 140 | ||
142 | return `https://www.npmjs.com/package/peertube-${typeString}-${name}` | 141 | return `https://www.npmjs.com/package/peertube-${typeString}-${name}` |
143 | } | 142 | } |
144 | |||
145 | private translateSettingsLabel (npmName: string, res: RegisteredServerSettings): Observable<RegisteredServerSettings> { | ||
146 | return this.pluginService.translationsObservable | ||
147 | .pipe( | ||
148 | map(allTranslations => allTranslations[npmName]), | ||
149 | map(translations => { | ||
150 | const registeredSettings = res.registeredSettings | ||
151 | .map(r => { | ||
152 | return Object.assign({}, r, { label: peertubeTranslate(r.label, translations) }) | ||
153 | }) | ||
154 | |||
155 | return { registeredSettings } | ||
156 | }) | ||
157 | ) | ||
158 | } | ||
159 | } | 143 | } |
diff --git a/client/src/app/+admin/plugins/shared/plugin-list.component.scss b/client/src/app/+admin/plugins/shared/plugin-list.component.scss index 83030b7e0..f59a01b74 100644 --- a/client/src/app/+admin/plugins/shared/plugin-list.component.scss +++ b/client/src/app/+admin/plugins/shared/plugin-list.component.scss | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | .plugin { | 4 | .plugin { |
5 | margin: 15px 0; | 5 | margin: 15px 0; |
6 | background-color: pvar(--submenuColor); | 6 | background-color: pvar(--submenuBackgroundColor); |
7 | } | 7 | } |
8 | 8 | ||
9 | .first-row { | 9 | .first-row { |
diff --git a/client/src/app/+admin/system/debug/debug.component.html b/client/src/app/+admin/system/debug/debug.component.html index 75f3df601..2dc509383 100644 --- a/client/src/app/+admin/system/debug/debug.component.html +++ b/client/src/app/+admin/system/debug/debug.component.html | |||
@@ -1,19 +1,19 @@ | |||
1 | <div class="root"> | 1 | <div class="root"> |
2 | <h4>IP</h4> | 2 | <h4 i18n>IP address</h4> |
3 | 3 | ||
4 | <p>PeerTube thinks your web browser public IP is <strong>{{ debug?.ip }}</strong>.</p> | 4 | <p i18n>PeerTube thinks your web browser public IP is <strong>{{ debug?.ip }}</strong>.</p> |
5 | 5 | ||
6 | <p>If this is not your correct public IP, please consider fixing it because:</p> | 6 | <p i18n>If this is not your correct public IP, please consider fixing it because:</p> |
7 | <ul> | 7 | <ul> |
8 | <li>Views may not be counted correctly (reduced compared to what they should be)</li> | 8 | <li i18n>Views may not be counted correctly (reduced compared to what they should be)</li> |
9 | <li>Anti brute force system could be overzealous</li> | 9 | <li i18n>Anti brute force system could be overzealous</li> |
10 | <li>P2P system could not work correctly</li> | 10 | <li i18n>P2P system could not work correctly</li> |
11 | </ul> | 11 | </ul> |
12 | 12 | ||
13 | <p>To fix it:<p> | 13 | <p i18n>To fix it:<p> |
14 | <ul> | 14 | <ul> |
15 | <li>Check the <code>trust_proxy</code> configuration key</li> | 15 | <li i18n>Check the <code>trust_proxy</code> configuration key</li> |
16 | <li>If you run PeerTube using Docker, check you run the <code>reverse-proxy</code> with <code>network_mode: "host"</code> | 16 | <li i18n>If you run PeerTube using Docker, check you run the <code>reverse-proxy</code> with <code>network_mode: "host"</code> |
17 | (see <a href="https://github.com/Chocobozzz/PeerTube/issues/1643#issuecomment-464789666">issue 1643</a>)</li> | 17 | (see <a href="https://github.com/Chocobozzz/PeerTube/issues/1643#issuecomment-464789666">issue 1643</a>)</li> |
18 | </ul> | 18 | </ul> |
19 | </div> | 19 | </div> |
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html index 243c6556a..5e92c0f36 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/users/user-edit/user-edit.component.html | |||
@@ -72,7 +72,7 @@ | |||
72 | <div class="anchor" id="user"></div> <!-- user anchor --> | 72 | <div class="anchor" id="user"></div> <!-- user anchor --> |
73 | <div *ngIf="isCreation()" class="account-title" i18n>NEW USER</div> | 73 | <div *ngIf="isCreation()" class="account-title" i18n>NEW USER</div> |
74 | <div *ngIf="!isCreation() && user" class="account-title"> | 74 | <div *ngIf="!isCreation() && user" class="account-title"> |
75 | <my-actor-avatar-info [actor]="user.account"></my-actor-avatar-info> | 75 | <my-actor-avatar-edit [actor]="user.account" [editable]="false" [displaySubscribers]="false" [displayUsername]="false"></my-actor-avatar-edit> |
76 | </div> | 76 | </div> |
77 | </div> | 77 | </div> |
78 | 78 | ||
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.scss b/client/src/app/+admin/users/user-edit/user-edit.component.scss index aa87b8d6d..8b0ac8783 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.scss +++ b/client/src/app/+admin/users/user-edit/user-edit.component.scss | |||
@@ -72,11 +72,3 @@ input[type=submit], button { | |||
72 | @include dashboard; | 72 | @include dashboard; |
73 | max-width: 900px; | 73 | max-width: 900px; |
74 | } | 74 | } |
75 | |||
76 | my-actor-avatar-info ::ng-deep { | ||
77 | .actor-img-edit-container, | ||
78 | .actor-info-followers, | ||
79 | .actor-info-username { | ||
80 | display: none; | ||
81 | } | ||
82 | } | ||
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html index 4a09fb392..e114f3425 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.html +++ b/client/src/app/+admin/users/user-list/user-list.component.html | |||
@@ -106,13 +106,8 @@ | |||
106 | <td *ngIf="isSelected('username')"> | 106 | <td *ngIf="isSelected('username')"> |
107 | <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/accounts/' + user.username ]"> | 107 | <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/accounts/' + user.username ]"> |
108 | <div class="chip two-lines"> | 108 | <div class="chip two-lines"> |
109 | <img | 109 | <my-account-avatar [account]="user?.account"></my-account-avatar> |
110 | class="avatar" | 110 | <div> |
111 | [src]="user?.account?.avatar?.path" | ||
112 | (error)="switchToDefaultAvatar($event)" | ||
113 | alt="Avatar" | ||
114 | > | ||
115 | <div> | ||
116 | <span class="user-table-primary-text">{{ user.account.displayName }}</span> | 111 | <span class="user-table-primary-text">{{ user.account.displayName }}</span> |
117 | <span class="text-muted">{{ user.username }}</span> | 112 | <span class="text-muted">{{ user.username }}</span> |
118 | </div> | 113 | </div> |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index 7875b74ad..339e18206 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts | |||
@@ -163,10 +163,6 @@ export class UserListComponent extends RestTable implements OnInit { | |||
163 | this.loadData() | 163 | this.loadData() |
164 | } | 164 | } |
165 | 165 | ||
166 | switchToDefaultAvatar ($event: Event) { | ||
167 | ($event.target as HTMLImageElement).src = Account.GET_DEFAULT_AVATAR_URL() | ||
168 | } | ||
169 | |||
170 | async unbanUsers (users: User[]) { | 166 | async unbanUsers (users: User[]) { |
171 | const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`) | 167 | const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`) |
172 | if (res === false) return | 168 | if (res === false) return |