Skip to content

Commit

Permalink
add ng-select for templatable select options
Browse files Browse the repository at this point in the history
  • Loading branch information
rigelk committed Aug 7, 2020
1 parent be59656 commit 155fc34
Show file tree
Hide file tree
Showing 25 changed files with 321 additions and 96 deletions.
4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@angularclass/hmr": "^2.1.3",
"@neos21/bootstrap3-glyphicons": "^1.0.1",
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
"@ng-select/ng-select": "^5.0.0",
"@ngx-i18nsupport/ngx-i18nsupport": "^1.1.6",
"@ngx-i18nsupport/tooling": "^8.0.3",
"@ngx-loading-bar/core": "^5.0.0",
Expand Down Expand Up @@ -133,6 +134,5 @@
"webtorrent": "^0.108.1",
"whatwg-fetch": "^3.0.0",
"zone.js": "~0.10.2"
},
"dependencies": {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ <h4 i18n class="modal-title">Add caption</h4>

<div class="modal-body">
<label i18n for="language">Language</label>
<div class="peertube-select-container">
<select id="language" formControlName="language" class="form-control">
<option></option>
<option *ngFor="let language of videoCaptionLanguages" [value]="language.id">{{ language.label }}</option>
</select>
<div class="peertube-ng-select-container">
<ng-select
labelForId="language" [items]="videoCaptionLanguages" formControlName="language"
bindLabel="label" bindValue="id"
></ng-select>
</div>

<div *ngIf="formErrors.language" class="form-error">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@import '_variables';
@import '_mixins';

.peertube-select-container {
@include peertube-select-container(auto);
label {
font-weight: $font-regular;
font-size: 100%;
}

.caption-file {
Expand Down
67 changes: 29 additions & 38 deletions client/src/app/+videos/+video-edit/shared/video-edit.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@
</ng-template>
</my-help>

<tag-input
[validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
i18n-placeholder placeholder="+ Tag" i18n-secondaryPlaceholder secondaryPlaceholder="Enter a new tag"
formControlName="tags" [maxItems]="5" [modelAsStrings]="true"
></tag-input>
<ng-select
i18n-placeholder placeholder="Enter a new tag"
formControlName="tags"
[maxSelectedItems]="5"
[addTag]="true"
[multiple]="true"
[selectOnTab]="true"
[isOpen]="false">
</ng-select>
<div *ngIf="formErrors.tags" class="form-error">
{{ formErrors.tags }}
</div>
</div>

<div class="form-group">
Expand All @@ -56,22 +63,15 @@

<div class="col-video-edit">
<div class="form-group">
<label i18n>Channel</label>
<div class="peertube-select-container">
<select formControlName="channelId" class="form-control">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
</div>
<label i18n for="channel">Channel</label>
<select-channel labelForId="channel" [videoChannels]="userVideoChannels" formControlName="channelId"></select-channel>
</div>

<div class="form-group">
<label i18n for="category">Category</label>
<div class="peertube-select-container">
<select id="category" formControlName="category" class="form-control">
<option></option>
<option *ngFor="let category of videoCategories" [value]="category.id">{{ category.label }}</option>
</select>
</div>
<select-options
labelForId="category" [items]="videoCategories" formControlName="category" [clearable]="true"
></select-options>

<div *ngIf="formErrors.category" class="form-error">
{{ formErrors.category }}
Expand All @@ -80,12 +80,9 @@

<div class="form-group">
<label i18n for="licence">Licence</label>
<div class="peertube-select-container">
<select id="licence" formControlName="licence" class="form-control">
<option></option>
<option *ngFor="let licence of videoLicences" [value]="licence.id">{{ licence.label }}</option>
</select>
</div>
<select-options
labelForId="licence" [items]="videoLicences" formControlName="licence" [clearable]="true"
></select-options>

<div *ngIf="formErrors.licence" class="form-error">
{{ formErrors.licence }}
Expand All @@ -94,12 +91,10 @@

<div class="form-group">
<label i18n for="language">Language</label>
<div class="peertube-select-container">
<select id="language" formControlName="language" class="form-control">
<option></option>
<option *ngFor="let language of videoLanguages" [value]="language.id">{{ language.label }}</option>
</select>
</div>
<select-options
labelForId="language" [items]="videoLanguages" formControlName="language"
[clearable]="true" [searchable]="true" [groupBy]="'group'"
></select-options>

<div *ngIf="formErrors.language" class="form-error">
{{ formErrors.language }}
Expand All @@ -108,13 +103,9 @@

<div class="form-group">
<label i18n for="privacy">Privacy</label>
<div class="peertube-select-container">
<select id="privacy" formControlName="privacy" class="form-control">
<option></option>
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
<option *ngIf="schedulePublicationPossible" [value]="SPECIAL_SCHEDULED_PRIVACY">Scheduled</option>
</select>
</div>
<select-options
labelForId="privacy" [items]="videoPrivacies" formControlName="privacy" [clearable]="false"
></select-options>

<div *ngIf="formErrors.privacy" class="form-error">
{{ formErrors.privacy }}
Expand All @@ -136,7 +127,7 @@

<my-peertube-checkbox inputName="nsfw" formControlName="nsfw" helpPlacement="bottom-right">
<ng-template ptTemplate="label">
<ng-container i18n>This video contains mature or explicit content</ng-container>
<ng-container i18n>Contains sensitive content</ng-container>
</ng-template>

<ng-template ptTemplate="help">
Expand All @@ -146,7 +137,7 @@

<my-peertube-checkbox *ngIf="waitTranscodingEnabled" inputName="waitTranscoding" formControlName="waitTranscoding" helpPlacement="bottom-right">
<ng-template ptTemplate="label">
<ng-container i18n>Wait transcoding before publishing the video</ng-container>
<ng-container i18n>Publish after transcoding</ng-container>
</ng-template>

<ng-template ptTemplate="help">
Expand Down
36 changes: 32 additions & 4 deletions client/src/app/+videos/+video-edit/shared/video-edit.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-ma
import { ServerConfig, VideoConstant, VideoPrivacy } from '@shared/models'
import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service'
import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component'
import { I18n } from '@ngx-translate/i18n-polyfill'
import { forkJoin } from 'rxjs'
import { InstanceService } from '@app/shared/shared-instance'

type VideoLanguages = VideoConstant<string> & { group?: string }

@Component({
selector: 'my-video-edit',
Expand All @@ -31,7 +36,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
videoPrivacies: VideoConstant<VideoPrivacy>[] = []
videoCategories: VideoConstant<number>[] = []
videoLicences: VideoConstant<number>[] = []
videoLanguages: VideoConstant<string>[] = []
videoLanguages: VideoLanguages[] = []

tagValidators: ValidatorFn[]
tagValidatorsMessages: { [ name: string ]: string }
Expand All @@ -56,7 +61,9 @@ export class VideoEditComponent implements OnInit, OnDestroy {
private videoValidatorsService: VideoValidatorsService,
private videoService: VideoService,
private serverService: ServerService,
private instanceService: InstanceService,
private i18nPrimengCalendarService: I18nPrimengCalendarService,
private i18n: I18n,
private ngZone: NgZone
) {
this.tagValidators = this.videoValidatorsService.VIDEO_TAGS.VALIDATORS
Expand Down Expand Up @@ -126,11 +133,32 @@ export class VideoEditComponent implements OnInit, OnDestroy {
.subscribe(res => this.videoCategories = res)
this.serverService.getVideoLicences()
.subscribe(res => this.videoLicences = res)
this.serverService.getVideoLanguages()
.subscribe(res => this.videoLanguages = res)
forkJoin([
this.instanceService.getAbout(),
this.serverService.getVideoLanguages()
]).pipe(map(([ about, languages ]) => ({ about, languages })))
.subscribe(res => {
this.videoLanguages = res.languages
.map(l => {
if (res.about.instance.languages.includes(l.id)) {
return { ...l, group: this.i18n('Instance languages'), groupOrder: 0 }
}
return { ...l, group: this.i18n('All languages'), groupOrder: 1 }
})
.sort((a, b) => a.groupOrder - b.groupOrder)
})

this.serverService.getVideoPrivacies()
.subscribe(privacies => this.videoPrivacies = this.videoService.explainedPrivacyLabels(privacies))
.subscribe(privacies => {
this.videoPrivacies = this.videoService.explainedPrivacyLabels(privacies)
if (this.schedulePublicationPossible) {
this.videoPrivacies.push({
id: this.SPECIAL_SCHEDULED_PRIVACY,
label: this.i18n('Scheduled'),
description: this.i18n('Hide the video until a specific date')
})
}
})

this.serverConfig = this.serverService.getTmpConfig()
this.serverService.getConfig()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,16 @@

<div class="form-group">
<label i18n for="first-step-channel">Channel</label>
<div class="peertube-select-container">
<select id="first-step-channel" [(ngModel)]="firstStepChannelId" class="form-control">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
</div>
<select-channel
labelForId="first-step-channel" [videoChannels]="userVideoChannels" [(ngModel)]="firstStepChannelId"
></select-channel>
</div>

<div class="form-group">
<label i18n for="first-step-privacy">Privacy</label>
<div class="peertube-select-container">
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId" class="form-control">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select>
</div>
<select-options
labelForId="first-step-privacy" [items]="videoPrivacies" [(ngModel)]="firstStepPrivacyId"
></select-options>
</div>

<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,16 @@

<div class="form-group">
<label i18n for="first-step-channel">Channel</label>
<div class="peertube-select-container">
<select id="first-step-channel" [(ngModel)]="firstStepChannelId" class="form-control">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
</div>
<select-channel
labelForId="first-step-channel" [videoChannels]="userVideoChannels" [(ngModel)]="firstStepChannelId"
></select-channel>
</div>

<div class="form-group">
<label i18n for="first-step-privacy">Privacy</label>
<div class="peertube-select-container">
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId" class="form-control">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select>
</div>
<select-options
labelForId="first-step-privacy" [items]="videoPrivacies" [(ngModel)]="firstStepPrivacyId"
></select-options>
</div>

<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ $width-size: 190px;
.peertube-select-container {
@include peertube-select-container($width-size);
}
select-options,
select-channel {
width: $width-size;
@media screen and (max-width: $width-size) {
width: 100%;
}
}

input[type=text] {
@include peertube-input-text($width-size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ServerConfig, VideoConstant, VideoPrivacy } from '@shared/models'
@Directive()
// tslint:disable-next-line: directive-class-suffix
export abstract class VideoSend extends FormReactive implements OnInit {
userVideoChannels: { id: number, label: string, support: string }[] = []
userVideoChannels: { id: number, label: string, support: string, avatarPath?: string }[] = []
videoPrivacies: VideoConstant<VideoPrivacy>[] = []
videoCaptions: VideoCaptionEdit[] = []

Expand Down Expand Up @@ -44,7 +44,7 @@ export abstract class VideoSend extends FormReactive implements OnInit {
this.serverService.getVideoPrivacies()
.subscribe(
privacies => {
this.videoPrivacies = privacies
this.videoPrivacies = this.videoService.explainedPrivacyLabels(privacies)

this.firstStepPrivacyId = this.DEFAULT_VIDEO_PRIVACY
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,16 @@

<div class="form-group form-group-channel">
<label i18n for="first-step-channel">Channel</label>
<div class="peertube-select-container">
<select id="first-step-channel" [(ngModel)]="firstStepChannelId" class="form-control">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
</div>
<select-channel
labelForId="first-step-channel" [videoChannels]="userVideoChannels" [(ngModel)]="firstStepChannelId"
></select-channel>
</div>

<div class="form-group">
<label i18n for="first-step-privacy">Privacy</label>
<div class="peertube-select-container">
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId" class="form-control">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
<option i18n [value]="SPECIAL_SCHEDULED_PRIVACY">Scheduled</option>
</select>
</div>
<select-options
labelForId="first-step-privacy" [items]="videoPrivacies" [(ngModel)]="firstStepPrivacyId"
></select-options>
</div>

<ng-container *ngIf="isUploadingAudioFile">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
video: VideoEdit

isUpdatingVideo = false
userVideoChannels: { id: number, label: string, support: string }[] = []
userVideoChannels: { id: number, label: string, support: string, avatar?: string }[] = []
schedulePublicationPossible = false
videoCaptions: VideoCaptionEdit[] = []
waitTranscodingEnabled = true
Expand Down
7 changes: 6 additions & 1 deletion client/src/app/+videos/+video-edit/video-update.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ export class VideoUpdateResolver implements Resolve<any> {
.listAccountVideoChannels(video.account)
.pipe(
map(result => result.data),
map(videoChannels => videoChannels.map(c => ({ id: c.id, label: c.displayName, support: c.support })))
map(videoChannels => videoChannels.map(c => ({
id: c.id,
label: c.displayName,
support: c.support,
avatarPath: c.avatar?.path
})))
),

this.videoCaptionService
Expand Down
7 changes: 5 additions & 2 deletions client/src/app/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ function getParameterByName (name: string, url: string) {
return decodeURIComponent(results[2].replace(/\+/g, ' '))
}

function populateAsyncUserVideoChannels (authService: AuthService, channel: { id: number, label: string, support?: string }[]) {
function populateAsyncUserVideoChannels (
authService: AuthService,
channel: { id: number, label: string, support?: string, avatarPath?: string, recent?: boolean }[]
) {
return new Promise(res => {
authService.userInformationLoaded
.subscribe(
Expand All @@ -27,7 +30,7 @@ function populateAsyncUserVideoChannels (authService: AuthService, channel: { id
const videoChannels = user.videoChannels
if (Array.isArray(videoChannels) === false) return

videoChannels.forEach(c => channel.push({ id: c.id, label: c.displayName, support: c.support }))
videoChannels.forEach(c => channel.push({ id: c.id, label: c.displayName, support: c.support, avatarPath: c.avatar?.path }))

return res()
}
Expand Down
Loading

0 comments on commit 155fc34

Please sign in to comment.