diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.html b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.html new file mode 100644 index 0000000000000000000000000000000000000000..1915d7b3d277c927ce213e1b508319796b7e4c4e --- /dev/null +++ b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.html @@ -0,0 +1,24 @@ +<div mat-dialog-content + *ngIf="editRoom"> + <div fxLayout="column"> + <mat-slide-toggle (change)="showMessage('words-will-be-overwritten', $event.checked)" [(ngModel)]="profanityCheck"> + {{ 'room-page.profanity-filter' | translate }} + </mat-slide-toggle> + <mat-slide-toggle *ngIf="profanityCheck" + (change)="showMessage('only-specific-language-will-be-filtered', $event.checked)" + [(ngModel)]="censorLanguageSpecificCheck"> + {{ 'room-page.language-specific-filter' | translate }} + </mat-slide-toggle> + <mat-slide-toggle *ngIf="profanityCheck" (change)="showMessage('partial-words-will-be-filtered', $event.checked)" + [(ngModel)]="censorPartialWordsCheck"> + {{ 'room-page.partial-words-filter' | translate }} + </mat-slide-toggle> + </div> +</div> +<app-dialog-action-buttons + buttonsLabelSection="room-page" + confirmButtonLabel="update" + + [cancelButtonClickAction]="buildCloseDialogActionCallback()" + [confirmButtonClickAction]="buildSaveActionCallback()" +></app-dialog-action-buttons> diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.scss b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.spec.ts b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..89f7b20011d98808e17822e7cf742950e30f2022 --- /dev/null +++ b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.spec.ts @@ -0,0 +1,25 @@ +// import { ComponentFixture, TestBed } from '@angular/core/testing'; +// +// import { ProfanitySettingsComponent } from './profanity-settings.component'; +// +// describe('ProfanitySettingsComponent', () => { +// let component: ProfanitySettingsComponent; +// let fixture: ComponentFixture<ProfanitySettingsComponent>; +// +// beforeEach(async () => { +// await TestBed.configureTestingModule({ +// declarations: [ ProfanitySettingsComponent ] +// }) +// .compileComponents(); +// }); +// +// beforeEach(() => { +// fixture = TestBed.createComponent(ProfanitySettingsComponent); +// component = fixture.componentInstance; +// fixture.detectChanges(); +// }); +// +// it('should create', () => { +// expect(component).toBeTruthy(); +// }); +// }); diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.ts b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ad81ba4ead5ed15fbf9034f0fddbaf3c604ee956 --- /dev/null +++ b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.ts @@ -0,0 +1,85 @@ +import {Component,Inject,OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA,MatDialog,MatDialogRef} from '@angular/material/dialog'; +import {RoomCreatorPageComponent} from '../../room-creator-page/room-creator-page.component'; +import {NotificationService} from '../../../../services/util/notification.service'; +import {TranslateService} from '@ngx-translate/core'; +import {RoomService} from '../../../../services/http/room.service'; +import {Router} from '@angular/router'; +import {EventService} from '../../../../services/util/event.service'; +import {ProfanityFilter,Room} from '../../../../models/room'; + +@Component({ + selector:'app-profanity-settings', + templateUrl:'./profanity-settings.component.html', + styleUrls:['./profanity-settings.component.scss'] +}) +export class ProfanitySettingsComponent implements OnInit{ + + editRoom: Room; + check=false; + profanityCheck: boolean; + censorPartialWordsCheck: boolean; + censorLanguageSpecificCheck: boolean; + + constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>, + public dialog: MatDialog, + public notificationService: NotificationService, + public translationService: TranslateService, + protected roomService: RoomService, + public router: Router, + public eventService: EventService, + @Inject(MAT_DIALOG_DATA) public data: any){ + } + + ngOnInit(){ + this.profanityCheck=this.editRoom.profanityFilter!==ProfanityFilter.deactivated; + if(this.editRoom.profanityFilter===ProfanityFilter.all){ + this.censorLanguageSpecificCheck=this.censorPartialWordsCheck=true; + }else if(this.profanityCheck){ + this.censorLanguageSpecificCheck=this.editRoom.profanityFilter===ProfanityFilter.languageSpecific; + this.censorPartialWordsCheck=this.editRoom.profanityFilter===ProfanityFilter.partialWords; + } + } + + showMessage(label: string,event: boolean){ + if(event){ + this.translationService.get('room-page.'+label).subscribe(msg=>{ + this.notificationService.show(msg); + }); + } + } + + + /** + * Returns a lambda which closes the dialog on call. + */ + buildCloseDialogActionCallback(): () => void{ + return ()=>this.closeDialog('abort'); + } + + /** + * Returns a lambda which executes the dialog dedicated action on call. + */ + buildSaveActionCallback(): () => void{ + return ()=>this.save(); + } + + closeDialog(type: string): void{ + this.dialogRef.close(type); + } + + save(): void{ + this.editRoom.questionsBlocked=this.check; + this.editRoom.profanityFilter=this.profanityCheck?ProfanityFilter.none:ProfanityFilter.deactivated; + if(this.profanityCheck){ + if(this.censorLanguageSpecificCheck&&this.censorPartialWordsCheck){ + this.editRoom.profanityFilter=ProfanityFilter.all; + }else{ + this.editRoom.profanityFilter=this.censorLanguageSpecificCheck?ProfanityFilter.languageSpecific:ProfanityFilter.none; + this.editRoom.profanityFilter=this.censorPartialWordsCheck?ProfanityFilter.partialWords:this.editRoom.profanityFilter; + } + } + this.closeDialog('update'); + } + +} diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.html b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.html new file mode 100644 index 0000000000000000000000000000000000000000..50b4fdab337336a77344cd04acd6f9525fb3cc0b --- /dev/null +++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.html @@ -0,0 +1,43 @@ +<div mat-dialog-content + *ngIf="editRoom"> + <mat-tab-group> + <mat-tab label="{{'room-page.description' | translate}}"> + <mat-form-field class="input-block"> + <textarea + (focus)="eventService.makeFocusOnInputTrue()" + (blur)="eventService.makeFocusOnInputFalse()" + [(ngModel)]="editRoom.description" + matInput + matTextareaAutosize + matAutosizeMinRows="2" + matAutosizeMaxRows="5" + maxlength="500" + name="description" + aria-labelledby="description" + ></textarea> + <mat-hint align="start"> + <span aria-hidden="true"> + {{ 'room-page.Markdown-hint' | translate }} + </span> + </mat-hint> + <mat-hint align="end"> + <span aria-hidden="true"> + {{ editRoom.description?editRoom.description.length:0 }} / 500 + </span> + </mat-hint> + </mat-form-field> + </mat-tab> + <mat-tab label="{{'session.preview' | translate}}" + [disabled]="!editRoom.description"> + <markdown class="images" katex emoji lineNumbers lineHighlight + [data]="editRoom.description"></markdown> + </mat-tab> + </mat-tab-group> +</div> +<app-dialog-action-buttons + buttonsLabelSection="room-page" + confirmButtonLabel="update" + + [cancelButtonClickAction]="buildCloseDialogActionCallback()" + [confirmButtonClickAction]="buildSaveActionCallback()" +></app-dialog-action-buttons> diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.scss b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.spec.ts b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..32a8c08c6970557863d0d91cb3d0e5be6476bf64 --- /dev/null +++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.spec.ts @@ -0,0 +1,25 @@ +// import { ComponentFixture, TestBed } from '@angular/core/testing'; +// +// import { RoomDescriptionSettingsComponent } from './room-description-settings.component'; +// +// describe('RoomDescriptionSettingsComponent', () => { +// let component: RoomDescriptionSettingsComponent; +// let fixture: ComponentFixture<RoomDescriptionSettingsComponent>; +// +// beforeEach(async () => { +// await TestBed.configureTestingModule({ +// declarations: [ RoomDescriptionSettingsComponent ] +// }) +// .compileComponents(); +// }); +// +// beforeEach(() => { +// fixture = TestBed.createComponent(RoomDescriptionSettingsComponent); +// component = fixture.componentInstance; +// fixture.detectChanges(); +// }); +// +// it('should create', () => { +// expect(component).toBeTruthy(); +// }); +// }); diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd5f3ac74bf44d7f926629a15046dadc5bebdfc1 --- /dev/null +++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts @@ -0,0 +1,57 @@ +import {Component,Inject,OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA,MatDialog,MatDialogRef} from '@angular/material/dialog'; +import {RoomCreatorPageComponent} from '../../room-creator-page/room-creator-page.component'; +import {NotificationService} from '../../../../services/util/notification.service'; +import {TranslateService} from '@ngx-translate/core'; +import {RoomService} from '../../../../services/http/room.service'; +import {Router} from '@angular/router'; +import {EventService} from '../../../../services/util/event.service'; +import {ProfanityFilter,Room} from '../../../../models/room'; +import {FormControl,Validators} from '@angular/forms'; + +@Component({ + selector:'app-room-description-settings', + templateUrl:'./room-description-settings.component.html', + styleUrls:['./room-description-settings.component.scss'] +}) +export class RoomDescriptionSettingsComponent implements OnInit{ + editRoom: Room; + roomNameFormControl=new FormControl('',[Validators.required,Validators.minLength(3),Validators.maxLength(30)]); + + constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>, + public dialog: MatDialog, + public notificationService: NotificationService, + public translationService: TranslateService, + protected roomService: RoomService, + public router: Router, + public eventService: EventService, + @Inject(MAT_DIALOG_DATA) public data: any){ + } + + + ngOnInit(){ + } + + buildCloseDialogActionCallback(): () => void{ + return ()=>this.closeDialog('abort'); + } + + buildSaveActionCallback(): () => void{ + return ()=>this.save(); + } + + closeDialog(type: string): void{ + this.dialogRef.close(type); + } + + save(): void{ + this.roomService.updateRoom(this.editRoom).subscribe(r=>this.editRoom=r); + if(!this.roomNameFormControl.hasError('required') + && !this.roomNameFormControl.hasError('minlength') + && !this.roomNameFormControl.hasError('maxlength')){ + this.closeDialog('update'); + } + this.closeDialog('update'); + } + +} diff --git a/src/app/components/creator/creator.module.ts b/src/app/components/creator/creator.module.ts index 10b0706bd73293cd45e16b584f072917b30750d4..b876aea134afe3d6bebcb146b45e339e0cf7881c 100644 --- a/src/app/components/creator/creator.module.ts +++ b/src/app/components/creator/creator.module.ts @@ -23,6 +23,8 @@ import { DeleteAnswerComponent } from './_dialogs/delete-answer/delete-answer.co import { QuestionWallComponent } from '../shared/questionwall/question-wall/question-wall.component'; import { ArsModule } from '../../../../projects/ars/src/lib/ars.module'; import { MatRippleModule } from '@angular/material/core'; +import { ProfanitySettingsComponent } from './_dialogs/profanity-settings/profanity-settings.component'; +import { RoomDescriptionSettingsComponent } from './_dialogs/room-description-settings/room-description-settings.component'; @NgModule({ imports: [ @@ -56,7 +58,9 @@ import { MatRippleModule } from '@angular/material/core'; DeleteCommentComponent, BonusDeleteComponent, DeleteAnswerComponent, - QuestionWallComponent + QuestionWallComponent, + ProfanitySettingsComponent, + RoomDescriptionSettingsComponent ], exports: [] }) diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.html b/src/app/components/creator/room-creator-page/room-creator-page.component.html index 7e675f2bf840c8bc6796ab6e1e272719ab77674b..f355631fd42e32d88b743044d1631ef8040898e5 100644 --- a/src/app/components/creator/room-creator-page/room-creator-page.component.html +++ b/src/app/components/creator/room-creator-page/room-creator-page.component.html @@ -4,9 +4,7 @@ fxFill> <div fxLayout="row" fxLayoutAlign="center"> - <mat-progress-spinner *ngIf="isLoading" - color="primary" - mode="indeterminate"></mat-progress-spinner> + <app-mat-spinner-overlay *ngIf="isLoading" overlay="true" useCustomCSSColor="true"></app-mat-spinner-overlay> <mat-card *ngIf="room"> <div fxLayout="row"> <span class="corner-icons"></span> @@ -65,15 +63,6 @@ {{ 'room-page.tags' | translate}} </button> </mat-menu> - <button id="settings-menu" - mat-icon-button - class="corner-icons" - [matMenuTriggerFor]="settingsMenu" - aria-labelledby="settings"> - <mat-icon class="corner-icon" - matTooltip="{{ 'room-page.session-settings' | translate}}">settings - </mat-icon> - </button> </div> <mat-card-content *ngIf="room.description" fxLayoutAlign="center"> diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.scss b/src/app/components/creator/room-creator-page/room-creator-page.component.scss index ea240d770244f84396af3a5289a9ba3ee8b6fb7c..f587e7ace435f3b40717f781cd6136a706d0c471 100644 --- a/src/app/components/creator/room-creator-page/room-creator-page.component.scss +++ b/src/app/components/creator/room-creator-page/room-creator-page.component.scss @@ -147,3 +147,7 @@ markdown { background: var(--secondary); color: var(--on-secondary); } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.ts b/src/app/components/creator/room-creator-page/room-creator-page.component.ts index f7e1967f66974f88d4427adfbc602f3130552315..6783a52836206829b173df498b147bf23c107fee 100644 --- a/src/app/components/creator/room-creator-page/room-creator-page.component.ts +++ b/src/app/components/creator/room-creator-page/room-creator-page.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, Renderer2, OnDestroy, AfterContentInit } from '@angular/core'; import { RoomService } from '../../../services/http/room.service'; -import { ActivatedRoute } from '@angular/router'; +import {ActivatedRoute,Router} from '@angular/router'; import { RoomPageComponent } from '../../shared/room-page/room-page.component'; -import { Room } from '../../../models/room'; +import {ProfanityFilter,Room} from '../../../models/room'; import { CommentSettingsDialog } from '../../../models/comment-settings-dialog'; import { Location } from '@angular/common'; import { NotificationService } from '../../../services/util/notification.service'; @@ -27,6 +27,10 @@ import { Export } from '../../../models/export'; import { BonusTokenService } from '../../../services/http/bonus-token.service'; import { TopicCloudFilterComponent } from '../../shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component'; import {HeaderService} from '../../../services/util/header.service'; +import {RoomDeleteComponent} from '../_dialogs/room-delete/room-delete.component'; +import {RoomDeleted} from '../../../models/events/room-deleted'; +import {ProfanitySettingsComponent} from '../_dialogs/profanity-settings/profanity-settings.component'; +import {RoomDescriptionSettingsComponent} from '../_dialogs/room-description-settings/room-description-settings.component'; @Component({ selector: 'app-room-creator-page', @@ -60,7 +64,9 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni public eventService: EventService, public titleService: TitleService, private notificationService: NotificationService, - private bonusTokenService: BonusTokenService) { + private bonusTokenService: BonusTokenService, + public router: Router, + public translationService: TranslateService) { super(roomService, route, location, wsCommentService, commentService, eventService); this.commentCounterEmitSubscription = this.commentCounterEmit.subscribe(e => { this.titleService.attachTitle('(' + e + ')'); @@ -71,35 +77,15 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni initNavigation() { const navigation = {}; const nav = (b, c) => navigation[b] = c; + nav('deleteRoom',()=>this.openDeleteRoomDialog()); + nav('profanityFilter',()=>this.toggleProfanityFilter()); + nav('editSessionDescription',()=>this.editSessionDescription()); nav('roomBonusToken', () => this.showBonusTokenDialog()); nav('moderator', () => this.showModeratorsDialog()); nav('tags', () => this.showTagsDialog()); nav('topicCloud', () => this.showTagCloud()); - nav('exportQuestions', () => { - const exp: Export = new Export( - this.room, - this.commentService, - this.bonusTokenService, - this.translateService, - 'comment-list', - this.notificationService); - exp.exportAsCsv(); - }); - nav('deleteQuestions', () => { - const dialogRef = this.dialog.open(DeleteCommentsComponent, { - width: '400px' - }); - dialogRef.componentInstance.roomId = this.room.id; - dialogRef.afterClosed() - .subscribe(result => { - if (result === 'delete') { - this.translateService.get('room-page.comments-deleted').subscribe(msg => { - this.notificationService.show(msg); - }); - this.commentService.deleteCommentsByRoomId(this.room.id).subscribe(); - } - }); - }); + nav('exportQuestions', () => this.exportQuestions()); + nav('deleteQuestions', () => this.deleteQuestions()); this.headerInterface = this.eventService.on<string>('navigate').subscribe(e => { if (navigation.hasOwnProperty(e)) { navigation[e](); @@ -107,6 +93,47 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni }); } + toggleProfanityFilter(){ + const dialogRef = this.dialog.open(ProfanitySettingsComponent, { + width: '400px' + }); + dialogRef.componentInstance.editRoom=this.room; + } + + editSessionDescription(){ + const dialogRef = this.dialog.open(RoomDescriptionSettingsComponent, { + width: '400px' + }); + dialogRef.componentInstance.editRoom=this.room; + } + + exportQuestions(){ + const exp: Export = new Export( + this.room, + this.commentService, + this.bonusTokenService, + this.translateService, + 'comment-list', + this.notificationService); + exp.exportAsCsv(); + } + + deleteQuestions(){ + const dialogRef = this.dialog.open(DeleteCommentsComponent, { + width: '400px' + }); + dialogRef.componentInstance.roomId = this.room.id; + dialogRef.afterClosed() + .subscribe(result => { + if (result === 'delete') { + this.translateService.get('room-page.comments-deleted').subscribe(msg => { + this.notificationService.show(msg); + }); + this.commentService.deleteCommentsByRoomId(this.room.id).subscribe(); + } + }); + } + ngOnDestroy() { super.ngOnDestroy(); this.commentCounterEmitSubscription.unsubscribe(); @@ -307,6 +334,30 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni }); } + openDeleteRoomDialog(): void { + const dialogRef = this.dialog.open(RoomDeleteComponent, { + width: '400px' + }); + dialogRef.componentInstance.room = this.room; + dialogRef.afterClosed() + .subscribe(result => { + if (result === 'delete') { + this.deleteRoom(); + } + }); + } + + deleteRoom(): void { + this.translationService.get('room-page.deleted').subscribe(msg => { + this.notificationService.show(this.room.name + msg); + }); + this.roomService.deleteRoom(this.room.id).subscribe(result => { + const event = new RoomDeleted(this.room.id); + this.eventService.broadcast(event.type, event.payload); + this.location.back(); + }); + } + copyShortId(): void { const selBox = document.createElement('textarea'); selBox.style.position = 'fixed'; diff --git a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html index 46f1e6eee87182ff5de9e83a9e0184291184f040..5327030937e706f682964b34a53b6c608988d7c9 100644 --- a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html +++ b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html @@ -4,8 +4,7 @@ fxFill> <div fxLayout="row" fxLayoutAlign="center"> - <mat-progress-spinner *ngIf="isLoading" - mode="indeterminate"></mat-progress-spinner> + <app-mat-spinner-overlay *ngIf="isLoading" overlay="true" useCustomCSSColor="true"></app-mat-spinner-overlay> <mat-card *ngIf="room"> <div fxLayout="row"> <span class="fill-remaining-space"></span> diff --git a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.scss b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.scss index a6ed51d24b38c06010c775f436d1c015ff11b6d3..9729f8db64969c1702d901e5806e1002e9a5974c 100644 --- a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.scss +++ b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.scss @@ -5,7 +5,7 @@ mat-card { max-width: 800px; min-height: 350px; max-height: 700px; - background-color: var(--surface)!important; + background-color: var(--surface) !important; } mat-card-content > :first-child { @@ -19,8 +19,9 @@ mat-card-content > :first-child { .mat-icon-button { width: 60%; // 100% height: 75%; - color: var(--primary)!important; + color: var(--primary) !important; transition: all 0.3s; + &:hover { transform: scale(1.2) } @@ -51,24 +52,24 @@ mat-card-content > :first-child { line-height: 100%!important; }*/ -.main-icon{ +.main-icon { font-size: 80px; height: 80px; width: 80px; - line-height: 100%!important; + line-height: 100% !important; } .smallerIcon { font-size: 55px; height: 55px; width: 55px; - line-height: 100%!important; + line-height: 100% !important; } .room-short-id { font-size: larger; font-weight: bold; - color: var(--on-surface)!important; + color: var(--on-surface) !important; margin: 5% 5% 0 0; } @@ -81,33 +82,33 @@ mat-grid-list { } h1 { - font-size: large; - color: var(--on-surface)!important; - } + font-size: large; + color: var(--on-surface) !important; +} p { - color: var(--on-surface)!important; + color: var(--on-surface) !important; } h2 { font-size: larger; - color: var(--on-surface)!important; + color: var(--on-surface) !important; } mat-card-header { min-height: 80px; - height: 10%!important; + height: 10% !important; } mat-card-title { height: 40%; min-width: 200px; - color: var(--on-surface)!important; + color: var(--on-surface) !important; } mat-card-subtitle { height: 30%; - color: var(--on-surface)!important; + color: var(--on-surface) !important; } mat-grid-tile { @@ -116,7 +117,7 @@ mat-grid-tile { } mat-expansion-panel { - background-color: var(--surface)!important; + background-color: var(--surface) !important; min-width: 200px; hyphens: auto; } @@ -150,3 +151,7 @@ markdown { color: var(--on-surface); margin: 0 3% 0 3% !important; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/participant/room-participant-page/room-participant-page.component.html b/src/app/components/participant/room-participant-page/room-participant-page.component.html index 67ffe857d86fed3c7fd90d05cdc5c0014126a9f1..e67dc575840ca736ce55c150f7131ba890979152 100644 --- a/src/app/components/participant/room-participant-page/room-participant-page.component.html +++ b/src/app/components/participant/room-participant-page/room-participant-page.component.html @@ -1,6 +1,6 @@ <div fxLayout="column" fxLayoutAlign="center" fxLayoutGap="20px" fxFill> <div fxLayout="row" fxLayoutAlign="center"> - <mat-progress-spinner *ngIf="isLoading" mode="indeterminate"></mat-progress-spinner> + <app-mat-spinner-overlay *ngIf="isLoading" overlay="true" useCustomCSSColor="true"></app-mat-spinner-overlay> <mat-card *ngIf="room"> <div fxLayout="row"> <span class="fill-remaining-space"></span> diff --git a/src/app/components/participant/room-participant-page/room-participant-page.component.scss b/src/app/components/participant/room-participant-page/room-participant-page.component.scss index 7e01c67a31b97b8b080a781255ad5f7f3c358705..29022f84107fce57d11d2a804642158d859d5b0a 100644 --- a/src/app/components/participant/room-participant-page/room-participant-page.component.scss +++ b/src/app/components/participant/room-participant-page/room-participant-page.component.scss @@ -4,10 +4,10 @@ mat-card { width: 100%; max-width: 800px; min-height: 350px; - background-color: var(--surface)!important; + background-color: var(--surface) !important; } -mat-card-content>:first-child { +mat-card-content > :first-child { margin-top: 5%; } @@ -16,14 +16,14 @@ mat-card-content>:first-child { height: 75%; margin-bottom: 3%; border-radius: 0; - color: var(--primary)!important; + color: var(--primary) !important; } .main-icon { font-size: 80px; height: 80px; width: 80px; - line-height: 100%!important; + line-height: 100% !important; } .desktop { @@ -42,30 +42,29 @@ button { } - h3 { margin: 5% 0 5% 0; - color: var(--on-surface)!important; + color: var(--on-surface) !important; } mat-card-header { - min-height: 80px!important; - height: 12%!important; + min-height: 80px !important; + height: 12% !important; } mat-card-title { height: 40%; min-width: 200px; - color: var(--on-surface)!important; + color: var(--on-surface) !important; } mat-card-subtitle { height: 20%; - color: var(-on--surface)!important; + color: var(-on--surface) !important; } mat-expansion-panel { - background-color: var(--surface)!important; + background-color: var(--surface) !important; min-width: 200px; hyphens: auto; } @@ -104,3 +103,7 @@ markdown { color: var(--on-surface); margin: 0 3% 0 3% !important; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/_dialogs/cloud-configuration/cloud-configuration.component.html b/src/app/components/shared/_dialogs/cloud-configuration/cloud-configuration.component.html index 67f579cc608c0f01ed2e0474cbd4232cd4b40f6b..af6b37c72506322ee8dfb1f746cef4dc72150cc5 100644 --- a/src/app/components/shared/_dialogs/cloud-configuration/cloud-configuration.component.html +++ b/src/app/components/shared/_dialogs/cloud-configuration/cloud-configuration.component.html @@ -4,7 +4,8 @@ <div class="input-row" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> <mat-slide-toggle fxFlex (change)="parent.dataManager.demoActive = !parent.dataManager.demoActive" [checked]="parent.dataManager.demoActive" - [ngModelOptions]="{standalone: true}">Demo Cloud</mat-slide-toggle> + [ngModelOptions]="{standalone: true}">Demo Cloud + </mat-slide-toggle> </div> </div> <br> @@ -16,31 +17,53 @@ </mat-panel-title> </mat-expansion-panel-header> <div class="input-row firstElementOfExpansionPanel" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> - <mat-slide-toggle matTooltip="{{'tag-cloud-config.random-angle-tooltip' | translate}}" (change)="valueChanged()" fxFlex [(ngModel)]="cloudParameters.randomAngles" - [ngModelOptions]="{standalone: true}">{{'tag-cloud-config.random-angle' | translate}}</mat-slide-toggle> - <mat-icon matTooltip="{{'tag-cloud-config.random-angle-note' | translate}}">help</mat-icon> + <mat-slide-toggle matTooltip="{{'tag-cloud-config.random-angle-tooltip' | translate}}" + (change)="valueChanged()" fxFlex [(ngModel)]="cloudParameters.randomAngles" + [ngModelOptions]="{standalone: true}">{{'tag-cloud-config.random-angle' | translate}}</mat-slide-toggle> + <mat-icon matTooltip="{{'tag-cloud-config.random-angle-note' | translate}}">help</mat-icon> </div> - <div class="input-row special-settings automatic-spelling" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> - <mat-radio-group matTooltip="{{'tag-cloud-config.notation-tooltip' | translate}}" aria-label="Notation:"> {{'tag-cloud-config.notation' | translate}} - <div><mat-radio-button value="1" (change)="textStyleChanged(1)" [checked]="cloudParameters.textTransform == 1">{{'tag-cloud-config.lowerCase' | translate}}</mat-radio-button> </div> - <div><mat-radio-button value="2" (change)="textStyleChanged(3)" [checked]="cloudParameters.textTransform == 3">{{'tag-cloud-config.upperCase' | translate}}</mat-radio-button> </div> - <div><mat-radio-button value="2" (change)="textStyleChanged(2)" [checked]="cloudParameters.textTransform == 2">{{'tag-cloud-config.capitalization' | translate}}</mat-radio-button> </div> - <div><mat-radio-button value="0" (change)="textStyleChanged(0)" [checked]="cloudParameters.textTransform == 0">{{'tag-cloud-config.standard' | translate}}</mat-radio-button> </div> - </mat-radio-group> - </div> - <div class="input-row special-settings alphabetical-sorting" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> - <div class="input-row" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> - <mat-slide-toggle matTooltip="{{'tag-cloud-config.alphabetical-sorting-tooltip' | translate}}" [(ngModel)]="cloudParameters.sortAlphabetically" [checked]="cloudParameters.sortAlphabetically" [ngModelOptions]="{standalone: true}"(change)="valueChanged()">{{'tag-cloud-config.alphabetical-sorting' | translate}}</mat-slide-toggle> + <div class="input-row special-settings automatic-spelling" fxLayout="row" fxLayoutGap="5px" + fxLayout.xs="column"> + <mat-radio-group matTooltip="{{'tag-cloud-config.notation-tooltip' | translate}}" + aria-label="Notation:"> {{'tag-cloud-config.notation' | translate}} + <div> + <mat-radio-button value="1" (change)="textStyleChanged(1)" + [checked]="cloudParameters.textTransform == 1">{{'tag-cloud-config.lowerCase' | translate}}</mat-radio-button> + </div> + <div> + <mat-radio-button value="2" (change)="textStyleChanged(3)" + [checked]="cloudParameters.textTransform == 3">{{'tag-cloud-config.upperCase' | translate}}</mat-radio-button> + </div> + <div> + <mat-radio-button value="2" (change)="textStyleChanged(2)" + [checked]="cloudParameters.textTransform == 2">{{'tag-cloud-config.capitalization' | translate}}</mat-radio-button> </div> + <div> + <mat-radio-button value="0" (change)="textStyleChanged(0)" + [checked]="cloudParameters.textTransform == 0">{{'tag-cloud-config.standard' | translate}}</mat-radio-button> + </div> + </mat-radio-group> + </div> + <div class="input-row special-settings alphabetical-sorting" fxLayout="row" fxLayoutGap="5px" + fxLayout.xs="column"> + <div class="input-row" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> + <mat-slide-toggle matTooltip="{{'tag-cloud-config.alphabetical-sorting-tooltip' | translate}}" + [(ngModel)]="cloudParameters.sortAlphabetically" + [checked]="cloudParameters.sortAlphabetically" [ngModelOptions]="{standalone: true}" + (change)="valueChanged()">{{'tag-cloud-config.alphabetical-sorting' | translate}}</mat-slide-toggle> </div> + </div> <div style="margin: 10px;"></div> <div class="input-row" fxLayout="column" fxLayoutGap="5px"> <div class="input-row" fxLayout="column" fxLayoutGap="5px"> <div fxLayout="row" fxLayoutGap="5px"> <mat-form-field fxFlex="100%"> <mat-label>{{'tag-cloud-config.background' | translate}}</mat-label> - <input matInput [value]="cloudParameters.backgroundColor" [colorPicker]="cloudParameters.backgroundColor" - (colorPickerChange)="backgroundColorChanged($event)" class="custom-color-picker" /> + <input matInput [value]="cloudParameters.backgroundColor" + [colorPicker]="cloudParameters.backgroundColor" + (colorPickerChange)="backgroundColorChanged($event)" + class="custom-color-picker" + [cpPosition]="'left'"/> <p matTooltip="{{'tag-cloud-config.background-tooltip' | translate}}" class="custom-color-picker-text"> {{'tag-cloud-config.select-color' | translate}}</p> </mat-form-field> @@ -51,12 +74,16 @@ <div class="input-row" fxLayout="column" fxLayoutGap="5px"> <mat-label class="label-text">{{'tag-cloud-config.word-delay' | translate}}</mat-label> <mat-slider #delaySlider min="0" max="1000" step="50" [(ngModel)]="cloudParameters.delayWord" - [ngModelOptions]="{standalone: true}" (change)="valueChanged()" [thumbLabel]="true" - [value]="cloudParameters.delayWord" matTooltip="{{'tag-cloud-config.word-delay-tooltip' | translate}}"> + [ngModelOptions]="{standalone: true}" (change)="valueChanged()" [thumbLabel]="true" + [value]="cloudParameters.delayWord" + matTooltip="{{'tag-cloud-config.word-delay-tooltip' | translate}}"> </mat-slider> </div> <mat-action-row> - <button mat-icon-button (click)="nextStep()"><mat-icon>expand_more</mat-icon></button> </mat-action-row> + <button mat-icon-button (click)="nextStep()"> + <mat-icon>expand_more</mat-icon> + </button> + </mat-action-row> </mat-expansion-panel> <mat-expansion-panel [expanded]="step == 1" (opened)="setStep(1)" class="matExpansionPanel"> <mat-expansion-panel-header> @@ -67,7 +94,9 @@ <div class="input-row" fxLayout="column" fxLayoutGap="5px"> <mat-form-field appearance="fill"> <mat-label>{{'tag-cloud-config.font-family' | translate}}</mat-label> - <mat-select (selectionChange)="valueChanged()" matTooltip="{{'tag-cloud-config.font-family-tooltip' | translate}}" [(ngModel)]="cloudParameters.fontFamily"> + <mat-select (selectionChange)="valueChanged()" + matTooltip="{{'tag-cloud-config.font-family-tooltip' | translate}}" + [(ngModel)]="cloudParameters.fontFamily"> <mat-option value="sans-serif">Normal</mat-option> <mat-option value="Abril Fatface">Abril Fatface</mat-option> <mat-option value="Dancing Script">Dancing Script</mat-option> @@ -76,134 +105,176 @@ </mat-select> </mat-form-field> </div> - <div class="input-row special-settings automatic-spelling" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> + <div class="input-row special-settings automatic-spelling" fxLayout="row" fxLayoutGap="5px" + fxLayout.xs="column"> <mat-radio-group matTooltip="{{'tag-cloud-config.bold-notation-tooltip' | translate}}" aria-label="Notation:"> - <div><mat-slide-toggle [checked]="checkBold()" (change)="boldChecked($event)" [ngModelOptions]="{standalone: true}">{{'tag-cloud-config.font-style-bold' | translate}}</mat-slide-toggle> </div> + <div> + <mat-slide-toggle [checked]="checkBold()" (change)="boldChecked($event)" + [ngModelOptions]="{standalone: true}">{{'tag-cloud-config.font-style-bold' | translate}}</mat-slide-toggle> + </div> </mat-radio-group> </div> <div class="input-row" fxLayout="column" fxLayoutGap="5px"> <mat-form-field fxFlex fxLayout.xs="column"> <mat-label>{{'tag-cloud-config.font-size-min' | translate}}</mat-label> <input #minFont [value]="cloudParameters.fontSizeMin.toString()" matInput type="number" - [(ngModel)]="cloudParameters.fontSizeMin" [ngModelOptions]="{standalone: true}" (change)="calcMaxFont($event,true)" - min="50" max="300" step="10" matTooltip="{{'tag-cloud-config.font-size-min-tooltip' | translate}}" /> + [(ngModel)]="cloudParameters.fontSizeMin" [ngModelOptions]="{standalone: true}" + (change)="calcMaxFont($event,true)" + min="50" max="300" step="10" matTooltip="{{'tag-cloud-config.font-size-min-tooltip' | translate}}"/> </mat-form-field> </div> <div class="input-row" fxLayout="column" fxLayoutGap="5px"> <mat-form-field fxFlex fxLayout.xs="column"> <mat-label>{{'tag-cloud-config.font-size-max' | translate}}</mat-label> <input #maxFont matInput type="number" [(ngModel)]="MaxFont" [value]="MaxFont.toString()" - [ngModelOptions]="{standalone: true}" (change)="calcMaxFont($event,false)" min="1" max="10" step="1" - matTooltip="{{'tag-cloud-config.font-size-max-tooltip' | translate}}" /> + [ngModelOptions]="{standalone: true}" (change)="calcMaxFont($event,false)" min="1" max="10" step="1" + matTooltip="{{'tag-cloud-config.font-size-max-tooltip' | translate}}"/> </mat-form-field> </div> <mat-action-row> - <button mat-icon-button (click)="prevStep()"><mat-icon>expand_less</mat-icon></button> - <button mat-icon-button (click)="nextStep()"><mat-icon>expand_more</mat-icon></button> + <button mat-icon-button (click)="prevStep()"> + <mat-icon>expand_less</mat-icon> + </button> + <button mat-icon-button (click)="nextStep()"> + <mat-icon>expand_more</mat-icon> + </button> </mat-action-row> </mat-expansion-panel> - <mat-expansion-panel [expanded]="step == 2" (opened)="setStep(2)" class="matExpansionPanel"> - <mat-expansion-panel-header> - <mat-panel-title> - <label class=" expansion-title settings-heading">{{'tag-cloud-config.hover-title' | translate}}</label> - </mat-panel-title> - </mat-expansion-panel-header> - <div> - <div class="input-row firstElementOfExpansionPanel" fxLayout="column" fxLayoutGap="5px"> - <div fxLayout="row" fxLayoutGap="5px"> - <mat-form-field fxFlex="100%"> - <mat-label>{{'tag-cloud-config.hover-color' | translate}}</mat-label> - <input matInput [value]="cloudParameters.fontColor" [colorPicker]="cloudParameters.fontColor" - (colorPickerChange)="fontColorChanged($event)" class="custom-color-picker" /> - <p class="custom-color-picker-text" matTooltip="{{'tag-cloud-config.select-color-tooltip' | translate}}"> - {{'tag-cloud-config.select-color' | translate}}</p> - </mat-form-field> - <div fxFlex="35px" class="color-box" [style.background]="cloudParameters.fontColor"></div> - </div> - </div> - <div class="input-row" fxLayout="column" fxLayoutGap="5px"> - <mat-label class="label-text">{{'tag-cloud-config.hover-scale' | translate}}</mat-label> - <mat-slider #hoverScaleSlider [value]="cloudParameters.hoverScale" min="1" max="10" step="0.2" - [(ngModel)]="cloudParameters.hoverScale" [ngModelOptions]="{standalone: true}" (change)="valueChanged()" - [thumbLabel]="true" matTooltip="{{'tag-cloud-config.hover-scale-tooltip' | translate}}"></mat-slider> - </div> - <div class="input-row" fxLayout="column" fxLayoutGap="5px"> - <mat-label class="label-text">{{'tag-cloud-config.hover-time' | translate}}</mat-label> - <mat-slider #transitonSlider [value]="cloudParameters.hoverTime" min="0" max="2" step="0.2" - [(ngModel)]="cloudParameters.hoverTime" [ngModelOptions]="{standalone: true}" (change)="valueChanged()" - [thumbLabel]="true" matTooltip="{{'tag-cloud-config.hover-time-tooltip' | translate}}"></mat-slider> - </div> - <div class="input-row" fxLayout="column" fxLayoutGap="5px"> - <mat-label class="label-text">{{'tag-cloud-config.hover-delay' | translate}}</mat-label> - <mat-slider #hoverDelaySlider [value]="cloudParameters.hoverDelay" min="0" max="2" step="0.1" - [(ngModel)]="cloudParameters.hoverDelay" [ngModelOptions]="{standalone: true}" (change)="valueChanged()" - [thumbLabel]="true" matTooltip="{{'tag-cloud-config.hover-delay-tooltip' | translate}}"></mat-slider> + <mat-expansion-panel [expanded]="step == 2" (opened)="setStep(2)" class="matExpansionPanel"> + <mat-expansion-panel-header> + <mat-panel-title> + <label class=" expansion-title settings-heading">{{'tag-cloud-config.hover-title' | translate}}</label> + </mat-panel-title> + </mat-expansion-panel-header> + <div> + <div class="input-row firstElementOfExpansionPanel" fxLayout="column" fxLayoutGap="5px"> + <div fxLayout="row" fxLayoutGap="5px"> + <mat-form-field fxFlex="100%"> + <mat-label>{{'tag-cloud-config.hover-color' | translate}}</mat-label> + <input matInput [value]="cloudParameters.fontColor" + [colorPicker]="cloudParameters.fontColor" + (colorPickerChange)="fontColorChanged($event)" + class="custom-color-picker" + [cpPosition]="'left'"/> + <p class="custom-color-picker-text" + matTooltip="{{'tag-cloud-config.select-color-tooltip' | translate}}"> + {{'tag-cloud-config.select-color' | translate}}</p> + </mat-form-field> + <div fxFlex="35px" class="color-box" [style.background]="cloudParameters.fontColor"></div> </div> </div> - <mat-action-row> - <button mat-icon-button (click)="prevStep()"><mat-icon>expand_less</mat-icon></button> - <button mat-icon-button (click)="nextStep()"><mat-icon>expand_more</mat-icon></button> - </mat-action-row> + <div class="input-row" fxLayout="column" fxLayoutGap="5px"> + <mat-label class="label-text">{{'tag-cloud-config.hover-scale' | translate}}</mat-label> + <mat-slider #hoverScaleSlider [value]="cloudParameters.hoverScale" min="1" max="10" step="0.2" + [(ngModel)]="cloudParameters.hoverScale" [ngModelOptions]="{standalone: true}" + (change)="valueChanged()" + [thumbLabel]="true" + matTooltip="{{'tag-cloud-config.hover-scale-tooltip' | translate}}"></mat-slider> + </div> + <div class="input-row" fxLayout="column" fxLayoutGap="5px"> + <mat-label class="label-text">{{'tag-cloud-config.hover-time' | translate}}</mat-label> + <mat-slider #transitonSlider [value]="cloudParameters.hoverTime" min="0" max="2" step="0.2" + [(ngModel)]="cloudParameters.hoverTime" [ngModelOptions]="{standalone: true}" + (change)="valueChanged()" + [thumbLabel]="true" + matTooltip="{{'tag-cloud-config.hover-time-tooltip' | translate}}"></mat-slider> + </div> + <div class="input-row" fxLayout="column" fxLayoutGap="5px"> + <mat-label class="label-text">{{'tag-cloud-config.hover-delay' | translate}}</mat-label> + <mat-slider #hoverDelaySlider [value]="cloudParameters.hoverDelay" min="0" max="2" step="0.1" + [(ngModel)]="cloudParameters.hoverDelay" [ngModelOptions]="{standalone: true}" + (change)="valueChanged()" + [thumbLabel]="true" + matTooltip="{{'tag-cloud-config.hover-delay-tooltip' | translate}}"></mat-slider> + </div> + </div> + <mat-action-row> + <button mat-icon-button (click)="prevStep()"> + <mat-icon>expand_less</mat-icon> + </button> + <button mat-icon-button (click)="nextStep()"> + <mat-icon>expand_more</mat-icon> + </button> + </mat-action-row> </mat-expansion-panel> <mat-expansion-panel [expanded]="step == 3" (opened)="setStep(3)" class="matExpansionPanel"> <mat-expansion-panel-header> <mat-panel-title> - <label class=" expansion-title settings-heading">{{'tag-cloud-config.weight-class-settings' | translate}}</label> + <label + class=" expansion-title settings-heading">{{'tag-cloud-config.weight-class-settings' | translate}}</label> </mat-panel-title> </mat-expansion-panel-header> <div class="input-row" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column"> - <div class="cloud-configuration-form" fxLayout="column"> - <div *ngFor="let weightClass of weightClasses" class="weight-class-setting"> - <div class ="weight-class-setting-content"> - <label class=" expansion-title weight-class-heading">{{'tag-cloud-config.weight-class' | translate}} {{weightClasses.indexOf(weightClass) + 1}}</label> - <div class="input-row" fxLayout="column" fxLayoutGap="5px"> - <div fxLayout="row" fxLayoutGap="5px"> - <mat-form-field fxFlex="100%"> - <mat-label>{{'tag-cloud-config.weight-color' | translate}}</mat-label> - <input matInput [value]="weightClass.tagColor" [colorPicker]="weightClass.tagColor" - (colorPickerChange)="weightColorChanged(weightClasses.indexOf(weightClass), $event)" class="custom-color-picker" /> - <p matTooltip="{{'tag-cloud-config.weight-color-tooltip' | translate}}" class="custom-color-picker-text"> - {{'tag-cloud-config.select-color' | translate}}</p> - </mat-form-field> - <div fxFlex="35px" class="color-box" [style.background]="weightClass.tagColor"></div> + <div class="cloud-configuration-form" fxLayout="column"> + <div *ngFor="let weightClass of weightClasses" class="weight-class-setting"> + <div class="weight-class-setting-content"> + <label + class=" expansion-title weight-class-heading">{{'tag-cloud-config.weight-class' | translate}} {{weightClasses.indexOf(weightClass) + 1}}</label> + <div class="input-row" fxLayout="column" fxLayoutGap="5px"> + <div fxLayout="row" fxLayoutGap="5px"> + <mat-form-field fxFlex="100%"> + <mat-label>{{'tag-cloud-config.weight-color' | translate}}</mat-label> + <input matInput [value]="weightClass.tagColor" [colorPicker]="weightClass.tagColor" + (colorPickerChange)="weightColorChanged(weightClasses.indexOf(weightClass), $event)" + class="custom-color-picker" + [cpPosition]="'left'"/> + <p matTooltip="{{'tag-cloud-config.weight-color-tooltip' | translate}}" + class="custom-color-picker-text"> + {{'tag-cloud-config.select-color' | translate}}</p> + </mat-form-field> + <div fxFlex="35px" class="color-box" [style.background]="weightClass.tagColor"></div> + </div> </div> - </div> - <div class="input-row firstElementOfWeightClass" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column" *ngIf="weightClass.actualTagNumber > 0 && !parent.dataManager.demoActive"> - <mat-slide-toggle matTooltip="{{'tag-cloud-config.manual-weight-number-tooltip' | translate}}" (change)="valueChanged()" fxFlex [(ngModel)]=" weightClass.allowManualTagNumber" - [ngModelOptions]="{standalone: true}">{{'tag-cloud-config.manual-weight-number' | translate}}</mat-slide-toggle> + <div class="input-row firstElementOfWeightClass" fxLayout="row" fxLayoutGap="5px" fxLayout.xs="column" + *ngIf="weightClass.actualTagNumber > 0 && !parent.dataManager.demoActive"> + <mat-slide-toggle matTooltip="{{'tag-cloud-config.manual-weight-number-tooltip' | translate}}" + (change)="valueChanged()" fxFlex [(ngModel)]=" weightClass.allowManualTagNumber" + [ngModelOptions]="{standalone: true}">{{'tag-cloud-config.manual-weight-number' | translate}}</mat-slide-toggle> <mat-icon matTooltip="{{'tag-cloud-config.manual-weight-number-note' | translate}}">help</mat-icon> - </div> - <div class="input-row" fxLayout="column" fxLayoutGap="5px" *ngIf="weightClass.actualTagNumber > 0 && !parent.dataManager.demoActive && weightClass.allowManualTagNumber"> - <div class="input-row" fxLayout="column" fxLayoutGap="5px"> - <mat-label class="label-text" >{{'tag-cloud-config.weight-number' | translate}}</mat-label> - <mat-slider [value]="weightClass.maxTagNumber" min="1" [max]="weightClass.actualTagNumber" step="1" - [(ngModel)]="weightClass.maxTagNumber" [ngModelOptions]="{standalone: true}" (change)="valueChanged()" - [thumbLabel]="true" matTooltip="{{'tag-cloud-config.weight-number-tooltip' | translate}}"></mat-slider> - </div> - </div> - <div class="input-row" fxLayout="column" fxLayoutGap="5px" *ngIf="!cloudParameters.randomAngles"> - <mat-label class="label-text">{{'tag-cloud-config.rotate-weight' | translate}}</mat-label> - <mat-slider [value]="weightClass.rotationAngle" min="-180" max="180" step="1" - [(ngModel)]="weightClass.rotationAngle" [ngModelOptions]="{standalone: true}" (change)="valueChanged()" - [thumbLabel]="true" matTooltip="{{'tag-cloud-config.rotate-weight-tooltip' | translate}}"></mat-slider> + </div> + <div class="input-row" fxLayout="column" fxLayoutGap="5px" + *ngIf="weightClass.actualTagNumber > 0 && !parent.dataManager.demoActive && weightClass.allowManualTagNumber"> + <div class="input-row" fxLayout="column" fxLayoutGap="5px"> + <mat-label class="label-text">{{'tag-cloud-config.weight-number' | translate}}</mat-label> + <mat-slider [value]="weightClass.maxTagNumber" min="1" [max]="weightClass.actualTagNumber" step="1" + [(ngModel)]="weightClass.maxTagNumber" [ngModelOptions]="{standalone: true}" + (change)="valueChanged()" + [thumbLabel]="true" + matTooltip="{{'tag-cloud-config.weight-number-tooltip' | translate}}"></mat-slider> + </div> + </div> + <div class="input-row" fxLayout="column" fxLayoutGap="5px" *ngIf="!cloudParameters.randomAngles"> + <mat-label class="label-text">{{'tag-cloud-config.rotate-weight' | translate}}</mat-label> + <mat-slider [value]="weightClass.rotationAngle" min="-180" max="180" step="1" + [(ngModel)]="weightClass.rotationAngle" [ngModelOptions]="{standalone: true}" + (change)="valueChanged()" + [thumbLabel]="true" + matTooltip="{{'tag-cloud-config.rotate-weight-tooltip' | translate}}"></mat-slider> + </div> </div> </div> </div> </div> - </div> <mat-action-row> - <button mat-icon-button (click)="prevStep()"><mat-icon>expand_less</mat-icon></button> - <button class="close-btn" mat-icon-button (click)="nextStep()"><mat-icon>close</mat-icon></button> + <button mat-icon-button (click)="prevStep()"> + <mat-icon>expand_less</mat-icon> + </button> + <button class="close-btn" mat-icon-button (click)="nextStep()"> + <mat-icon>close</mat-icon> + </button> </mat-action-row> </mat-expansion-panel> </mat-accordion> <br> <div class="button-row"> - <button (click)="reset()" mat-button class="reset tag-config-button" >{{'tag-cloud-config.reset-btn' | translate}}</button> + <button (click)="reset()" mat-button + class="reset tag-config-button">{{'tag-cloud-config.reset-btn' | translate}}</button> </div> <div class="button-row save-or-cancel"> - <button (click)="cancel()" mat-button class="secondary tag-config-button">{{'tag-cloud-config.cancel-btn' | translate}}</button> - <button (click)="save()" mat-button class="primary tag-config-button">{{'tag-cloud-config.save-btn' | translate}}</button> + <button (click)="cancel()" mat-button + class="secondary tag-config-button">{{'tag-cloud-config.cancel-btn' | translate}}</button> + <button (click)="save()" mat-button + class="primary tag-config-button">{{'tag-cloud-config.save-btn' | translate}}</button> </div> </div> </div> diff --git a/src/app/components/shared/_dialogs/create-comment/create-comment.component.html b/src/app/components/shared/_dialogs/create-comment/create-comment.component.html index 9665db287649fe9286b180d4e26347d4de569709..aeb369475c8246c8b0e2029073ea3a6b20eeec3f 100644 --- a/src/app/components/shared/_dialogs/create-comment/create-comment.component.html +++ b/src/app/components/shared/_dialogs/create-comment/create-comment.component.html @@ -124,8 +124,11 @@ (click)="grammarChecker.grammarCheck(commentBody)"> {{ 'comment-page.grammar-check' | translate}} <mat-icon *ngIf="grammarChecker.isSpellchecking" - style="margin: 0;"> - <mat-spinner diameter="20"></mat-spinner> + class="spinner-container"> + <app-mat-spinner-overlay diameter="20" + strokeWidth="2" + [useCustomCSSColor]="true"> + </app-mat-spinner-overlay> </mat-icon> </button> </ars-col> diff --git a/src/app/components/shared/_dialogs/create-comment/create-comment.component.scss b/src/app/components/shared/_dialogs/create-comment/create-comment.component.scss index 49db67e66622737f4548f9083baed326d50c9fe4..4882ec336d862bc588af06371f91514691af7347 100644 --- a/src/app/components/shared/_dialogs/create-comment/create-comment.component.scss +++ b/src/app/components/shared/_dialogs/create-comment/create-comment.component.scss @@ -134,10 +134,6 @@ mat-hint { overflow-x: hidden !important; } -::ng-deep .mat-spinner circle { - stroke: var(--on-primary); -} - .lang-confidence { color: var(--on-cancel); background-color: var(--cancel); @@ -200,6 +196,12 @@ mat-hint { display: none; } +.spinner-container { + font-size: 14px; + margin-right: 7px; + margin-top: -2px; +} + /* Suggestion classes from Languagetool */ diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html index cf04bef1a22cb1d9be4f35206be3f1cc4a872aaa..627a3b4fc074e4df20eccc12bbae1e46a25bcd5b 100644 --- a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html @@ -24,7 +24,7 @@ </span> <ars-row class="list-container"> <div fxLayout="row" fxLayoutAlign="center center" fxFill> - <mat-progress-spinner *ngIf="isLoading" mode="indeterminate"></mat-progress-spinner> + <app-mat-spinner-overlay *ngIf="isLoading" useCustomCSSColor="true"></app-mat-spinner-overlay> </div> <mat-list dense class="keywords-list"> <mat-list-item *ngFor="let keyword of keywords; let odd = odd; let even = even; let i = index" diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss index 81cd32b18d2a08e7bdd29411015eb614f8b12d03..8777cc69a22994426afdb48325b7ad0d948e6379 100644 --- a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss @@ -2,6 +2,7 @@ font-size: 13px; height: 40px !important; } + .keywords-list { max-height: 340px; flex-grow: 1; @@ -9,11 +10,13 @@ overflow: auto; padding-top: 0 !important; } + .first-keyword { border-top: 1px solid var(--surface); box-sizing: border-box; } -.keywords-even, .keywords-alternate { + +.keywords-even, .keywords-alternate { background-color: var(--dialog); border-bottom: 1px solid var(--surface); border-top-left-radius: 5px; @@ -22,33 +25,41 @@ border-right: 1px solid var(--primary); box-sizing: border-box; } + .keyword-selected { background: var(--surface); box-shadow: inset -2px 0 0 1px var(--primary); } + .keyword-span { color: var(--on-surface) !important; opacity: 1 !important; } + ::ng-deep .mat-checkbox-checked .mat-checkbox-background { background: var(--primary) !important; } + .mat-checkbox-frame { color: var(--secondary); } -:focus{ + +:focus { outline: none; outline-offset: 8px; } + .lang-selection { vertical-align: middle; margin-right: 0; } -.select-all-label{ + +.select-all-label { padding-left: 15px; cursor: pointer; } -.manual-input{ + +.manual-input { background-color: transparent; border: 1px solid var(--on-dialog); padding: 5px; @@ -56,59 +67,78 @@ color: var(--on-dialog); width: 100% } -.manual-input-title{ + +.manual-input-title { margin-top: 15px; } -.select-list{ + +.select-list { width: calc(100% - 24px); } + .keywords-actions { white-space: nowrap; padding-left: 5px; margin-left: auto; color: var(--on-surface); } -.lang-btn{ + +.lang-btn { width: 100%; } + .keywords-actions-selected { color: var(--on-surface); } -.isEditing{ + +.isEditing { background: var(--primary); height: 22px; border-radius: 5px; color: var(--on-primary); - border: 1px solid var( --on-primary); + border: 1px solid var(--on-primary); } + .edit-accept { color: var(--on-surface); } + .select-all-section { vertical-align: middle; padding-top: 20px; padding-bottom: 20px; } + .select-all-label { padding-left: 15px; } + .select-all-icon { float: left; padding-left: 16px; } + .select-all-checkbox { float: right; padding-right: 3px; } + .mat-select { padding-left: 14px; } + ::ng-deep .mat-select-panel { background: var(--dialog); } + .mat-option.mat-active { color: var(--primary); } + .mat-option { color: var(--on-surface); } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html index 058ba59373cc75263dc5dddefa9c5a8844c1080a..5e2ad24517e187c1c83352feeb81ba6fb19861b7 100644 --- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html +++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html @@ -1,6 +1,6 @@ <mat-dialog-content> <div fxLayout="row" fxLayoutAlign="center center" fxFill> - <mat-progress-spinner *ngIf="isLoading" mode="indeterminate"></mat-progress-spinner> + <app-mat-spinner-overlay *ngIf="isLoading" [useCustomCSSColor]="true"></app-mat-spinner-overlay> </div> <div *ngIf="!isLoading"> <mat-accordion hideToggle> @@ -367,7 +367,8 @@ </mat-menu> - <mat-tab-group [selectedIndex]="selectedTabIndex" (selectedIndexChange)="changeTabIndex()" animationDuration="0ms" mat-stretch-tabs mat-align-tabs="center"> + <mat-tab-group [selectedIndex]="selectedTabIndex" (selectedIndexChange)="changeTabIndex()" animationDuration="0ms" + mat-stretch-tabs mat-align-tabs="center"> <mat-tab label="{{'topic-cloud-dialog.keywords' | translate}}"> <mat-card class="color-surface" *ngIf="(keywords.size === 0 || (searchMode && filteredKeywords.length === 0))&&!isLoading"> @@ -409,7 +410,8 @@ </button> <button class="margin-right" mat-icon-button style="align-self:flex-end;" (click)="openConfirmDialog('delete-message','delete',keyword)"> - <mat-icon class="red" matTooltip="{{'topic-cloud-dialog.delete' | translate}}">delete_sweep</mat-icon> + <mat-icon class="red" matTooltip="{{'topic-cloud-dialog.delete' | translate}}">delete_sweep + </mat-icon> </button> </div> @@ -443,7 +445,7 @@ matTooltip="{{'topic-cloud-dialog.blacklist-is'+(blacklistIsActive?'':'-not')+'-active' | translate}}">Blacklist</label> </ng-template> <mat-card class="color-surface" - *ngIf="(blacklistKeywords.length === 0 || (searchMode && filteredKeywords.length === 0))&&!isLoading"> + *ngIf="(blacklistKeywords.length === 0 || (searchMode && filteredKeywords.length === 0))&&!isLoading"> <p class="color-on-surface" fxLayoutAlign="center"> {{'topic-cloud-dialog.no-keywords-note' | translate}} </p> @@ -451,8 +453,8 @@ <mat-accordion> <div *ngFor="let keyword of (searchMode ? filteredKeywords : blacklistKeywords); let i = index"> <mat-expansion-panel class="color-surface" (opened)="panelOpenState = true" - (closed)="panelOpenState = edit = false" [attr.data-index]="i" - matTooltip="{{'topic-cloud-dialog.'+(keyword.keywordType === 2?'Keyword-from-both':(keyword.keywordType === 0?'keyword-from-spacy':'keyword-from-questioner')) | translate}}"> + (closed)="panelOpenState = edit = false" [attr.data-index]="i" + matTooltip="{{'topic-cloud-dialog.'+(keyword.keywordType === 2?'Keyword-from-both':(keyword.keywordType === 0?'keyword-from-spacy':'keyword-from-questioner')) | translate}}"> <mat-expansion-panel-header class="color-surface"> <mat-panel-title> {{keyword.keyword}} @@ -464,8 +466,10 @@ </mat-expansion-panel-header> <div *ngFor="let question of keyword.comments"> - <app-topic-dialog-comment [question]="question.body" [keyword]="keyword.keyword" [maxShowedCharachters]="140" - [profanityFilter]="profanityFilter" [languageSpecific]="censorLanguageSpecificCheck" + <app-topic-dialog-comment [question]="question.body" [keyword]="keyword.keyword" + [maxShowedCharachters]="140" + [profanityFilter]="profanityFilter" + [languageSpecific]="censorLanguageSpecificCheck" [partialWords]="censorPartialWordsCheck" [language]="question.language"></app-topic-dialog-comment> </div> @@ -478,7 +482,8 @@ </button> <button class="margin-right" mat-icon-button style="align-self:flex-end;" (click)="openConfirmDialog('delete-message','delete',keyword)"> - <mat-icon class="red" matTooltip="{{'topic-cloud-dialog.delete' | translate}}">delete_sweep</mat-icon> + <mat-icon class="red" matTooltip="{{'topic-cloud-dialog.delete' | translate}}">delete_sweep + </mat-icon> </button> </div> diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss index 86c644ce629cd8a7704e986c99957c3071e622fb..de118a9b851e3632354f6838a78da700b6a400e4 100644 --- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss +++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss @@ -181,3 +181,7 @@ mat-dialog-content { color: black; width: 100%; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts index 0ac869af9f8fb781e123345a4878147cdc5de081..36eb4e46695a782290b0800cd865b2dac56e9d95 100644 --- a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts +++ b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts @@ -17,6 +17,8 @@ import { User } from '../../../../models/user'; import { WorkerDialogComponent } from '../worker-dialog/worker-dialog.component'; import { Room } from '../../../../models/room'; import { CloudParameters } from '../../../../utils/cloud-parameters'; +import { ThemeService } from '../../../../../theme/theme.service'; +import { Theme } from '../../../../../theme/Theme'; class CommentsCount { comments: number; @@ -51,6 +53,7 @@ export class TopicCloudFilterComponent implements OnInit { hasNoKeywords = false; private readonly _adminData: TopicCloudAdminData; private _room: Room; + private currentTheme: Theme; constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>, public dialog: MatDialog, @@ -61,7 +64,8 @@ export class TopicCloudFilterComponent implements OnInit { protected roomService: RoomService, @Inject(MAT_DIALOG_DATA) public data: any, public eventService: EventService, - private topicCloudAdminService: TopicCloudAdminService) { + private topicCloudAdminService: TopicCloudAdminService, + private themeService: ThemeService) { langService.langEmitter.subscribe(lang => translationService.use(lang)); this._adminData = TopicCloudAdminService.getDefaultAdminData; if (this._adminData.keywordORfulltext === KeywordOrFulltext.fulltext) { @@ -75,6 +79,9 @@ export class TopicCloudFilterComponent implements OnInit { } ngOnInit() { + this.themeService.getTheme().subscribe((themeName) => { + this.currentTheme = this.themeService.getThemeByKey(themeName); + }); this.translationService.use(localStorage.getItem('currentLang')); const subscriptionEventService = this.eventService.on<CommentListData>('currentRoomData').subscribe(data => { subscriptionEventService.unsubscribe(); diff --git a/src/app/components/shared/comment-answer/comment-answer.component.html b/src/app/components/shared/comment-answer/comment-answer.component.html index 635e3eee0ef78021f792b66ab45b3df7bebd4f0e..96993bcf257750c76b43c49d50d2313b12442166 100644 --- a/src/app/components/shared/comment-answer/comment-answer.component.html +++ b/src/app/components/shared/comment-answer/comment-answer.component.html @@ -93,8 +93,12 @@ (click)="grammarChecker.grammarCheck(commentBody)" class="spell-button"> {{ 'comment-page.grammar-check' | translate}} - <mat-icon *ngIf="grammarChecker.isSpellchecking" style="margin: 0;"> - <mat-spinner diameter="20"></mat-spinner> + <mat-icon *ngIf="grammarChecker.isSpellchecking" + class="spinner-container"> + <app-mat-spinner-overlay diameter="20" + strokeWidth="2" + [useCustomCSSColor]="true"> + </app-mat-spinner-overlay> </mat-icon> </button> </ars-col> diff --git a/src/app/components/shared/comment-answer/comment-answer.component.scss b/src/app/components/shared/comment-answer/comment-answer.component.scss index 9229ee94d2f9bf98c52a871549bb5a191b098232..5af943e0ad1bc9980ca6f9c52b4cc6b10c1f5956 100644 --- a/src/app/components/shared/comment-answer/comment-answer.component.scss +++ b/src/app/components/shared/comment-answer/comment-answer.component.scss @@ -115,6 +115,12 @@ mat-icon { display: none; } +.spinner-container { + font-size: 14px; + margin-right: 7px; + margin-top: -6px; +} + /* Suggestion classes from Languagetool */ diff --git a/src/app/components/shared/comment-list/comment-list.component.html b/src/app/components/shared/comment-list/comment-list.component.html index acd1731dd28dd31ea3fa8b5b89d663cddced158e..23286baa3333ed535aab5448decd1d2b8fec074a 100644 --- a/src/app/components/shared/comment-list/comment-list.component.html +++ b/src/app/components/shared/comment-list/comment-list.component.html @@ -154,7 +154,8 @@ <mat-icon class="star" [ngClass]="{favorite: 'favorite-icon'}[currentFilter]">grade </mat-icon> - <span [ngClass]="{favorite: 'favorite-icon'}[currentFilter]">{{ 'comment-list.filter-favorite' | translate }}</span> + <span + [ngClass]="{favorite: 'favorite-icon'}[currentFilter]">{{ 'comment-list.filter-favorite' | translate }}</span> </button> <button mat-menu-item @@ -163,7 +164,8 @@ <mat-icon class="bookmark" [ngClass]="{bookmark: 'bookmark-icon'}[currentFilter]">bookmark </mat-icon> - <span [ngClass]="{bookmark: 'bookmark-icon'}[currentFilter]">{{ 'comment-list.filter-bookmark' | translate }}</span> + <span + [ngClass]="{bookmark: 'bookmark-icon'}[currentFilter]">{{ 'comment-list.filter-bookmark' | translate }}</span> </button> <button mat-menu-item @@ -173,7 +175,8 @@ <mat-icon class="answer" [ngClass]="{answer: 'answered-icon'}[currentFilter]">comment </mat-icon> - <span [ngClass]="{answer: 'answered-icon'}[currentFilter]">{{ 'comment-list.filter-answered' | translate }}</span> + <span + [ngClass]="{answer: 'answered-icon'}[currentFilter]">{{ 'comment-list.filter-answered' | translate }}</span> </button> <button mat-menu-item @@ -183,7 +186,8 @@ <mat-icon class="unanswered" [ngClass]="{unanswered: 'unanswered-icon'}[currentFilter]">comment </mat-icon> - <span [ngClass]="{unanswered: 'unanswered-icon'}[currentFilter]">{{ 'comment-list.filter-unanswered' | translate }}</span> + <span + [ngClass]="{unanswered: 'unanswered-icon'}[currentFilter]">{{ 'comment-list.filter-unanswered' | translate }}</span> </button> <button mat-menu-item @@ -201,7 +205,8 @@ <mat-icon class="lecturer" [ngClass]="{lecturer: 'lecturer-icon'}[currentFilter]">school </mat-icon> - <span [ngClass]="{lecturer: 'lecturer-icon'}[currentFilter]">{{ 'comment-list.filter-lecturer' | translate }}</span> + <span + [ngClass]="{lecturer: 'lecturer-icon'}[currentFilter]">{{ 'comment-list.filter-lecturer' | translate }}</span> </button> <button mat-menu-item @@ -210,7 +215,8 @@ <mat-icon class="moderator" [ngClass]="{moderator: 'moderator-icon'}[currentFilter]">gavel </mat-icon> - <span [ngClass]="{moderator: 'moderator-icon'}[currentFilter]">{{ 'comment-list.filter-moderator' | translate }}</span> + <span + [ngClass]="{moderator: 'moderator-icon'}[currentFilter]">{{ 'comment-list.filter-moderator' | translate }}</span> </button> @@ -244,6 +250,11 @@ <mat-icon>add</mat-icon> </button> +<app-mat-spinner-overlay *ngIf="isLoading" + overlay="true" + [useCustomCSSColor]="true"> +</app-mat-spinner-overlay> + <div *ngIf="!isLoading"> <app-comment *ngFor="let current of hideCommentsList ? filteredComments : commentsFilteredByTime" [comment]="current" @@ -262,10 +273,11 @@ <app-active-user *ngIf="room" [room]="this.room"></app-active-user> <!-- No Questions Present --> -<div *ngIf="comments && (commentsFilteredByTime.length < 1 && period === 'time-all' || comments.length === 0) && !isLoading" - fxLayout="row" - fxLayoutAlign="center center" - class="no-comments"> +<div + *ngIf="comments && (commentsFilteredByTime.length < 1 && period === 'time-all' || comments.length === 0) && !isLoading" + fxLayout="row" + fxLayoutAlign="center center" + class="no-comments"> <p class="oldtypo-p">{{ 'comment-page.no-comments' | translate }}</p> </div> @@ -274,7 +286,8 @@ fxLayout="row" fxLayoutAlign="center center" class="no-comments"> - <p class="oldtypo-p">{{ (search ? 'comment-page.no-comments-with-search' : 'comment-page.no-comments-with-filter') | translate }}</p> + <p + class="oldtypo-p">{{ (search ? 'comment-page.no-comments-with-search' : 'comment-page.no-comments-with-filter') | translate }}</p> </div> <!--Hidden Div's for a11y-Descriptions--> diff --git a/src/app/components/shared/comment-list/comment-list.component.scss b/src/app/components/shared/comment-list/comment-list.component.scss index a669b2f1b032e4ed7e951bf0b6b4c20979dfea6e..109b80571f4500c0ad2d2526997985b9b3d3668c 100644 --- a/src/app/components/shared/comment-list/comment-list.component.scss +++ b/src/app/components/shared/comment-list/comment-list.component.scss @@ -255,6 +255,10 @@ h3 { opacity: 1.0 !important; } -h1{ +h1 { color: red; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/comment/comment.component.html b/src/app/components/shared/comment/comment.component.html index c54a2c2f2c52080f95d1da31d2ae06ec93be4bd9..cf0cf62bba47aa88951a3e05767913f8e41d91f5 100644 --- a/src/app/components/shared/comment/comment.component.html +++ b/src/app/components/shared/comment/comment.component.html @@ -85,7 +85,7 @@ </mat-icon> </button> <button mat-icon-button - *ngIf="(!isStudent || comment.favorite) && !moderator" + *ngIf="!isStudent && !moderator" [disabled]="isStudent" (click)="setFavorite(comment)" tabindex="0" @@ -95,6 +95,25 @@ : ('comment-page.mark-not-favorite' | translate)">grade </mat-icon> </button> + <button mat-icon-button + *ngIf="(comment.favorite && isStudent && !(comment.creatorId && user && comment.creatorId === user.id))" + tabindex="0" + attr.aria-labelledby="comment_grade{{ comment.id }}"> + <mat-icon [ngClass]="{'favorite-icon' : comment.favorite, 'not-marked' : !comment.favorite}" + [matTooltip]="!comment.favorite ? ('comment-page.mark-favorite' | translate) + : ('comment-page.mark-not-favorite' | translate)">grade + </mat-icon> + </button> + <button mat-icon-button + *ngIf="(comment.favorite && isStudent && (comment.creatorId && user && comment.creatorId === user.id))" + (click)="openBonusStarDialog()" + tabindex="0" + attr.aria-labelledby="comment_grade{{ comment.id }}"> + <mat-icon [ngClass]="{'favorite-icon' : comment.favorite, 'not-marked' : !comment.favorite}" + [matTooltip]="!comment.favorite ? ('comment-page.mark-favorite' | translate) + : ('comment-page.mark-not-favorite' | translate)">grade + </mat-icon> + </button> <button mat-icon-button *ngIf="(!isStudent || comment.bookmark) && !moderator" [disabled]="isStudent" diff --git a/src/app/components/shared/comment/comment.component.ts b/src/app/components/shared/comment/comment.component.ts index ca06a69ac583a44ed8efa4b21aa249fe19b8ce88..83c2ec6a2fb5f8209964fc6c632d1db9387ac45b 100644 --- a/src/app/components/shared/comment/comment.component.ts +++ b/src/app/components/shared/comment/comment.component.ts @@ -19,6 +19,7 @@ import { RowComponent } from '../../../../../projects/ars/src/lib/components/lay import { User } from '../../../models/user'; import { RoomDataService } from '../../../services/util/room-data.service'; import { SpacyKeyword } from '../../../services/http/spacy.service'; +import { UserBonusTokenComponent } from '../../participant/_dialogs/user-bonus-token/user-bonus-token.component'; @Component({ selector: 'app-comment', @@ -292,4 +293,11 @@ export class CommentComponent implements OnInit, AfterViewInit { }); } + + openBonusStarDialog() { + const dialogRef = this.dialog.open(UserBonusTokenComponent, { + width: '600px' + }); + dialogRef.componentInstance.userId = this.user.id; + } } diff --git a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html index fc72dc98d2fbbe8dda14c6316402bfed4dd100e7..76a2bf7d8af64259d8e094dce9413ca84b4fd500 100644 --- a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html +++ b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html @@ -18,8 +18,11 @@ <mat-icon *ngIf="buttonIcon" style="margin-right: 5px;">{{buttonIcon}}</mat-icon> {{ buttonsLabelSection + '.' + confirmButtonLabel | translate}} - <mat-icon *ngIf="showLoadingCycle"> - <mat-spinner diameter="20"></mat-spinner> + <mat-icon *ngIf="showLoadingCycle" class="spinner-container"> + <app-mat-spinner-overlay diameter="20" + strokeWidth="2" + [useCustomCSSColor]="true"> + </app-mat-spinner-overlay> </mat-icon> </button> <button diff --git a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.scss b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.scss index f05bfaa7fd20dec32f0eab59e64d0a322861c6b0..2a364a363221960de5e78c1cd26134fcda75bdfd 100644 --- a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.scss +++ b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.scss @@ -26,3 +26,8 @@ background: var(--secondary); color: var(--on-secondary); } + +.spinner-container { + font-size: 14px; + margin-top: -2px; +} diff --git a/src/app/components/shared/header/header.component.html b/src/app/components/shared/header/header.component.html index df647343fac75108d51f83fc3b23bb1dd8318f97..f021bc444457a00e1498018895edca25231bd7b5 100644 --- a/src/app/components/shared/header/header.component.html +++ b/src/app/components/shared/header/header.component.html @@ -237,7 +237,7 @@ <ng-container *ngIf="router.url.includes('/creator/room/')"> <button mat-menu-item - (click)="navigateModerator()" + (click)="navigateEditSessionDescription()" tabindex="0"> <mat-icon>flag</mat-icon> <span>{{'header.edit-session-description' | translate}}</span> @@ -245,8 +245,8 @@ <button mat-menu-item *ngIf="user" - (click)="navigateModerator()" - tabindex="0"> + tabindex="0" + routerLink="moderator/room/{{shortId}}/moderator/comments"> <mat-icon class="gavel">visibility_off</mat-icon> <span>{{'header.moderation-mode' | translate}}</span> </button> @@ -290,7 +290,7 @@ </button> <button mat-menu-item - (click)="navigateModerator()" + (click)="navigateProfanityFilter()" tabindex="0"> <mat-icon>clear</mat-icon> <span>{{'header.profanity-filter' | translate}}</span> @@ -365,7 +365,7 @@ <button mat-menu-item *ngIf="user && user.role == 3 && !router.url.includes('/participant') && !router.url.endsWith('/comments') && !router.url.includes('/comment/') && !router.url.endsWith('tagcloud')" - (click)="delete()" + (click)="navigateDeleteRoom()" tabindex="0"> <mat-icon class="color-warn">delete</mat-icon> <span>{{'header.delete-room' | translate}}</span> diff --git a/src/app/components/shared/header/header.component.ts b/src/app/components/shared/header/header.component.ts index 13618fdf7522f89357c1f0d8b23e3a32b34e03df..43159cf93dc68cddd5f127c6297ba6191d4caccd 100644 --- a/src/app/components/shared/header/header.component.ts +++ b/src/app/components/shared/header/header.component.ts @@ -1,34 +1,33 @@ -import {Component,OnInit,Renderer2} from '@angular/core'; -import {AuthenticationService} from '../../../services/http/authentication.service'; -import {NotificationService} from '../../../services/util/notification.service'; -import {NavigationEnd,Router} from '@angular/router'; -import {User} from '../../../models/user'; -import {UserRole} from '../../../models/user-roles.enum'; -import {Location} from '@angular/common'; -import {TranslateService} from '@ngx-translate/core'; -import {MatDialog} from '@angular/material/dialog'; -import {LoginComponent} from '../login/login.component'; -import {DeleteAccountComponent} from '../_dialogs/delete-account/delete-account.component'; -import {UserService} from '../../../services/http/user.service'; -import {EventService} from '../../../services/util/event.service'; -import {AppComponent} from '../../../app.component'; -import {Rescale} from '../../../models/rescale'; -import {KeyboardUtils} from '../../../utils/keyboard'; -import {KeyboardKey} from '../../../utils/keyboard/keys'; -import {UserBonusTokenComponent} from '../../participant/_dialogs/user-bonus-token/user-bonus-token.component'; -import {RemindOfTokensComponent} from '../../participant/_dialogs/remind-of-tokens/remind-of-tokens.component'; -import {QrCodeDialogComponent} from '../_dialogs/qr-code-dialog/qr-code-dialog.component'; -import {BonusTokenService} from '../../../services/http/bonus-token.service'; -import {MotdService} from '../../../services/http/motd.service'; -import {TopicCloudFilterComponent} from '../_dialogs/topic-cloud-filter/topic-cloud-filter.component'; -import {RoomService} from '../../../services/http/room.service'; -import {Room} from '../../../models/room'; -import {TagCloudMetaData} from '../../../services/util/tag-cloud-data.service'; -import {WorkerDialogComponent} from '../_dialogs/worker-dialog/worker-dialog.component'; -import {WsRoomService} from '../../../services/websockets/ws-room.service'; -import {TopicCloudAdminService} from '../../../services/util/topic-cloud-admin.service'; -import {HeaderService} from '../../../services/util/header.service'; - +import { Component, OnInit, Renderer2 } from '@angular/core'; +import { AuthenticationService } from '../../../services/http/authentication.service'; +import { NotificationService } from '../../../services/util/notification.service'; +import { Router, NavigationEnd } from '@angular/router'; +import { User } from '../../../models/user'; +import { UserRole } from '../../../models/user-roles.enum'; +import { Location } from '@angular/common'; +import { TranslateService } from '@ngx-translate/core'; +import { MatDialog } from '@angular/material/dialog'; +import { LoginComponent } from '../login/login.component'; +import { DeleteAccountComponent } from '../_dialogs/delete-account/delete-account.component'; +import { UserService } from '../../../services/http/user.service'; +import { EventService } from '../../../services/util/event.service'; +import { AppComponent } from '../../../app.component'; +import { Rescale } from '../../../models/rescale'; +import { KeyboardUtils } from '../../../utils/keyboard'; +import { KeyboardKey } from '../../../utils/keyboard/keys'; +import { UserBonusTokenComponent } from '../../participant/_dialogs/user-bonus-token/user-bonus-token.component'; +import { RemindOfTokensComponent } from '../../participant/_dialogs/remind-of-tokens/remind-of-tokens.component'; +import { QrCodeDialogComponent } from '../_dialogs/qr-code-dialog/qr-code-dialog.component'; +import { BonusTokenService } from '../../../services/http/bonus-token.service'; +import { MotdService } from '../../../services/http/motd.service'; +import { TopicCloudFilterComponent } from '../_dialogs/topic-cloud-filter/topic-cloud-filter.component'; +import { RoomService } from '../../../services/http/room.service'; +import { Room } from '../../../models/room'; +import { TagCloudMetaData } from '../../../services/util/tag-cloud-data.service'; +import { WorkerDialogComponent } from '../_dialogs/worker-dialog/worker-dialog.component'; +import { WsRoomService } from '../../../services/websockets/ws-room.service'; +import { TopicCloudAdminService } from '../../../services/util/topic-cloud-admin.service'; +import { HeaderService } from '../../../services/util/header.service'; @Component({ selector: 'app-header', @@ -336,6 +335,18 @@ export class HeaderComponent implements OnInit { this.eventService.broadcast('navigate', 'createQuestion'); } + public navigateDeleteRoom(){ + this.eventService.broadcast('navigate', 'deleteRoom'); + } + + public navigateProfanityFilter() { + this.eventService.broadcast('navigate', 'profanityFilter'); + } + + public navigateEditSessionDescription() { + this.eventService.broadcast('navigate', 'editSessionDescription'); + } + public navigateTopicCloud() { const confirmDialogRef = this.confirmDialog.open(TopicCloudFilterComponent, { autoFocus: false diff --git a/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.html b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.html new file mode 100644 index 0000000000000000000000000000000000000000..161e84155fbeb0c4f317bdf15c7251140bf3549c --- /dev/null +++ b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.html @@ -0,0 +1,18 @@ +<ng-container *ngIf="overlay;else progressSpinner"> + <div class="overlay"> + <div class="center"> + <ng-template [ngTemplateOutlet]="progressSpinner"></ng-template> + </div> + </div> +</ng-container> +<ng-template #progressSpinner> + <mat-progress-spinner + #containerRef + [ngClass]="{'inline-spinner': !overlay}" + [diameter]="diameter" + [mode]="mode" + [color]="color" + [strokeWidth]="strokeWidth" + [value]="value"> + </mat-progress-spinner> +</ng-template> diff --git a/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.scss b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..0437c8816aa2b083a50fe8073ce233808740a075 --- /dev/null +++ b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.scss @@ -0,0 +1,27 @@ +.center { + position: absolute; + top: 50%; + left: 50%; +} + +mat-progress-spinner { + -moz-transform: translateX(-50%) translateY(-50%); + -webkit-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); +} + +.overlay { + height: 100vh; + width: 100%; + background-color: rgba(0, 0, 0, 0.286); + z-index: 10; + top: 0; + left: 0; + position: fixed; +} + +mat-progress-spinner.inline-spinner { + display: inline; + margin-left: 0.25em; + top: 0.115em; +} diff --git a/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.spec.ts b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..e984205b8f4ded729d07b6a92c8a305a125111e9 --- /dev/null +++ b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.spec.ts @@ -0,0 +1,26 @@ +/*import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MatSpinnerOverlayComponent } from './mat-spinner-overlay.component'; + +describe('MatSpinnerOverlayComponent', () => { + let component: MatSpinnerOverlayComponent; + let fixture: ComponentFixture<MatSpinnerOverlayComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MatSpinnerOverlayComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MatSpinnerOverlayComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + */ diff --git a/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.ts b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..fccc0f9a21360fd8e1df0bbb3c82931f3d46de3a --- /dev/null +++ b/src/app/components/shared/mat-spinner-overlay/mat-spinner-overlay.component.ts @@ -0,0 +1,61 @@ +import { + AfterViewInit, + Component, + ElementRef, + Input, + OnInit, + Renderer2, + RendererStyleFlags2, + ViewChild +} from '@angular/core'; +import { ProgressSpinnerMode } from '@angular/material/progress-spinner'; +import { ThemePalette } from '@angular/material/core'; + +@Component({ + selector: 'app-mat-spinner-overlay', + templateUrl: './mat-spinner-overlay.component.html', + styleUrls: ['./mat-spinner-overlay.component.scss'] +}) +export class MatSpinnerOverlayComponent implements OnInit, AfterViewInit { + + @ViewChild('containerRef') containerRef: ElementRef; + @Input() value = 100; + @Input() diameter = 100; + @Input() mode: ProgressSpinnerMode = 'indeterminate'; + @Input() strokeWidth = 10; + @Input() overlay = false; + @Input() color: ThemePalette = 'primary'; + /** + * Overrides diameter and strokeWidth settings, only possible if overlay is false + */ + @Input() parentFontContainer: HTMLElement = null; + @Input() useCustomCSSColor = false; + + constructor(private element: ElementRef<HTMLElement>, + private renderer2: Renderer2) { + } + + ngOnInit(): void { + if (this.parentFontContainer && !this.overlay) { + const elem = this.renderer2.createElement('canvas'); + const ctx = elem.getContext('2d'); + const style = window.getComputedStyle(this.parentFontContainer); + ctx.font = style.font; + const metric = ctx.measureText(this.parentFontContainer.innerText); + this.diameter = Math.abs(metric.fontBoundingBoxAscent) + Math.abs(metric.actualBoundingBoxDescent); + this.strokeWidth = this.diameter / 10; + } + } + + ngAfterViewInit() { + const svg = this.element.nativeElement.getElementsByTagName('svg'); + if (svg.length < 1) { + return; + } + this.renderer2.setStyle(svg[0], 'position', 'static'); + if (this.useCustomCSSColor && svg[0].firstElementChild) { + this.renderer2.setStyle(svg[0].firstElementChild, 'stroke', 'currentColor', RendererStyleFlags2.Important); + } + } + +} diff --git a/src/app/components/shared/questionwall/question-wall/question-wall.component.html b/src/app/components/shared/questionwall/question-wall/question-wall.component.html index 5a6249b9cb33c9cacc3c86446b65fabcd0fd41cb..5c780b45a7b9995f3d6a341a47136f7f26c9f767 100644 --- a/src/app/components/shared/questionwall/question-wall/question-wall.component.html +++ b/src/app/components/shared/questionwall/question-wall/question-wall.component.html @@ -1,3 +1,7 @@ +<app-mat-spinner-overlay *ngIf="isLoading" + [overlay]="true" + [useCustomCSSColor]="true"> +</app-mat-spinner-overlay> <ars-screen ars-flex-box class="questionwall-screen"> <ars-row [height]="50" class="questionwall-header"> <ars-style-btn-material *ngIf="room" style="width:100%;height:100%;" ars-flex-box> @@ -17,9 +21,12 @@ <ars-fill></ars-fill> <ars-col ars-btn-wrp [xp]="16" [extra]="true"> <mat-menu #sortMenu> - <button mat-menu-item (click)="sortTime(true)" aria-labelledby="sort-lbl-new">{{'question-wall.sort-new' | translate}}</button> - <button mat-menu-item (click)="sortTime()" aria-labelledby="sort-lbl-old">{{'question-wall.sort-old' | translate}}</button> - <button mat-menu-item (click)="sortScore(true)" aria-labelledby="sort-lbl-rating">{{'question-wall.sort-score' | translate}}</button> + <button mat-menu-item (click)="sortTime(true)" + aria-labelledby="sort-lbl-new">{{'question-wall.sort-new' | translate}}</button> + <button mat-menu-item (click)="sortTime()" + aria-labelledby="sort-lbl-old">{{'question-wall.sort-old' | translate}}</button> + <button mat-menu-item (click)="sortScore(true)" + aria-labelledby="sort-lbl-rating">{{'question-wall.sort-score' | translate}}</button> </mat-menu> <mat-menu #filterMenu> <button mat-menu-item (click)="filterFavorites()" aria-labelledby="filter-lbl-favorites" class="selection"> @@ -119,7 +126,8 @@ </ars-row> <ars-row> <ars-row class="bound" style="padding:16px 32px 16px 32px;box-sizing:border-box;max-width:100%;"> - <markdown [ngStyle]="{'font-size':fontSize+'%'}" class="questionwall-present-markdown" class="images" katex emoji lineNumbers lineHighlight + <markdown [ngStyle]="{'font-size':fontSize+'%'}" class="questionwall-present-markdown" class="images" + katex emoji lineNumbers lineHighlight [data]="commentFocus.comment.body"></markdown> </ars-row> </ars-row> @@ -214,11 +222,12 @@ style="box-sizing:border-box;padding:16px;cursor:pointer"> <ars-col class="questionwall-comment-meta"> <i class="questionwall-icon">person_pin_circle</i> - <p (click)="filterUser(comment);" class="questionwall-comment-user" matRipple>{{comment.comment.userNumber}}</p> + <p (click)="filterUser(comment);" class="questionwall-comment-user" + matRipple>{{comment.comment.userNumber}}</p> <p class="questionwall-comment-timestamp">{{comment.timeAgo}}</p> </ars-col> <ars-col> - <p class="questionwall-comment-notification">{{comment.old?'':'NEW'}}</p> + <p class="questionwall-comment-notification">{{comment.old ? '' : 'NEW'}}</p> </ars-col> </ars-row> <ars-row @@ -226,7 +235,7 @@ style="box-sizing:border-box;padding:0 16px;cursor:pointer"> <p class="questionwall-comment-body"> <markdown class="images" katex emoji lineNumbers lineHighlight - [data]="comment.comment.body"></markdown> + [data]="comment.comment.body"></markdown> </p> </ars-row> <ars-row [height]="50"> @@ -241,7 +250,7 @@ </button> </ars-col> <ars-fill (click)="focusComment(comment)" style="cursor:pointer"></ars-fill> - <ars-col ars-btn-wrp [xp]="16" [extra]="true"*ngIf="comment.comment.tag"> + <ars-col ars-btn-wrp [xp]="16" [extra]="true" *ngIf="comment.comment.tag"> <button ars-btn (click)="filterTag(comment.comment.tag);" matRipple> <mat-icon class="icon-svg" svgIcon="comment_tag"></mat-icon> <p>{{comment.comment.tag}}</p> @@ -274,7 +283,8 @@ <p>{{'question-wall.filter-user-count' | translate}}</p> </button> <button ars-btn mat-ripple *ngFor="let user of userList" (click)="applyUserMap(user[1])"> - <p>{{user[1]}}</p><p>{{user[0]}}</p> + <p>{{user[1]}}</p> + <p>{{user[0]}}</p> </button> </ars-row> </ars-style-btn-material> diff --git a/src/app/components/shared/questionwall/question-wall/question-wall.component.scss b/src/app/components/shared/questionwall/question-wall/question-wall.component.scss index bbeedf4ba8595b677263476f3a1bf819db083425..e435ea8944df7595c087572a043ef6b71af23a9c 100644 --- a/src/app/components/shared/questionwall/question-wall/question-wall.component.scss +++ b/src/app/components/shared/questionwall/question-wall/question-wall.component.scss @@ -300,11 +300,16 @@ font-weight: bold; } -.selection:focus{ +.selection:focus { background-color: black !important; } -h2{ + +h2 { color: red; font-weight: normal !important; padding-top: 10px !important; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/questionwall/question-wall/question-wall.component.ts b/src/app/components/shared/questionwall/question-wall/question-wall.component.ts index cc87e03cbce36f35d20c2c02577a0bc07455aea1..4506a8b84e2c671140ac26802d87e7fe1e5dea56 100644 --- a/src/app/components/shared/questionwall/question-wall/question-wall.component.ts +++ b/src/app/components/shared/questionwall/question-wall/question-wall.component.ts @@ -50,6 +50,7 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy { fontSize = 180; periodsList = Object.values(Period); period: Period = Period.all; + isLoading = true; constructor( private authenticationService: AuthenticationService, @@ -92,6 +93,7 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy { return; } e.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); + this.isLoading = false; e.forEach(c => { this.roomDataService.checkProfanity(c); const comment = new QuestionWallComment(c, true); diff --git a/src/app/components/shared/quiz-now/quiz-now.component.html b/src/app/components/shared/quiz-now/quiz-now.component.html index 5d780e06aa171fb6353bc3c5af3d04d09bb76c47..0b24598d6eeb81b767bfc5e3ad1501b19cf2c194 100644 --- a/src/app/components/shared/quiz-now/quiz-now.component.html +++ b/src/app/components/shared/quiz-now/quiz-now.component.html @@ -1,3 +1,10 @@ +<app-mat-spinner-overlay *ngIf="isLoading" + overlay="true" + useCustomCSSColor="true"> +</app-mat-spinner-overlay> <div class="container"> - <iframe class="responsive-iframe" [src]="urlSafe"></iframe> + <iframe class="responsive-iframe" [src]="urlSafe" + (load)="isLoading = false" + (error)="isLoading = false"> + </iframe> </div> diff --git a/src/app/components/shared/quiz-now/quiz-now.component.scss b/src/app/components/shared/quiz-now/quiz-now.component.scss index c4785b36853df6e11b794b3f6b9a944a4163e941..7c334602eeae117754d9201661d8c9f3bdff6e7d 100644 --- a/src/app/components/shared/quiz-now/quiz-now.component.scss +++ b/src/app/components/shared/quiz-now/quiz-now.component.scss @@ -16,3 +16,7 @@ iframe { width: 100%; height: 100%; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/quiz-now/quiz-now.component.ts b/src/app/components/shared/quiz-now/quiz-now.component.ts index 2c7fc356db5be3d03f20231a83858d9e7b19fc42..69c95063fe6c472fa1727c2cd21ce4bce7647c72 100644 --- a/src/app/components/shared/quiz-now/quiz-now.component.ts +++ b/src/app/components/shared/quiz-now/quiz-now.component.ts @@ -1,16 +1,19 @@ -import {Component, OnInit} from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; + @Component({ selector: 'app-quiz-now', templateUrl: './quiz-now.component.html', styleUrls: ['./quiz-now.component.scss'] }) -export class QuizNowComponent { +export class QuizNowComponent implements OnInit { urlSafe: SafeResourceUrl; + isLoading = true; - constructor(public sanitizer: DomSanitizer) { } + constructor(public sanitizer: DomSanitizer) { + } ngOnInit() { - this.urlSafe= this.sanitizer.bypassSecurityTrustResourceUrl("https://staging.antworte.jetzt/"); + this.urlSafe = this.sanitizer.bypassSecurityTrustResourceUrl('https://staging.antworte.jetzt/'); } } diff --git a/src/app/components/shared/room-list/room-list.component.html b/src/app/components/shared/room-list/room-list.component.html index 6e897e4853fd98768a3905a6811f9fd80ce47ca3..9740726c01f3e91fc35b44374086ae2e2fc2144a 100644 --- a/src/app/components/shared/room-list/room-list.component.html +++ b/src/app/components/shared/room-list/room-list.component.html @@ -1,6 +1,7 @@ <div *ngIf="isLoading" fxLayout="column" fxLayoutAlign="center" fxFill> <div fxLayout="row" fxLayoutAlign="center"> - <mat-progress-spinner color="primary" mode="indeterminate" diameter="80"></mat-progress-spinner> + <app-mat-spinner-overlay [useCustomCSSColor]="true" diameter="80" strokeWidth="8"> + </app-mat-spinner-overlay> </div> </div> @@ -32,7 +33,8 @@ </th> <td mat-cell class="clickable" *matCellDef="let room" (click)="setCurrentRoom(room.shortId)" routerLink="/{{ roleToString((room.role)) }}/room/{{ room.shortId }}"> - <span matBadge="{{room.commentCount > 0 ? room.commentCount : null}}" matBadgePosition="before" matBadgeSize="small" matBadgeOverlap="false"> + <span matBadge="{{room.commentCount > 0 ? room.commentCount : null}}" matBadgePosition="before" + matBadgeSize="small" matBadgeOverlap="false"> »{{room.name}}« </span> </td> @@ -97,9 +99,9 @@ <div class="visually-hidden"> <div id="{{ 'joinButtonLabel' + room.shortId | translate }}"> {{ 'room-list.join-message-template' | translate:{ - session: room.name, - id: room.shortId, - role: ( 'room-list.' + roleToString((room.role)) + '-role' | translate ) + session: room.name, + id: room.shortId, + role: ('room-list.' + roleToString((room.role)) + '-role' | translate) } }} </div> </div> diff --git a/src/app/components/shared/room-list/room-list.component.scss b/src/app/components/shared/room-list/room-list.component.scss index a5c5f7d854e7b690113e9f2c21e5154f02c27306..2d9123091ea75f58036953316fcf7971c1f0cb5f 100644 --- a/src/app/components/shared/room-list/room-list.component.scss +++ b/src/app/components/shared/room-list/room-list.component.scss @@ -100,3 +100,7 @@ th, tr { .warn { color: var(--red) !important; } + +app-mat-spinner-overlay { + color: var(--primary); +} diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts index 1e41de89a920629e55370d040c54eff20aa03aa4..7c6520d2d6da3ccfb8eb61374691a633b2426032 100644 --- a/src/app/components/shared/shared.module.ts +++ b/src/app/components/shared/shared.module.ts @@ -45,6 +45,7 @@ import { JoyrideModule } from 'ngx-joyride'; import { TagCloudComponent } from './tag-cloud/tag-cloud.component'; import { JoyrideTemplateComponent } from './_dialogs/joyride-template/joyride-template.component'; import { JoyrideTemplateDirective } from '../../directives/joyride-template.directive'; +import { MatSpinnerOverlayComponent } from './mat-spinner-overlay/mat-spinner-overlay.component'; @NgModule({ imports: [ @@ -95,7 +96,8 @@ import { JoyrideTemplateDirective } from '../../directives/joyride-template.dire WorkerDialogComponent, AutofocusDirective, JoyrideTemplateComponent, - JoyrideTemplateDirective + JoyrideTemplateDirective, + MatSpinnerOverlayComponent ], exports: [ RoomJoinComponent, @@ -113,7 +115,8 @@ import { JoyrideTemplateDirective } from '../../directives/joyride-template.dire UserBonusTokenComponent, CloudConfigurationComponent, TagCloudPopUpComponent, - ActiveUserComponent + ActiveUserComponent, + MatSpinnerOverlayComponent ] }) export class SharedModule { diff --git a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts index 14b4e30c6cb2ac0eaa167288166eea0f7f705e3e..41bebb11df4bd5f59c5b4d9dc073ecb010156b66 100644 --- a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts +++ b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts @@ -33,8 +33,8 @@ export class TagCloudPopUpComponent implements OnInit, AfterViewInit { selectedLang: Language = 'en-US'; spellingData: string[] = []; isBlacklistActive = true; - private _popupHoverTimer: number; - private _popupCloseTimer: number; + private _popupHoverTimer; + private _popupCloseTimer; private _hasLeft = true; constructor(private langService: LanguageService, diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.html b/src/app/components/shared/tag-cloud/tag-cloud.component.html index 36b56bdcdc825808c230f597e95a56f2620592a4..e1f55377de666c06882573d552501e4cc364e990 100644 --- a/src/app/components/shared/tag-cloud/tag-cloud.component.html +++ b/src/app/components/shared/tag-cloud/tag-cloud.component.html @@ -6,7 +6,9 @@ joyrideStep="hallo123" [stepContentParams]="{text: 'Hallo Test'}" appJoyrideTemplate> - <h1 *ngIf="user && user.role > 0 && question" class="tag-cloud-brainstorming-question mat-display-1">{{question}}</h1> + <h1 *ngIf="user && user.role > 0 && question" class="tag-cloud-brainstorming-question mat-display-1"> + {{question}} + </h1> <mat-drawer-container class="spacyTagCloudContainer"> <mat-drawer [(opened)]="configurationOpen" position="end" mode="over"> <app-cloud-configuration [parent]="this"></app-cloud-configuration> @@ -14,9 +16,10 @@ <mat-drawer-content> <ars-fill ars-flex-box> <app-tag-cloud-pop-up></app-tag-cloud-pop-up> - <div [ngClass]="{'hidden': !isLoading}" fxLayout="row" fxLayoutAlign="center center" fxFill> - <mat-progress-spinner *ngIf="isLoading" mode="indeterminate"></mat-progress-spinner> - </div> + <app-mat-spinner-overlay *ngIf="isLoading" + overlay="true" + [useCustomCSSColor]="true"> + </app-mat-spinner-overlay> <angular-tag-cloud id="tagCloudComponent" class="spacyTagCloud" diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.scss b/src/app/components/shared/tag-cloud/tag-cloud.component.scss index 15887f083e174dda75a3ecc7aaf3afd38c5c2efa..342b41d255963ec864477525ca77729ee0118cab 100644 --- a/src/app/components/shared/tag-cloud/tag-cloud.component.scss +++ b/src/app/components/shared/tag-cloud/tag-cloud.component.scss @@ -33,10 +33,6 @@ mat-drawer-content { display: none !important; } -::ng-deep mat-progress-spinner circle { - stroke: var(--on-background) !important; -} - app-tag-cloud-pop-up { width: max-content; height: max-content; @@ -66,5 +62,14 @@ app-tag-cloud-pop-up { top: 80px; left: 20px; z-index: 2; - color: var(--tag-cloud-color, black); + color: var(--tag-cloud-inverted-background, black); + text-transform: var(--tag-cloud-transform, unset); + font-weight: var(--tag-cloud-font-weight, normal); + font-style: var(--tag-cloud-font-style, normal); + font-family: var(--tag-cloud-font-family, 'Dancing Script'); + font-size: 50px; +} + +app-mat-spinner-overlay { + color: var(--primary); } diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.ts b/src/app/components/shared/tag-cloud/tag-cloud.component.ts index f64e9bfa4477e6056431c5f8a9eea09fa405c5d7..5104096982f8efd248908d85e5dd4ef2efde8682 100644 --- a/src/app/components/shared/tag-cloud/tag-cloud.component.ts +++ b/src/app/components/shared/tag-cloud/tag-cloud.component.ts @@ -31,6 +31,7 @@ import { CloudParameters, CloudTextStyle } from '../../../utils/cloud-parameters import { SmartDebounce } from '../../../utils/smart-debounce'; import { JoyrideOptions } from 'ngx-joyride/lib/models/joyride-options.class'; import { JoyrideService } from 'ngx-joyride'; +import { Theme } from '../../../../theme/Theme'; class CustomPosition implements Position { left: number; @@ -107,6 +108,7 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { private _calcRenderContext: CanvasRenderingContext2D = null; private _calcFont: string = null; private readonly _smartDebounce = new SmartDebounce(1, 1_000); + private _currentTheme: Theme; constructor(private commentService: CommentService, private langService: LanguageService, @@ -138,6 +140,13 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { return CloudParameters.currentParameters; } + private static invertHex(hexStr: string) { + const r = 255 - parseInt(hexStr.substr(1, 2), 16); + const g = 255 - parseInt(hexStr.substr(3, 2), 16); + const b = 255 - parseInt(hexStr.substr(5, 2), 16); + return `#${((r * 256 + g) * 256 + b).toString(16).padStart(6, '0')}`; + } + ngOnInit(): void { this.updateGlobalStyles(); this.headerInterface = this.eventService.on<string>('navigate').subscribe(e => { @@ -198,7 +207,8 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { }); }); this.translateService.use(localStorage.getItem('currentLang')); - this.themeSubscription = this.themeService.getTheme().subscribe(() => { + this.themeSubscription = this.themeService.getTheme().subscribe((themeName) => { + this._currentTheme = this.themeService.getThemeByKey(themeName); if (this.child) { setTimeout(() => { this.setCloudParameters(TagCloudComponent.getCurrentCloudParameters(), false); @@ -208,7 +218,6 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { } ngAfterContentInit() { - document.getElementById('footer_rescale').style.display = 'none'; this._calcFont = window.getComputedStyle(document.getElementById('tagCloudComponent')).fontFamily; setTimeout(() => this.dataManager.bindToRoom(this.roomId, this.userRole)); this.dataManager.updateDemoData(this.translateService); @@ -223,7 +232,10 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { } ngOnDestroy() { - document.getElementById('footer_rescale').style.display = 'block'; + const customTagCloudStyles = document.getElementById('tagCloudStyles') as HTMLStyleElement; + if (customTagCloudStyles) { + customTagCloudStyles.sheet.disabled = true; + } this.headerInterface.unsubscribe(); this.themeSubscription.unsubscribe(); this.dataManager.unbindRoom(); @@ -262,7 +274,7 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { resetColorsToTheme() { const param = new CloudParameters(); - param.resetToDefault(); + param.resetToDefault(this._currentTheme.isDark); this.setCloudParameters(param, true); } @@ -383,17 +395,22 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { customTagCloudStyles.id = 'tagCloudStyles'; document.head.appendChild(customTagCloudStyles); } + customTagCloudStyles.sheet.disabled = false; const rules = customTagCloudStyles.sheet.cssRules; for (let i = rules.length - 1; i >= 0; i--) { customTagCloudStyles.sheet.deleteRule(i); } let textTransform = ''; + let plainTextTransform = 'unset'; if (this._currentSettings.textTransform === CloudTextStyle.capitalized) { textTransform = 'text-transform: capitalize;'; + plainTextTransform = 'capitalize'; } else if (this._currentSettings.textTransform === CloudTextStyle.lowercase) { textTransform = 'text-transform: lowercase;'; + plainTextTransform = 'lowercase'; } else if (this._currentSettings.textTransform === CloudTextStyle.uppercase) { textTransform = 'text-transform: uppercase;'; + plainTextTransform = 'uppercase'; } customTagCloudStyles.sheet.insertRule('.spacyTagCloud > span, .spacyTagCloud > span > a { ' + textTransform + ' font-family: ' + this._currentSettings.fontFamily + '; ' + @@ -412,8 +429,22 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit { 'background-color: ' + this._currentSettings.backgroundColor + '; }'); customTagCloudStyles.sheet.insertRule('.spacyTagCloudContainer { ' + 'background-color: ' + this._currentSettings.backgroundColor + '; }'); + const invertedBackground = TagCloudComponent.invertHex(this._currentSettings.backgroundColor); customTagCloudStyles.sheet.insertRule(':root { ' + - '--tag-cloud-color: ' + this._currentSettings.fontColor + '; }'); + '--tag-cloud-inverted-background: ' + invertedBackground + ';' + + '--tag-cloud-transform: ' + plainTextTransform + ';' + + '--tag-cloud-background-color: ' + this._currentSettings.backgroundColor + ';' + + '--tag-cloud-font-weight: ' + this._currentSettings.fontWeight + ';' + + '--tag-cloud-font-style: ' + this._currentSettings.fontStyle + ';' + + '--tag-cloud-font-family: ' + this._currentSettings.fontFamily + '; }'); + customTagCloudStyles.sheet.insertRule('.header-icons { ' + + 'color: var(--tag-cloud-inverted-background) !important; }'); + customTagCloudStyles.sheet.insertRule('.header .oldtypo-h2, .header .oldtypo-h2 + span { ' + + 'color: var(--tag-cloud-inverted-background) !important; }'); + customTagCloudStyles.sheet.insertRule('#footer_rescale {' + + 'display: none; }'); + customTagCloudStyles.sheet.insertRule('div.main_container {' + + 'background-color: var(--tag-cloud-background-color) !important; }'); } /** diff --git a/src/app/utils/cloud-parameters.const.ts b/src/app/utils/cloud-parameters.const.ts new file mode 100644 index 0000000000000000000000000000000000000000..26b493c8efb59d8973b006bf28b5b7f82dd503a1 --- /dev/null +++ b/src/app/utils/cloud-parameters.const.ts @@ -0,0 +1,44 @@ +export interface DefaultCloudParameters { + w1: string; + w2: string; + w3: string; + w4: string; + w5: string; + w6: string; + w7: string; + w8: string; + w9: string; + w10: string; + backgroundColor: string; + hoverColor: string; +} + +export const LIGHT_THEME: DefaultCloudParameters = { + w1: 'dimgray', + w2: 'brown', + w3: 'olive', + w4: 'seagreen', + w5: 'teal', + w6: 'navy', + w7: 'green', + w8: 'salmon', + w9: 'darkorange', + w10: 'red', + backgroundColor: 'var(--background, moccasin)', + hoverColor: 'var(--black, black)' +}; + +export const DARK_THEME: DefaultCloudParameters = { + w1: 'dimgray', + w2: 'brown', + w3: 'olive', + w4: 'seagreen', + w5: 'teal', + w6: 'green', + w7: 'orange', + w8: 'magenta', + w9: 'greenyellow', + w10: 'red', + backgroundColor: 'var(--background, #121212)', + hoverColor: 'var(--white, white)' +}; diff --git a/src/app/utils/cloud-parameters.ts b/src/app/utils/cloud-parameters.ts index 54c2450001eb183f1b0cf934feb3ca05dcba053a..037e5263d27292e86961d8eedeec2d7438b66791 100644 --- a/src/app/utils/cloud-parameters.ts +++ b/src/app/utils/cloud-parameters.ts @@ -1,3 +1,6 @@ +import { themes } from '../../theme/arsnova-theme.const'; +import { DARK_THEME, DefaultCloudParameters, LIGHT_THEME } from './cloud-parameters.const'; + export interface CloudWeightSetting { maxVisibleElements: number; color: string; @@ -33,7 +36,7 @@ export class CloudParameters { const jsonData = localStorage.getItem('tagCloudConfiguration'); const temp = jsonData != null ? JSON.parse(jsonData) : null; const elem = new CloudParameters(); - elem.resetToDefault(); + elem.resetToDefault(this.isThemeDark()); if (temp != null) { for (const key of Object.keys(elem)) { if (temp[key] !== undefined) { @@ -99,7 +102,33 @@ export class CloudParameters { } } - resetToDefault() { + private static isThemeDark() { + const currentThemeName = localStorage.getItem('theme'); + for (const theme in themes) { + if (theme === currentThemeName) { + return themes[theme].isDark; + } + } + return false; + } + + private static resolveColor(element: HTMLParagraphElement, color: string): string { + element.style.backgroundColor = 'rgb(0, 0, 0)'; + element.style.backgroundColor = color; + const result = window.getComputedStyle(element).backgroundColor.match(colorRegex); + const r = parseInt(result[1], 10); + const g = parseInt(result[2], 10); + const b = parseInt(result[3], 10); + return `#${((r * 256 + g) * 256 + b).toString(16).padStart(6, '0')}`; + } + + private static mapValue(current: number, minInput: number, maxInput: number, minOut: number, maxOut: number) { + const value = (current - minInput) * (maxOut - minOut) / (maxInput - minInput) + minOut; + return Math.min(maxOut, Math.max(minOut, value)); + } + + resetToDefault(isDark: boolean) { + const theme: DefaultCloudParameters = isDark ? DARK_THEME : LIGHT_THEME; const p = document.createElement('p'); p.style.display = 'none'; document.body.appendChild(p); @@ -110,11 +139,11 @@ export class CloudParameters { this.fontStyle = 'normal'; this.fontWeight = 'normal'; this.fontSize = '10px'; - this.backgroundColor = this.resolveColor(p, 'var(--background, black)'); - this.fontColor = this.resolveColor(p, 'var(--secondary, greenyellow)'); - this.fontSizeMin = this.mapValue(minValue, 375, 750, 125, 200); - this.fontSizeMax = this.mapValue(minValue, 375, 1500, 300, 900); - this.hoverScale = this.mapValue(minValue, 375, 1500, 1.4, 2); + this.backgroundColor = CloudParameters.resolveColor(p, theme.backgroundColor); + this.fontColor = CloudParameters.resolveColor(p, theme.hoverColor); + this.fontSizeMin = CloudParameters.mapValue(minValue, 375, 750, 125, 200); + this.fontSizeMax = CloudParameters.mapValue(minValue, 375, 1500, 300, 900); + this.hoverScale = CloudParameters.mapValue(minValue, 375, 1500, 1.4, 2); this.hoverTime = 1; this.hoverDelay = 0.4; this.delayWord = 100; @@ -123,32 +152,67 @@ export class CloudParameters { this.question = ''; this.textTransform = CloudTextStyle.capitalized; this.cloudWeightSettings = [ - { maxVisibleElements: elements, color: '#C0C0C0', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#d98e49', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#ccca3c', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#83e761', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#3accd4', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#54a1e9', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#3a44ee', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#9725eb', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#e436c7', rotation: 0, allowManualTagNumber: true }, - { maxVisibleElements: elements, color: '#ff0000', rotation: 0, allowManualTagNumber: true }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w1), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w2), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w3), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w4), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w5), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w6), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w7), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w8), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w9), + rotation: 0, + allowManualTagNumber: isMobile + }, + { + maxVisibleElements: elements, + color: CloudParameters.resolveColor(p, theme.w10), + rotation: 0, + allowManualTagNumber: isMobile + }, ]; p.remove(); } - - private resolveColor(element: HTMLParagraphElement, color: string): string { - element.style.backgroundColor = 'rgb(0, 0, 0)'; - element.style.backgroundColor = color; - const result = window.getComputedStyle(element).backgroundColor.match(colorRegex); - const r = parseInt(result[1], 10); - const g = parseInt(result[2], 10); - const b = parseInt(result[3], 10); - return `#${((r * 256 + g) * 256 + b).toString(16).padStart(6, '0')}`; - } - - private mapValue(current: number, minInput: number, maxInput: number, minOut: number, maxOut: number) { - const value = (current - minInput) * (maxOut - minOut) / (maxInput - minInput) + minOut; - return Math.min(maxOut, Math.max(minOut, value)); - } } diff --git a/src/assets/i18n/creator/de.json b/src/assets/i18n/creator/de.json index 9387db05074e5d953f5c0444363a35a6e60f3559..a2cd85f4cc73ca804b4fe49c1bcd534abd71e3f5 100644 --- a/src/assets/i18n/creator/de.json +++ b/src/assets/i18n/creator/de.json @@ -80,7 +80,7 @@ "token-time": "Token-Zeitstempel", "no-comments": "Es sind noch keine Fragen vorhanden.", "export-comments": "Fragen speichern", - "questions-blocked": "Fragenstellen deaktiviert " + "questions-blocked": "Fragenstellen deaktiviert" }, "spacy-dialog": { "auto": "auto", diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json index 3d087320091641168da7daf1731375d286dbd438..2141e0bedfc5e253b53d4127a02930f79d45b3b2 100644 --- a/src/assets/i18n/participant/de.json +++ b/src/assets/i18n/participant/de.json @@ -375,5 +375,22 @@ "manual-weight-number": "Anzahl Themen beschränken", "manual-weight-number-tooltip": "Anzahl Themen der Häufigkeitsgruppe", "manual-weight-number-note": "Begrenzt die Anzahl Themen einer Häufigkeitsgruppe auf den eingestellten Wert" + }, + "user-bonus-token": { + "header": "Sterne für Bonuspunkte einlösen", + "no-bonus": "Du hast noch keinen Stern für eine gute Frage erhalten.", + "redeem-tokens": "Sterne per Mail einlösen", + "mail-subject": "Bitte%20um%20Einl%C3%B6sung%20meiner%20Tokens%20aus%20der%20%C2%BBfrag.jetzt%C2%AB-Sitzung%20%C2%BB", + "mail-body-1": "Hallo%2C%0D%0A%0D%0Aich%20habe%20heute%20in%20der%20%C2%BBfrag.jetzt%C2%AB-Sitzung%20%C2%BB", + "mail-body-2": "%C2%AB%20mit%20dem%20Raum-Code%20%C2%BB", + "mail-body-3": "%C2%AB%20die%20folgenden%20Tokens%20erhalten%3A%0D%0A%0D%0A", + "mail-body-4": "%0D%0A%0D%0AIch%20bitte%20um%20die%20Einl%C3%B6sung%20in%20Bonuspunkte.%0D%0A%0D%0ADanke%20f%C3%BCr%20%C2%BBfrag.jetzt%C2%AB!%0D%0A%0D%0A---", + "choose-session": "Wähle eine Sitzung aus", + "please-choose": "Bitte wähle zuerst eine Sitzung aus!" + }, + "introduction": { + "cancel": "Schließen", + "cancel-description": "Schließe die Einführung und gehe zurück zur Anmeldung.", + "title": "Einführung" } } diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json index 77191ab0c9201b221e4289007ba1e31198507eb8..2cdb66c5f8304fc0f71fda87418682f0167068fe 100644 --- a/src/assets/i18n/participant/en.json +++ b/src/assets/i18n/participant/en.json @@ -381,5 +381,22 @@ "manual-weight-number": "Set quantity", "manual-weight-number-tooltip": "Quantity Limitation of this weight class", "manual-weight-number-note": "Limits the respective weight class to a self-defined Quantity" + }, + "user-bonus-token": { + "header": "Redeem stars for bonus", + "no-bonus": "You haven't received a bonus star for a good question yet.", + "redeem-tokens": "Redeem stars by mail", + "mail-subject": "Request%20to%20redeem%20my%20tokens%20from%20the%20%C2%BBfrag.jetzt%C2%AB-session%20%C2%BB", + "mail-body-1": "Hello%2C%0D%0A%0D%0Ai%20have%20received%20the%20following%20tokens%20today%20in%20the%20%C2%BBfrag.jetzt%C2%AB-session%20%C2%BB", + "mail-body-2": "%C2%AB%20with%20the%20session%20code%20%C2%BB", + "mail-body-3": "%C2%AB%3A%0D%0A%0D%0A", + "mail-body-4": "%0D%0A%0D%0AI%20ask%20for%20the%20redemption%20in%20bonus%20points.%0D%0A%0D%0AThanks%20for%20%C2%BBfrag.jetzt%C2%AB!%0D%0A%0D%0A---", + "choose-session": "Choose a session", + "please-choose": "Please select a session first!" + }, + "introduction": { + "cancel": "Close", + "cancel-description": "Close introduction.", + "title": "Introduction" } }