From be2818aaaa26e6f086241e686ae553d65db90dd2 Mon Sep 17 00:00:00 2001
From: Lukas Haase <lukas.haase@mni.thm.de>
Date: Mon, 4 May 2020 15:40:33 +0200
Subject: [PATCH] Questionwall improve sort

---
 .../content/menu/ButtonWrapper.directive.ts   |  14 +-
 .../material-btn/material-btn.component.scss  |   5 +
 src/app/components/creator/creator.module.ts  |   4 +-
 .../question-wall.component.html              | 152 +++++++++++-------
 .../question-wall.component.scss              |  19 ++-
 .../question-wall/question-wall.component.ts  |  81 ++++++++--
 6 files changed, 199 insertions(+), 76 deletions(-)

diff --git a/projects/ars/src/lib/components/content/menu/ButtonWrapper.directive.ts b/projects/ars/src/lib/components/content/menu/ButtonWrapper.directive.ts
index e377f9918..d6cdd57cf 100644
--- a/projects/ars/src/lib/components/content/menu/ButtonWrapper.directive.ts
+++ b/projects/ars/src/lib/components/content/menu/ButtonWrapper.directive.ts
@@ -57,11 +57,15 @@ export class ButtonWrapperDirective implements OnInit, AfterViewInit {
     // init padding for each button
     if (this.ft.isCol()) {
       this.btn.forEach(e => e.setPadding(this.xs / 2, this.xe / 2, 0, 0));
-      if (this.extraStart) {
-        this.btn.first.setPaddingLeft(this.xs);
-      }
-      if (this.extraEnd) {
-        this.btn.last.setPaddingRight(this.xe);
+      if (this.extraStart && this.extraEnd && this.btn.length == 1) {
+        this.btn.first.setPadding(this.xs, this.xe, 0, 0);
+      } else {
+        if (this.extraStart) {
+          this.btn.first.setPaddingLeft(this.xs);
+        }
+        if (this.extraEnd) {
+          this.btn.last.setPaddingRight(this.xe);
+        }
       }
     } else {
       this.btn.forEach(e => e.setPadding(this.xs / 2, this.xe / 2, this.ys / 2, this.ye / 2));
diff --git a/projects/ars/src/lib/components/style/menu/material-btn/material-btn.component.scss b/projects/ars/src/lib/components/style/menu/material-btn/material-btn.component.scss
index 779e84f28..cc483305c 100644
--- a/projects/ars/src/lib/components/style/menu/material-btn/material-btn.component.scss
+++ b/projects/ars/src/lib/components/style/menu/material-btn/material-btn.component.scss
@@ -38,6 +38,11 @@
     font-weight:500;
     font-size:14px;
     line-height:14px;
+    color:var(--ars-button-color);
+  }
+
+  ars-row > button > *:nth-child(2){
+    float:right;
   }
 
   button > *:nth-child(2){
diff --git a/src/app/components/creator/creator.module.ts b/src/app/components/creator/creator.module.ts
index 1ec004568..10b0706bd 100644
--- a/src/app/components/creator/creator.module.ts
+++ b/src/app/components/creator/creator.module.ts
@@ -22,6 +22,7 @@ import { MarkdownModule } from 'ngx-markdown';
 import { DeleteAnswerComponent } from './_dialogs/delete-answer/delete-answer.component';
 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';
 
 @NgModule({
   imports: [
@@ -39,7 +40,8 @@ import { ArsModule } from '../../../../projects/ars/src/lib/ars.module';
       isolate: true
     }),
     MarkdownModule,
-    ArsModule
+    ArsModule,
+    MatRippleModule
   ],
   declarations: [
     RoomCreatorPageComponent,
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 c1850e961..3fb4cbe7a 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
@@ -3,7 +3,7 @@
     <ars-style-btn-material *ngIf="room" style="width:100%;height:100%;" ars-flex-box>
       <ars-fill ars-flex-box>
         <ars-col ars-btn-wrp [xp]="16" [yp]="0" [extra]="true">
-          <button ars-btn (click)="leave()"><i>arrow_back</i></button>
+          <button ars-btn (click)="leave()" matRipple><i>arrow_back</i></button>
         </ars-col>
       </ars-fill>
       <ars-col>
@@ -12,11 +12,28 @@
       <ars-fill ars-flex-box>
         <ars-fill></ars-fill>
         <ars-col ars-btn-wrp [xp]="16" [extra]="true">
-          <button ars-btn (click)="sortTime()"><p>{{'question-wall.sort-time' | translate}}</p><i>expand_less</i></button>
-          <button ars-btn (click)="sortTime(true)"><i>expand_more</i></button>
-          <button ars-btn (click)="sortScore()"><p>{{'question-wall.sort-score' | translate}}</p><i>expand_less</i></button>
-          <button ars-btn (click)="sortScore(true)"><i>expand_more</i></button>
-          <button ars-btn (click)="filterFavorites()"><i>star</i><p>{{'question-wall.filter-favorite' | translate}}</p></button>
+          <mat-menu #sortMenu>
+            <button mat-menu-item (click)="sortTime(true)">Newest</button>
+            <button mat-menu-item (click)="sortTime()">Oldest</button>
+            <button mat-menu-item (click)="sortScore(true)">Score</button>
+          </mat-menu>
+          <mat-menu #filterMenu>
+            <button mat-menu-item (click)="filterFavorites()">
+              <mat-icon>star</mat-icon>
+              <span>Favorite</span>
+            </button>
+            <button mat-menu-item (click)="filterFavorites()">
+              <mat-icon>check_circle</mat-icon>
+              <span>approved</span>
+            </button>
+            <button mat-menu-item (click)="filterFavorites()">
+              <mat-icon>block</mat-icon>
+              <span>disapproved</span>
+            </button>
+          </mat-menu>
+          <button ars-btn [mat-menu-trigger-for]="sortMenu" matRipple><i>sort</i><p>Sort</p></button>
+          <button ars-btn [mat-menu-trigger-for]="filterMenu" matRipple><i>filter_list</i><p>Filter</p></button>
+          <button ars-btn (click)="openUserMap()" matRipple><i>person</i><p>user</p></button>
         </ars-col>
       </ars-fill>
     </ars-style-btn-material>
@@ -46,65 +63,86 @@
       <ars-fill>
       </ars-fill>
     </ars-fill>
-    <ars-col [width]="450" [overflow]="'auto'" class="questionwall-list" #colComponent>
-      <ars-row *ngIf="hasFilter" class="questionwall-list-filter" [height]="45">
-        <ars-style-btn-material style="width:100%;height:100%;" ars-flex-box>
-          <ars-col ars-btn-wrp [xp]="48">
-            <button ars-btn><p>{{filterTitle | translate}} {{filterDesc}}</p></button>
-          </ars-col>
-          <ars-fill></ars-fill>
-          <ars-col ars-btn-wrp [xp]="48">
-            <button ars-btn (click)="deactivateFilter()"><i>remove_circle</i><p>remove filter</p></button>
-          </ars-col>
-        </ars-style-btn-material>
+    <ars-col ars-flex-box [width]="450" class="questionwall-list"  #colComponent>
+
+      <ars-row>
+        <ars-row *ngIf="hasFilter" class="questionwall-list-border-bottom" [height]="45">
+          <ars-style-btn-material style="width:100%;height:100%;" ars-flex-box>
+            <ars-col ars-btn-wrp [xp]="48">
+              <button ars-btn matRipple><i>{{filterIcon}}</i><p>{{filterTitle | translate}} {{filterDesc}}</p></button>
+            </ars-col>
+            <ars-fill></ars-fill>
+            <ars-col ars-btn-wrp [xp]="48">
+              <button ars-btn (click)="deactivateFilter()" matRipple><i>remove_circle</i><p>remove filter</p></button>
+            </ars-col>
+          </ars-style-btn-material>
+        </ars-row>
       </ars-row>
-      <ars-row *ngFor="let comment of hasFilter?commentsFilter:comments" class="questionwall-comment-anchor">
-        <ars-row style="box-sizing:border-box;padding:8px;">
-          <ars-row
-            [ngClass]="comment===commentFocus?'questionwall-comment-border-on':'questionwall-comment-border-off'"
-            style="border-radius:5px">
-            <ars-row ars-flex-box
-                     (click)="focusComment(comment)"
-                     style="box-sizing:border-box;padding:16px;cursor:pointer">
-              <ars-col class="questionwall-comment-meta">
-                <i class="questionwall-icon">person</i>
-                <p (click)="filterUser(comment);" class="questionwall-comment-user">{{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>
-              </ars-col>
-              <ars-col>
-<!--                <ars-style-btn-material>-->
-<!--                  <ars-col ars-btn-wrp [xp]="16" [extraStart]="true" class="questionwall-comment-btn">-->
-<!--                    <button ars-btn><i>{{comment.comment.favorite?'star':'star_border'}}</i></button>-->
-<!--                  </ars-col>-->
-<!--                </ars-style-btn-material>-->
-              </ars-col>
+
+      <ars-fill class="questionwall-list-comments">
+
+        <ars-row *ngIf="!userSelection">
+
+          <ars-row *ngFor="let comment of hasFilter?commentsFilter:comments" class="questionwall-comment-anchor" style="float:left;">
+            <ars-row style="box-sizing:border-box;padding:8px;">
+              <ars-row
+                [ngClass]="comment===commentFocus?'questionwall-comment-border-on':'questionwall-comment-border-off'"
+                style="border-radius:5px">
+                <ars-row ars-flex-box
+                         (click)="focusComment(comment)"
+                         style="box-sizing:border-box;padding:16px;cursor:pointer">
+                  <ars-col class="questionwall-comment-meta">
+                    <i class="questionwall-icon">person</i>
+                    <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>
+                  </ars-col>
+                </ars-row>
+                <ars-row
+                  (click)="focusComment(comment)"
+                  style="box-sizing:border-box;padding:0 16px;cursor:pointer">
+                  <p class="questionwall-comment-body">{{comment.comment.body}}</p>
+                </ars-row>
+                <ars-row [height]="50">
+                  <ars-style-btn-material style="width:100%;height:100%;" ars-flex-box>
+                    <ars-col ars-btn-wrp [xp]="16" [extra]="true" class="questionwall-comment-btn">
+                      <button ars-btn (click)="likeComment(comment)" matRipple><i>thumb_up</i><p>{{comment.comment.score}}</p></button>
+                      <button ars-btn (click)="dislikeComment(comment)" matRipple><i>thumb_down</i></button>
+                    </ars-col>
+                    <ars-fill (click)="focusComment(comment)" style="cursor:pointer"></ars-fill>
+                  </ars-style-btn-material>
+                </ars-row>
+              </ars-row>
             </ars-row>
-            <ars-row
-              (click)="focusComment(comment)"
-              style="box-sizing:border-box;padding:0 16px;cursor:pointer">
-              <p class="questionwall-comment-body">{{comment.comment.body}}</p>
+          </ars-row>
+
+        </ars-row>
+
+        <ars-row *ngIf="userSelection">
+          <ars-style-btn-material style="width:100%">
+            <ars-row [height]="50" ars-flex-box class="questionwall-list-border-bottom">
+              <ars-col ars-btn-wrp [xp]="24" [extra]="true">
+                <button ars-btn (click)="cancelUserMap()" matRipple><i>arrow_back</i></button>
+              </ars-col>
             </ars-row>
-            <ars-row [height]="50">
-              <ars-style-btn-material style="width:100%;height:100%;" ars-flex-box>
-                <ars-col ars-btn-wrp [xp]="16" [extra]="true" class="questionwall-comment-btn">
-                  <button ars-btn (click)="likeComment(comment)"><i>thumb_up</i><p>{{comment.comment.score}}</p></button>
-                  <button ars-btn (click)="dislikeComment(comment)"><i>thumb_down</i></button>
-                </ars-col>
-                <ars-fill (click)="focusComment(comment)" style="cursor:pointer"></ars-fill>
-              </ars-style-btn-material>
+            <ars-row ars-btn-wrp [xp]="48" [yp]="32">
+              <button ars-btn mat-ripple *ngFor="let user of userList" (click)="applyUserMap(user[1])">
+                <p>{{user[1]}}</p><p>{{user[0]}}</p>
+              </button>
             </ars-row>
-          </ars-row>
+          </ars-style-btn-material>
         </ars-row>
-      </ars-row>
+
+      </ars-fill>
+
     </ars-col>
   </ars-fill>
     <ars-row [height]="50" class="questionwall-footer">
       <ars-style-btn-material style="width:100%;" ars-flex-box>
         <ars-col ars-btn-wrp [xp]="16" [extra]="true">
-          <button ars-btn (click)="toggleFocusIncommingComments()">
+          <button ars-btn (click)="toggleFocusIncommingComments()" matRipple>
             <ng-container *ngIf="focusIncommingComments">
               <i>{{'question-wall.auto-renew-off-icon' | translate}}</i>
               <p>{{'question-wall.auto-renew-off' | translate}}</p>
@@ -120,11 +158,11 @@
           <p *ngIf="unreadComments" style="line-height:18px;" class="questionwall-text-color">{{unreadComments}}</p>
         </ars-col>
         <ars-col ars-btn-wrp [xp]="16" [extra]="true">
-          <button ars-btn (click)="prevComment()">
+          <button ars-btn (click)="prevComment()" matRipple>
             <i>{{'question-wall.prev-comment-icon' | translate}}</i>
             <p>{{'question-wall.prev-comment' | translate}}</p>
           </button>
-          <button ars-btn (click)="nextComment()">
+          <button ars-btn (click)="nextComment()" matRipple>
             <i>{{'question-wall.next-comment-icon' | translate}}</i>
             <p>{{'question-wall.next-comment' | translate}}</p>
           </button>
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 67e0dae7e..864b6ca85 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
@@ -5,6 +5,12 @@
     margin:0;
   }
 
+  .test{
+    width:100%;
+    height:250px;
+    box-shadow:inset 0 0 0 1px black;
+  }
+
   .questionwall{
     &-icon{
       font-family:'Material Icons', serif;
@@ -81,12 +87,23 @@
     }
     &-list{
       box-sizing:border-box;
-      padding:16px 0px;
       border-left:solid 1px var(--ars-border-color);
       &-filter{
         border-top:solid 1px var(--ars-border-color);
         border-bottom:solid 1px var(--ars-border-color);
       }
+      &-border-bottom{
+        border-bottom:solid 1px var(--ars-border-color);
+      }
+      &-comments{
+      }
+      &-scroll{
+        width:100%;
+        height:100%;
+        display:flex;
+        flex-direction:column;
+        background-color:orange;
+      }
     }
     &-present{
       font-size:45px;
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 0fc83046e..39d77a44f 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
@@ -1,5 +1,4 @@
 import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
-import { StyleDebug } from '../../../../../../projects/ars/src/lib/models/debug/StyleDebug';
 import { CommentService } from '../../../../services/http/comment.service';
 import { Comment } from '../../../../models/comment';
 import { RoomService } from '../../../../services/http/room.service';
@@ -13,6 +12,7 @@ import { LanguageService } from '../../../../services/util/language.service';
 import { TranslateService } from '@ngx-translate/core';
 import { Rescale } from '../../../../models/rescale';
 import { QuestionWallKeyEventSupport } from '../QuestionWallKeyEventSupport';
+import { CorrectWrong } from '../../../../models/correct-wrong.enum';
 
 @Component({
   selector: 'app-question-wall',
@@ -33,8 +33,12 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy {
   timeUpdateInterval;
   keySupport: QuestionWallKeyEventSupport;
   hasFilter = false;
-  filterTitle = 'Test';
-  filterDesc = 'test';
+  filterTitle = '';
+  filterDesc = '';
+  filterIcon = '';
+  userMap: Map<number, number> = new Map<number, number>();
+  userList = [];
+  userSelection = false;
 
   public wrap<E>(e: E, action: (e: E) => void) {
     action(e);
@@ -69,7 +73,7 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy {
     QuestionWallComment.updateTimeFormat(localStorage.getItem('currentLang'));
     this.translateService.use(localStorage.getItem('currentLang'));
     this.commentService.getAckComments(this.roomId).subscribe(e => {
-      e.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
+      e.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
       e.forEach(c => {
         const comment = new QuestionWallComment(c, true);
         this.comments.push(comment);
@@ -175,6 +179,34 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy {
     this.focusIncommingComments = !this.focusIncommingComments;
   }
 
+  createUserMap() {
+    this.userMap = new Map();
+    this.comments.forEach(c => {
+      if (!this.userMap.has(c.comment.userNumber)) {
+        this.userMap.set(c.comment.userNumber, 0);
+      }
+      this.userMap.set(c.comment.userNumber, this.userMap.get(c.comment.userNumber) + 1);
+    });
+    this.userList = [];
+    this.userMap.forEach((num, user) => {
+      this.userList.push([num, user]);
+    });
+  }
+
+  applyUserMap(user: number) {
+    this.userSelection = false;
+    this.filterUserByNumber(user);
+  }
+
+  openUserMap() {
+    this.createUserMap();
+    this.userSelection = true;
+  }
+
+  cancelUserMap() {
+    this.userSelection = false;
+  }
+
   leave() {
     document.getElementById('back-button').click();
   }
@@ -204,7 +236,7 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy {
     }
     setTimeout(() => {
       if (commentList.length > 1) {
-        this.focusComment(commentList[commentList.length - 1]);
+        this.focusComment(commentList[0]);
       }
     }, 0);
   }
@@ -222,17 +254,42 @@ export class QuestionWallComponent implements OnInit, AfterViewInit, OnDestroy {
   }
 
   filterFavorites() {
-    this.filterTitle = 'question-wall.filter-favorite';
-    this.filterDesc = '';
-    this.commentsFilter = this.comments.filter(x => x.comment.favorite);
-    this.hasFilter = true;
+    this.filter('star', 'question-wall.filter-favorite', '',
+        x => x.comment.favorite);
   }
 
   filterUser(comment: QuestionWallComment) {
-    this.filterTitle = 'question-wall.filter-user';
-    this.filterDesc = comment.comment.userNumber + '';
-    this.commentsFilter = this.comments.filter(x => x.comment.userNumber === comment.comment.userNumber);
+    this.filterUserByNumber(comment.comment.userNumber);
+  }
+
+  filterUserByNumber(user: number) {
+    this.filter('person', 'question-wall.filter-user', user + '',
+      x => x.comment.userNumber === user);
+  }
+
+  filterApproved() {
+    this.filter('check_circle', 'question-wall.filter-disapproved', '',
+        x => x.comment.correct === CorrectWrong.CORRECT);
+  }
+
+  filterDisapproved() {
+    this.filter('block', 'question-wall.filter-disapproved', '',
+        x => x.comment.correct === CorrectWrong.WRONG);
+  }
+
+  filter(icon: string, title: string, desc: string, filter: (x: QuestionWallComment) => boolean) {
+    this.filterIcon = icon;
+    this.filterTitle = title;
+    this.filterDesc = desc;
+    this.commentsFilter = this.comments.filter(filter);
     this.hasFilter = true;
+    setTimeout(() => this.focusFirstComment(), 0);
+  }
+
+  focusFirstComment() {
+    if (this.getCurrentCommentList().length > 0) {
+      this.commentFocus = this.getCurrentCommentList()[0];
+    }
   }
 
   deactivateFilter() {
-- 
GitLab