forked from EVOgeek/Vmeda.Online
		
	MOBILE-1486 user: Show status indicator on user avatar
This commit is contained in:
		
							parent
							
								
									bb3a525a5b
								
							
						
					
					
						commit
						5e4e4fc75f
					
				| @ -28,12 +28,7 @@ | |||||||
|         <h3 margin-horizontal *ngIf="competencies && competencies.statistics.competencycount > 0">{{ 'addon.competency.competencies' | translate }}</h3> |         <h3 margin-horizontal *ngIf="competencies && competencies.statistics.competencycount > 0">{{ 'addon.competency.competencies' | translate }}</h3> | ||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|              <ion-item text-wrap> |              <ion-item text-wrap> | ||||||
|                 <ion-avatar *ngIf="user.profileimageurl && user.profileimageurl !== true" item-start> |                 <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|                     <img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <span *ngIf="user.profileimageurl === true" item-start> |  | ||||||
|                     <ion-icon name="person"></ion-icon> |  | ||||||
|                 </span> |  | ||||||
|                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
|  | |||||||
| @ -10,12 +10,7 @@ | |||||||
|     <core-loading [hideUntil]="competencyLoaded"> |     <core-loading [hideUntil]="competencyLoaded"> | ||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar *ngIf="user.profileimageurl && user.profileimageurl !== true" item-start> |                 <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|                     <img  [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <span *ngIf="user.profileimageurl === true" item-start> |  | ||||||
|                     <ion-icon name="person"></ion-icon> |  | ||||||
|                 </span> |  | ||||||
|                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
| @ -78,9 +73,7 @@ | |||||||
|             </p> |             </p> | ||||||
|             <ion-card *ngFor="let evidence of competency.evidence"> |             <ion-card *ngFor="let evidence of competency.evidence"> | ||||||
|                 <a ion-item text-wrap *ngIf="evidence.actionuser" (click)="openUserProfile(evidence.actionuser.id)"> |                 <a ion-item text-wrap *ngIf="evidence.actionuser" (click)="openUserProfile(evidence.actionuser.id)"> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="evidence.actionuser" item-start></ion-avatar> | ||||||
|                         <img core-external-content [src]="evidence.actionuser.profileimageurlsmall" [alt]="'core.pictureof' | translate:{$a: evidence.actionuser.fullname}" role="presentation"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2>{{ evidence.actionuser.fullname }}</h2> |                     <h2>{{ evidence.actionuser.fullname }}</h2> | ||||||
|                     <p>{{ evidence.timemodified | coreToLocaleString }}</p> |                     <p>{{ evidence.timemodified | coreToLocaleString }}</p> | ||||||
|                 </a> |                 </a> | ||||||
|  | |||||||
| @ -10,12 +10,7 @@ | |||||||
|     <core-loading [hideUntil]="planLoaded"> |     <core-loading [hideUntil]="planLoaded"> | ||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar *ngIf="user.profileimageurl && user.profileimageurl !== true" item-start> |                 <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|                     <img  [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <span *ngIf="user.profileimageurl === true" item-start> |  | ||||||
|                     <ion-icon name="person"></ion-icon> |  | ||||||
|                 </span> |  | ||||||
|                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|        </ion-card> |        </ion-card> | ||||||
|  | |||||||
| @ -19,9 +19,7 @@ | |||||||
|                 <ng-container *ngFor="let contact of contacts[contactType]"> |                 <ng-container *ngFor="let contact of contacts[contactType]"> | ||||||
|                     <!-- Don't show deleted users --> |                     <!-- Don't show deleted users --> | ||||||
|                     <a ion-item text-wrap *ngIf="contact.profileimageurl || contact.profileimageurlsmall"  [title]="contact.fullname" (click)="gotoDiscussion(contact.id)" [class.core-split-item-selected]="contact.id == discussionUserId" detail-none> |                     <a ion-item text-wrap *ngIf="contact.profileimageurl || contact.profileimageurlsmall"  [title]="contact.fullname" (click)="gotoDiscussion(contact.id)" [class.core-split-item-selected]="contact.id == discussionUserId" detail-none> | ||||||
|                         <ion-avatar item-start> |                         <ion-avatar class="user-avatar" [user]="contact" item-start></ion-avatar> | ||||||
|                             <img src="{{contact.profileimageurl || contact.profileimageurlsmall}}" [alt]="'core.pictureof' | translate:{$a: contact.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                         </ion-avatar> |  | ||||||
|                         <h2><core-format-text [text]="contact.fullname"></core-format-text></h2> |                         <h2><core-format-text [text]="contact.fullname"></core-format-text></h2> | ||||||
|                     </a> |                     </a> | ||||||
|                 </ng-container> |                 </ng-container> | ||||||
|  | |||||||
| @ -17,9 +17,7 @@ | |||||||
|                 <ion-note item-end>{{ search.results.length }}</ion-note> |                 <ion-note item-end>{{ search.results.length }}</ion-note> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <a ion-item text-wrap *ngFor="let result of search.results" [title]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" [class.core-split-item-selected]="result.userid == discussionUserId" detail-none> |             <a ion-item text-wrap *ngFor="let result of search.results" [title]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" [class.core-split-item-selected]="result.userid == discussionUserId" detail-none> | ||||||
|                 <ion-avatar item-start> |                 <ion-avatar class="user-avatar" [user]="result" item-start></ion-avatar> | ||||||
|                     <img src="{{result.profileimageurl}}" [alt]="'core.pictureof' | translate:{$a: result.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2><core-format-text [text]="result.fullname"></core-format-text></h2> |                 <h2><core-format-text [text]="result.fullname"></core-format-text></h2> | ||||||
|                 <p><core-format-text clean="true" singleLine="true" [text]="result.lastmessage"></core-format-text></p> |                 <p><core-format-text clean="true" singleLine="true" [text]="result.lastmessage"></core-format-text></p> | ||||||
|             </a> |             </a> | ||||||
| @ -27,9 +25,7 @@ | |||||||
| 
 | 
 | ||||||
|         <ion-list *ngIf="!search.showResults" no-margin> |         <ion-list *ngIf="!search.showResults" no-margin> | ||||||
|             <a ion-item text-wrap *ngFor="let discussion of discussions" [title]="discussion.fullname" (click)="gotoDiscussion(discussion.message.user)" [class.core-split-item-selected]="discussion.message.user == discussionUserId" detail-none> |             <a ion-item text-wrap *ngFor="let discussion of discussions" [title]="discussion.fullname" (click)="gotoDiscussion(discussion.message.user)" [class.core-split-item-selected]="discussion.message.user == discussionUserId" detail-none> | ||||||
|                 <ion-avatar item-start> |                 <ion-avatar class="user-avatar" [user]="discussion" item-start></ion-avatar> | ||||||
|                     <img src="{{discussion.profileimageurl}}" [alt]="'core.pictureof' | translate:{$a: discussion.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2> |                 <h2> | ||||||
|                     <core-format-text [text]="discussion.fullname"></core-format-text> |                     <core-format-text [text]="discussion.fullname"></core-format-text> | ||||||
|                     <ion-note *ngIf="discussion.message.timecreated > 0 || discussion.unread"> |                     <ion-note *ngIf="discussion.message.timecreated > 0 || discussion.unread"> | ||||||
|  | |||||||
| @ -2,9 +2,7 @@ | |||||||
| 
 | 
 | ||||||
|     <!-- User and status of the submission. --> |     <!-- User and status of the submission. --> | ||||||
|     <a ion-item text-wrap *ngIf="!blindMarking && user" (click)="openUserProfile(submitId)" [title]="user.fullname"> |     <a ion-item text-wrap *ngIf="!blindMarking && user" (click)="openUserProfile(submitId)" [title]="user.fullname"> | ||||||
|         <ion-avatar item-start> |         <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|             <img [src]="user.profileimageurl" core-external-content [alt]="'core.pictureof' | translate:{$a: user.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|         </ion-avatar> |  | ||||||
|         <h2>{{ user.fullname }}</h2> |         <h2>{{ user.fullname }}</h2> | ||||||
|         <ng-container *ngTemplateOutlet="submissionStatus"></ng-container> |         <ng-container *ngTemplateOutlet="submissionStatus"></ng-container> | ||||||
|     </a> |     </a> | ||||||
| @ -113,9 +111,7 @@ | |||||||
|                     <h2>{{ 'addon.mod_assign.userswhoneedtosubmit' | translate: {$a: ''} }}</h2> |                     <h2>{{ 'addon.mod_assign.userswhoneedtosubmit' | translate: {$a: ''} }}</h2> | ||||||
|                     <div *ngFor="let user of membersToSubmit"> |                     <div *ngFor="let user of membersToSubmit"> | ||||||
|                         <a ion-item text-wrap *ngIf="user.fullname" (click)="openUserProfile(user.id)" [title]="user.fullname"> |                         <a ion-item text-wrap *ngIf="user.fullname" (click)="openUserProfile(user.id)" [title]="user.fullname"> | ||||||
|                             <ion-avatar item-start> |                             <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|                                 <img [src]="user.profileimageurl" core-external-content [alt]="'core.pictureof' | translate:{$a: user.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                             </ion-avatar> |  | ||||||
|                             <h2>{{ user.fullname }}</h2> |                             <h2>{{ user.fullname }}</h2> | ||||||
|                         </a> |                         </a> | ||||||
|                         <ion-item text-wrap *ngIf="!user.fullname"> |                         <ion-item text-wrap *ngIf="!user.fullname"> | ||||||
| @ -213,9 +209,7 @@ | |||||||
| 
 | 
 | ||||||
|                 <!-- Data about the grader (teacher who graded). --> |                 <!-- Data about the grader (teacher who graded). --> | ||||||
|                 <a ion-item text-wrap *ngIf="grader" (click)="openUserProfile(grader.id)" [title]="grader.fullname" detail-push> |                 <a ion-item text-wrap *ngIf="grader" (click)="openUserProfile(grader.id)" [title]="grader.fullname" detail-push> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="grader" item-start></ion-avatar> | ||||||
|                         <img [src]="grader.profileimageurl" core-external-content [alt]="'core.pictureof' | translate:{$a: grader.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2>{{ 'addon.mod_assign.gradedby' | translate }}</h2> |                     <h2>{{ 'addon.mod_assign.gradedby' | translate }}</h2> | ||||||
|                     <h2>{{ grader.fullname }}</h2> |                     <h2>{{ grader.fullname }}</h2> | ||||||
|                     <p *ngIf="feedback.gradeddate">{{ feedback.gradeddate * 1000 | coreFormatDate:"dfmediumdate" }}</p> |                     <p *ngIf="feedback.gradeddate">{{ feedback.gradeddate * 1000 | coreFormatDate:"dfmediumdate" }}</p> | ||||||
|  | |||||||
| @ -18,9 +18,7 @@ | |||||||
|                 <!-- List of submissions. --> |                 <!-- List of submissions. --> | ||||||
|                 <ng-container *ngFor="let submission of submissions"> |                 <ng-container *ngFor="let submission of submissions"> | ||||||
|                     <a ion-item text-wrap (click)="loadSubmission(submission)" [class.core-split-item-selected]="submission.id == selectedSubmissionId"> |                     <a ion-item text-wrap (click)="loadSubmission(submission)" [class.core-split-item-selected]="submission.id == selectedSubmissionId"> | ||||||
|                         <ion-avatar item-start *ngIf="submission.userprofileimageurl"> |                         <ion-avatar class="user-avatar" [user]="submission" item-start></ion-avatar> | ||||||
|                             <img [src]="submission.userprofileimageurl" [alt]="'core.pictureof' | translate:{$a: submission.userfullname}" core-external-content role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                         </ion-avatar> |  | ||||||
|                         <h2 *ngIf="submission.userfullname">{{submission.userfullname}}</h2> |                         <h2 *ngIf="submission.userfullname">{{submission.userfullname}}</h2> | ||||||
|                         <h2 *ngIf="!submission.userfullname">{{ 'addon.mod_assign.hiddenuser' | translate }}{{submission.blindid}}</h2> |                         <h2 *ngIf="!submission.userfullname">{{ 'addon.mod_assign.hiddenuser' | translate }}{{submission.blindid}}</h2> | ||||||
|                         <p *ngIf="assign.teamsubmission"> |                         <p *ngIf="assign.teamsubmission"> | ||||||
|  | |||||||
| @ -38,9 +38,7 @@ | |||||||
|                 </div> |                 </div> | ||||||
| 
 | 
 | ||||||
|                 <ion-item text-wrap *ngIf="!message.system && message.message.substr(0, 4) != 'beep'" class="addon-mod-chat-message"> |                 <ion-item text-wrap *ngIf="!message.system && message.message.substr(0, 4) != 'beep'" class="addon-mod-chat-message"> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="message" item-start></ion-avatar> | ||||||
|                         <img [src]="message.userprofileimageurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: message.userfullname}" role="presentation"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2> |                     <h2> | ||||||
|                         <p float-end>{{ message.timestamp * 1000 | coreFormatDate:"dftimedate" }}</p> |                         <p float-end>{{ message.timestamp * 1000 | coreFormatDate:"dftimedate" }}</p> | ||||||
|                         <core-format-text [text]="message.userfullname"></core-format-text> |                         <core-format-text [text]="message.userfullname"></core-format-text> | ||||||
|  | |||||||
| @ -11,9 +11,7 @@ | |||||||
| <ion-content> | <ion-content> | ||||||
|     <core-loading [hideUntil]="usersLoaded"> |     <core-loading [hideUntil]="usersLoaded"> | ||||||
|         <ion-item text-wrap *ngFor="let user of users" [class.addon-mod-chat-user]="currentUserId != user.id && isOnline"> |         <ion-item text-wrap *ngFor="let user of users" [class.addon-mod-chat-user]="currentUserId != user.id && isOnline"> | ||||||
|             <ion-avatar item-start> |             <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|                 <img [src]="user.profileimageurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: user.fullname}" role="presentation"> |  | ||||||
|             </ion-avatar> |  | ||||||
|             <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |             <h2><core-format-text [text]="user.fullname"></core-format-text></h2> | ||||||
|             <ng-container *ngIf="currentUserId != user.id && isOnline"> |             <ng-container *ngIf="currentUserId != user.id && isOnline"> | ||||||
|                 <button ion-button clear icon-left (click)="talkTo(user)"> |                 <button ion-button clear icon-left (click)="talkTo(user)"> | ||||||
|  | |||||||
| @ -82,9 +82,7 @@ | |||||||
|                             <p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamount} }})</p> |                             <p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamount} }})</p> | ||||||
|                         </ion-item-divider> |                         </ion-item-divider> | ||||||
|                         <a ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseid" [userId]="user.userid" [title]="user.fullname" text-wrap> |                         <a ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseid" [userId]="user.userid" [title]="user.fullname" text-wrap> | ||||||
|                             <ion-avatar item-start> |                             <ion-avatar class="user-avatar" [user]="user" item-start [courseId]="courseid"></ion-avatar> | ||||||
|                                 <img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                             </ion-avatar> |  | ||||||
|                             <p>{{user.fullname}}</p> |                             <p>{{user.fullname}}</p> | ||||||
|                         </a> |                         </a> | ||||||
|                     </ion-item-group> |                     </ion-item-group> | ||||||
|  | |||||||
| @ -6,10 +6,8 @@ | |||||||
| <ion-content> | <ion-content> | ||||||
|     <core-loading [hideUntil]="feedbackLoaded"> |     <core-loading [hideUntil]="feedbackLoaded"> | ||||||
|         <ion-list no-margin> |         <ion-list no-margin> | ||||||
|             <a *ngIf="attempt.fullname" ion-item text-wrap core-user-link [userId]="attempt.userid" [attr.aria-label]=" 'core.user.viewprofile' | translate" core-user-link [courseId]="attempt.courseid" [title]="attempt.fullname"> |             <a *ngIf="attempt.fullname" ion-item text-wrap core-user-link [userId]="attempt.userid" [attr.aria-label]=" 'core.user.viewprofile' | translate" [courseId]="attempt.courseid" [title]="attempt.fullname"> | ||||||
|                 <ion-avatar item-start> |                 <ion-avatar class="user-avatar" [user]="attempt" item-start></ion-avatar> | ||||||
|                     <img [src]="attempt.profileimageurl" [alt]="'core.pictureof' | translate:{$a: attempt.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2>{{attempt.fullname}}</h2> |                 <h2>{{attempt.fullname}}</h2> | ||||||
|                 <p *ngIf="attempt.timemodified">{{attempt.timemodified * 1000 | coreFormatDate:"LLL"}}</p> |                 <p *ngIf="attempt.timemodified">{{attempt.timemodified * 1000 | coreFormatDate:"LLL"}}</p> | ||||||
|             </a> |             </a> | ||||||
|  | |||||||
| @ -21,9 +21,7 @@ | |||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ng-container *ngIf="total > 0"> |             <ng-container *ngIf="total > 0"> | ||||||
|                 <ion-item *ngFor="let user of users" text-wrap> |                 <ion-item *ngFor="let user of users" text-wrap> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar> | ||||||
|                         <img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                     <h2><core-format-text [text]="user.fullname"></core-format-text></h2> | ||||||
|                     <p> |                     <p> | ||||||
|                         <ion-badge color="success" *ngIf="user.started"> |                         <ion-badge color="success" *ngIf="user.started"> | ||||||
|  | |||||||
| @ -22,9 +22,7 @@ | |||||||
|                         {{ 'addon.mod_feedback.non_anonymous_entries' | translate : {$a: responses.total } }} |                         {{ 'addon.mod_feedback.non_anonymous_entries' | translate : {$a: responses.total } }} | ||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
|                     <a *ngFor="let attempt of responses.attempts" ion-item text-wrap (click)="gotoAttempt(attempt)" [class.core-split-item-selected]="attempt.id == attemptId"> |                     <a *ngFor="let attempt of responses.attempts" ion-item text-wrap (click)="gotoAttempt(attempt)" [class.core-split-item-selected]="attempt.id == attemptId"> | ||||||
|                         <ion-avatar item-start> |                         <ion-avatar class="user-avatar" [user]="attempt" item-start></ion-avatar> | ||||||
|                             <img [src]="attempt.profileimageurl" [alt]="'core.pictureof' | translate:{$a: attempt.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                         </ion-avatar> |  | ||||||
|                         <h2><core-format-text [text]="attempt.fullname"></core-format-text></h2> |                         <h2><core-format-text [text]="attempt.fullname"></core-format-text></h2> | ||||||
|                         <p *ngIf="attempt.timemodified">{{attempt.timemodified * 1000 | coreFormatDate: "LLL"}}</p> |                         <p *ngIf="attempt.timemodified">{{attempt.timemodified * 1000 | coreFormatDate: "LLL"}}</p> | ||||||
|                     </a> |                     </a> | ||||||
|  | |||||||
| @ -27,9 +27,7 @@ | |||||||
|             <ng-container *ngIf="forum && discussions.length > 0"> |             <ng-container *ngIf="forum && discussions.length > 0"> | ||||||
|                 <ion-card *ngFor="let discussion of offlineDiscussions" (click)="openNewDiscussion(discussion.timecreated)" [class.addon-forum-discussion-selected]="discussion.timecreated == -selectedDiscussion"> |                 <ion-card *ngFor="let discussion of offlineDiscussions" (click)="openNewDiscussion(discussion.timecreated)" [class.addon-forum-discussion-selected]="discussion.timecreated == -selectedDiscussion"> | ||||||
|                     <ion-item text-wrap> |                     <ion-item text-wrap> | ||||||
|                         <ion-avatar item-start core-user-link [userId]="discussion.userid" [courseId]="courseId"> |                         <ion-avatar class="user-avatar" [user]="discussion" item-start [courseId]="courseId"></ion-avatar> | ||||||
|                             <img [src]="discussion.userpictureurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: discussion.userfullname}" role="presentation"> |  | ||||||
|                         </ion-avatar> |  | ||||||
|                         <h2><core-format-text [text]="discussion.subject"></core-format-text></h2> |                         <h2><core-format-text [text]="discussion.subject"></core-format-text></h2> | ||||||
|                         <p *ngIf="discussion.userfullname"> |                         <p *ngIf="discussion.userfullname"> | ||||||
|                             <ion-note float-end padding-left><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note> |                             <ion-note float-end padding-left><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note> | ||||||
| @ -45,9 +43,7 @@ | |||||||
|                 </ion-card> |                 </ion-card> | ||||||
|                 <ion-card *ngFor="let discussion of discussions" (click)="openDiscussion(discussion)" [class.addon-forum-discussion-selected]="discussion.discussion == selectedDiscussion"> |                 <ion-card *ngFor="let discussion of discussions" (click)="openDiscussion(discussion)" [class.addon-forum-discussion-selected]="discussion.discussion == selectedDiscussion"> | ||||||
|                     <ion-item text-wrap> |                     <ion-item text-wrap> | ||||||
|                         <ion-avatar item-start core-user-link [userId]="discussion.userid" [courseId]="courseId"> |                         <ion-avatar class="user-avatar" [user]="discussion" item-start [courseId]="courseId"></ion-avatar> | ||||||
|                             <img [src]="discussion.userpictureurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: discussion.userfullname}" role="presentation"> |  | ||||||
|                         </ion-avatar> |  | ||||||
|                         <h2><core-icon name="fa-map-pin" *ngIf="discussion.pinned"></core-icon> <core-format-text [text]="discussion.subject"></core-format-text></h2> |                         <h2><core-icon name="fa-map-pin" *ngIf="discussion.pinned"></core-icon> <core-format-text [text]="discussion.subject"></core-format-text></h2> | ||||||
|                         <p> |                         <p> | ||||||
|                             <ion-note float-end padding-left text-end> |                             <ion-note float-end padding-left text-end> | ||||||
|  | |||||||
| @ -1,8 +1,6 @@ | |||||||
| <ion-card-header text-wrap no-padding > | <ion-card-header text-wrap no-padding > | ||||||
|     <ion-item text-wrap> |     <ion-item text-wrap> | ||||||
|         <ion-avatar item-start (click)="openUserProfile(post.userid)"> |         <ion-avatar class="user-avatar" [user]="post" item-start (click)="openUserProfile(post.userid)"></ion-avatar> | ||||||
|             <img [src]="post.userpictureurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: post.userfullname}" role="presentation"> |  | ||||||
|         </ion-avatar> |  | ||||||
|         <h2><span [class.core-bold]="post.parent == 0"><core-format-text [text]="post.subject"></core-format-text></span></h2> |         <h2><span [class.core-bold]="post.parent == 0"><core-format-text [text]="post.subject"></core-format-text></span></h2> | ||||||
|         <p> |         <p> | ||||||
|             <ion-note float-end padding-left *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note> |             <ion-note float-end padding-left *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note> | ||||||
|  | |||||||
| @ -11,9 +11,7 @@ | |||||||
|     <core-loading [hideUntil]="loaded"> |     <core-loading [hideUntil]="loaded"> | ||||||
|         <ng-container *ngIf="entry"> |         <ng-container *ngIf="entry"> | ||||||
|             <ion-item text-wrap *ngIf="showAuthor"> |             <ion-item text-wrap *ngIf="showAuthor"> | ||||||
|                 <ion-avatar item-start (click)="openUserProfile(post.userid)"> |                 <ion-avatar class="user-avatar" [user]="entry" (click)="openUserProfile(post.userid)" item-start></ion-avatar> | ||||||
|                     <img [src]="entry.userpictureurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: entry.userfullname}" role="presentation"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2><core-format-text [text]="entry.concept"></core-format-text></h2> |                 <h2><core-format-text [text]="entry.concept"></core-format-text></h2> | ||||||
|                 <ion-note item-end *ngIf="showDate">{{ entry.timemodified | coreDateDayOrTime }}</ion-note> |                 <ion-note item-end *ngIf="showDate">{{ entry.timemodified | coreDateDayOrTime }}</ion-note> | ||||||
|                 <p><core-format-text [text]="entry.userfullname"></core-format-text></p> |                 <p><core-format-text [text]="entry.userfullname"></core-format-text></p> | ||||||
|  | |||||||
| @ -233,9 +233,7 @@ | |||||||
|                         </ion-card-header> |                         </ion-card-header> | ||||||
| 
 | 
 | ||||||
|                         <a ion-item text-wrap *ngFor="let student of overview.students" [navPush]="'AddonModLessonUserRetakePage'" [navParams]="{courseId: courseId, lessonId: lesson.id, userId: student.id}"> |                         <a ion-item text-wrap *ngFor="let student of overview.students" [navPush]="'AddonModLessonUserRetakePage'" [navParams]="{courseId: courseId, lessonId: lesson.id, userId: student.id}"> | ||||||
|                             <ion-avatar item-start *ngIf="student.profileimageurl" core-user-link [userId]="student.id" [courseId]="courseId"> |                             <ion-avatar class="user-avatar" [user]="student" item-start [userId]="student.id" [courseId]="courseId"></ion-avatar> | ||||||
|                                 <img [src]="student.profileimageurl" [alt]="'core.pictureof' | translate:{$a: student.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'" role="presentation"> |  | ||||||
|                             </ion-avatar> |  | ||||||
|                             <h2>{{ student.fullname }}</h2> |                             <h2>{{ student.fullname }}</h2> | ||||||
|                             <core-progress-bar [progress]="student.bestgrade"></core-progress-bar> |                             <core-progress-bar [progress]="student.bestgrade"></core-progress-bar> | ||||||
|                         </a> |                         </a> | ||||||
|  | |||||||
| @ -12,9 +12,7 @@ | |||||||
|         <ion-list *ngIf="student"> |         <ion-list *ngIf="student"> | ||||||
|             <!-- Student data. --> |             <!-- Student data. --> | ||||||
|             <a ion-item text-wrap core-user-link [userId]="student.id" [courseId]="courseId" [title]="student.fullname"> |             <a ion-item text-wrap core-user-link [userId]="student.id" [courseId]="courseId" [title]="student.fullname"> | ||||||
|                 <ion-avatar *ngIf="student.profileimageurl" item-start> |                 <ion-avatar class="user-avatar" [user]="student" item-start [userId]="student.id" [courseId]="courseId"></ion-avatar> | ||||||
|                     <img [src]="student.profileimageurl" [alt]="'core.pictureof' | translate:{$a: student.fullname}" core-external-content role="presentation"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2>{{student.fullname}}</h2> |                 <h2>{{student.fullname}}</h2> | ||||||
|                 <core-progress-bar [progress]="student.bestgrade"></core-progress-bar> |                 <core-progress-bar [progress]="student.bestgrade"></core-progress-bar> | ||||||
|             </a> |             </a> | ||||||
|  | |||||||
| @ -1,8 +1,6 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
|     <a ion-item *ngIf="summary" text-wrap [attr.detail-none]="canViewAssessment && !canSelfAssess? null : true" (click)="gotoAssessment()"> |     <a ion-item *ngIf="summary" text-wrap [attr.detail-none]="canViewAssessment && !canSelfAssess? null : true" (click)="gotoAssessment()"> | ||||||
|         <ion-avatar item-start> |         <ion-avatar class="user-avatar" [user]="profile" item-start [courseId]="courseId" [userId]="profile && profile.id"></ion-avatar> | ||||||
|             <img [src]="profile && profile.profileimageurl" core-external-content [alt]="'core.pictureof' | translate:{$a: profile && profile.fullname}" core-user-link [courseId]="courseId" [userId]="profile && profile.id" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|         </ion-avatar> |  | ||||||
| 
 | 
 | ||||||
|         <h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2> |         <h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2> | ||||||
|         <p *ngIf="showGrade(assessment.grade)"> |         <p *ngIf="showGrade(assessment.grade)"> | ||||||
|  | |||||||
| @ -1,9 +1,7 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
|     <div *ngIf="!summary"> |     <div *ngIf="!summary"> | ||||||
|         <ion-list-header text-wrap> |         <ion-list-header text-wrap> | ||||||
|             <ion-avatar item-start> |             <ion-avatar class="user-avatar" [user]="profile" item-start></ion-avatar> | ||||||
|                 <img [src]="profile && profile.profileimageurl" core-external-content [alt]="'core.pictureof' | translate:{$a: profile && profile.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|             </ion-avatar> |  | ||||||
|             <h2>{{submission.title}}</h2> |             <h2>{{submission.title}}</h2> | ||||||
|             <p *ngIf="profile && profile.fullname">{{profile.fullname}}</p> |             <p *ngIf="profile && profile.fullname">{{profile.fullname}}</p> | ||||||
|             <p *ngIf="showGrade(submission.submissiongrade)" [class.addon-has-overriden-grade]="showGrade(submission.submissiongradeover)"> |             <p *ngIf="showGrade(submission.submissiongrade)" [class.addon-has-overriden-grade]="showGrade(submission.submissiongradeover)"> | ||||||
| @ -34,9 +32,7 @@ | |||||||
|             <core-local-file *ngIf="attachment.name" [file]="attachment"></core-local-file> |             <core-local-file *ngIf="attachment.name" [file]="attachment"></core-local-file> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|         <ion-item text-wrap *ngIf="viewDetails && submission.feedbackauthor"> |         <ion-item text-wrap *ngIf="viewDetails && submission.feedbackauthor"> | ||||||
|             <ion-avatar item-start *ngIf="evaluateByProfile"> |             <ion-avatar class="user-avatar" [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar> | ||||||
|                 <img [src]="evaluateByProfile.profileimageurl" core-external-content core-user-link [courseId]="courseId" [userId]="evaluateByProfile.id" [alt]="'core.pictureof' | translate:{$a: evaluateByProfile.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|             </ion-avatar> |  | ||||||
| 
 | 
 | ||||||
|             <h2 *ngIf="evaluateByProfile && evaluateByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateByProfile.fullname} }}</h2> |             <h2 *ngIf="evaluateByProfile && evaluateByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateByProfile.fullname} }}</h2> | ||||||
|             <core-format-text [text]="submission.feedbackauthor"></core-format-text> |             <core-format-text [text]="submission.feedbackauthor"></core-format-text> | ||||||
| @ -50,9 +46,7 @@ | |||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <a ion-item text-wrap *ngIf="summary" [attr.detail-none]="submission.timemodified ? null : true" (click)="gotoSubmission()"> |     <a ion-item text-wrap *ngIf="summary" [attr.detail-none]="submission.timemodified ? null : true" (click)="gotoSubmission()"> | ||||||
|         <ion-avatar item-start> |         <ion-avatar class="user-avatar" [user]="profile" item-start [courseId]="courseId" [userId]="profile && profile.id"></ion-avatar> | ||||||
|             <img [src]="profile && profile.profileimageurl" core-external-content [alt]="'core.pictureof' | translate:{$a: profile && profile.fullname}" core-user-link [courseId]="courseId" [userId]="profile && profile.id" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|         </ion-avatar> |  | ||||||
| 
 | 
 | ||||||
|         <h2>{{submission.title}}</h2> |         <h2>{{submission.title}}</h2> | ||||||
|         <p *ngIf="profile && profile.fullname">{{profile.fullname}}</p> |         <p *ngIf="profile && profile.fullname">{{profile.fullname}}</p> | ||||||
|  | |||||||
| @ -15,9 +15,8 @@ | |||||||
|     <core-loading [hideUntil]="loaded"> |     <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|         <ion-item text-wrap> |         <ion-item text-wrap> | ||||||
|             <ion-avatar item-start *ngIf="profile"> |             <ion-avatar class="user-avatar" [user]="profile" item-start [courseId]="courseId" [userId]="profile.id"></ion-avatar> | ||||||
|                 <img [src]="profile.profileimageurl" core-external-content core-user-link [courseId]="courseId" [userId]="profile.id" [alt]="'core.pictureof' | translate:{$a: profile.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> | 
 | ||||||
|             </ion-avatar> |  | ||||||
|             <h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2> |             <h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2> | ||||||
| 
 | 
 | ||||||
|             <p *ngIf="workshop && assessment && showGrade(assessment.grade)"> |             <p *ngIf="workshop && assessment && showGrade(assessment.grade)"> | ||||||
| @ -66,9 +65,7 @@ | |||||||
|         </form> |         </form> | ||||||
|         <ion-list *ngIf="!evaluating && evaluate && evaluate.text"> |         <ion-list *ngIf="!evaluating && evaluate && evaluate.text"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar item-start *ngIf="evaluateGradingByProfile"> |                 <ion-avatar class="user-avatar" [user]="evaluateGradingByProfile" item-start [courseId]="courseId" [userId]="evaluateGradingByProfile.id"></ion-avatar> | ||||||
|                     <img [src]="evaluateGradingByProfile.profileimageurl" core-external-content core-user-link [courseId]="courseId" [userId]="evaluateGradingByProfile.id" [alt]="'core.pictureof' | translate:{$a: evaluateGradingByProfile.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2 *ngIf="evaluateGradingByProfile && evaluateGradingByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateGradingByProfile.fullname} }}</h2> |                 <h2 *ngIf="evaluateGradingByProfile && evaluateGradingByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateGradingByProfile.fullname} }}</h2> | ||||||
|                 <core-format-text [text]="evaluate.text"></core-format-text> |                 <core-format-text [text]="evaluate.text"></core-format-text> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -36,9 +36,7 @@ | |||||||
| 
 | 
 | ||||||
|         <ion-list *ngIf="!canAddFeedback && evaluate && evaluate.text"> |         <ion-list *ngIf="!canAddFeedback && evaluate && evaluate.text"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar item-start *ngIf="evaluateByProfile"> |                 <ion-avatar class="user-avatar" [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar> | ||||||
|                     <img [src]="evaluateByProfile.profileimageurl" core-external-content core-user-link [courseId]="courseId" [userId]="evaluateByProfile.id" [alt]="'core.pictureof' | translate:{$a: evaluateByProfile.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2 *ngIf="evaluateByProfile && evaluateByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateByProfile.fullname} }}</h2> |                 <h2 *ngIf="evaluateByProfile && evaluateByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateByProfile.fullname} }}</h2> | ||||||
|                 <core-format-text [text]="evaluate.text"></core-format-text> |                 <core-format-text [text]="evaluate.text"></core-format-text> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| @ -97,9 +95,7 @@ | |||||||
| 
 | 
 | ||||||
|         <ion-list *ngIf="assessmentId && !access.assessingallowed && assessment.feedbackreviewer"> |         <ion-list *ngIf="assessmentId && !access.assessingallowed && assessment.feedbackreviewer"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar item-start *ngIf="evaluateGradingByProfile"> |                 <ion-avatar class="user-avatar" [user]="evaluateGradingByProfile" item-start [courseId]="courseId" [userId]="evaluateGradingByProfile.id"></ion-avatar> | ||||||
|                     <img [src]="evaluateGradingByProfile.profileimageurl" core-external-content core-user-link [courseId]="courseId" [userId]="evaluateGradingByProfile.id" [alt]="'core.pictureof' | translate:{$a: evaluateGradingByProfile.fullname}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2 *ngIf="evaluateGradingByProfile && evaluateGradingByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateGradingByProfile.fullname} }}</h2> |                 <h2 *ngIf="evaluateGradingByProfile && evaluateGradingByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateGradingByProfile.fullname} }}</h2> | ||||||
|                 <core-format-text [text]="assessment.feedbackreviewer"></core-format-text> |                 <core-format-text [text]="assessment.feedbackreviewer"></core-format-text> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -27,9 +27,7 @@ | |||||||
|         <ion-list *ngIf="notes && notes.length > 0"> |         <ion-list *ngIf="notes && notes.length > 0"> | ||||||
|             <ion-card *ngFor="let note of notes"> |             <ion-card *ngFor="let note of notes"> | ||||||
|                 <ion-item text-wrap> |                 <ion-item text-wrap> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="note" item-start></ion-avatar> | ||||||
|                         <img [src]="note.userprofileimageurl || 'assets/img/user-avatar.png'" core-external-content core-user-link [userId]="note.userid" [courseId]="note.courseid" [alt]="'core.pictureof' | translate:{$a: note.userfullname}" role="presentation"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2>{{note.userfullname}}</h2> |                     <h2>{{note.userfullname}}</h2> | ||||||
|                     <p *ngIf="!note.offline" item-end>{{note.lastmodified | coreDateDayOrTime}}</p> |                     <p *ngIf="!note.offline" item-end>{{note.lastmodified | coreDateDayOrTime}}</p> | ||||||
|                     <p *ngIf="note.offline" item-end><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> |                     <p *ngIf="note.offline" item-end><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> | ||||||
|  | |||||||
| @ -19,9 +19,7 @@ | |||||||
|         </div> |         </div> | ||||||
|         <ion-card *ngFor="let notification of notifications"> |         <ion-card *ngFor="let notification of notifications"> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-avatar item-start core-user-link [userId]="notification.useridfrom" [courseId]="notification.courseid"> |                 <ion-avatar class="user-avatar" [user]="notification" item-start [profileUrl]="notification.profileimageurlfrom" [fullname]="notification.userfromfullname" [userId]="notification.useridfrom" [courseId]="notification.courseid"></ion-avatar> | ||||||
|                     <img [src]="notification.profileimageurlfrom || 'assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: notification.userfromfullname}" role="presentation"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2>{{notification.userfromfullname}}</h2> |                 <h2>{{notification.userfromfullname}}</h2> | ||||||
|                 <div item-end *ngIf="!notification.timeread"><core-icon name="fa-circle" color="primary"></core-icon></div> |                 <div item-end *ngIf="!notification.timeread"><core-icon name="fa-circle" color="primary"></core-icon></div> | ||||||
|                 <p>{{notification.timecreated | coreDateDayOrTime}}</p> |                 <p>{{notification.timecreated | coreDateDayOrTime}}</p> | ||||||
|  | |||||||
| @ -52,7 +52,7 @@ export class CoreChronoComponent implements OnChanges, OnDestroy { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Component being initialized. |      * Component being changed. | ||||||
|      */ |      */ | ||||||
|     ngOnChanges(changes: { [name: string]: SimpleChange }): void { |     ngOnChanges(changes: { [name: string]: SimpleChange }): void { | ||||||
|         if (changes && changes.running) { |         if (changes && changes.running) { | ||||||
|  | |||||||
| @ -50,6 +50,7 @@ import { CoreAttachmentsComponent } from './attachments/attachments'; | |||||||
| import { CoreIonTabsComponent } from './ion-tabs/ion-tabs'; | import { CoreIonTabsComponent } from './ion-tabs/ion-tabs'; | ||||||
| import { CoreIonTabComponent } from './ion-tabs/ion-tab'; | import { CoreIonTabComponent } from './ion-tabs/ion-tab'; | ||||||
| import { CoreInfiniteLoadingComponent } from './infinite-loading/infinite-loading'; | import { CoreInfiniteLoadingComponent } from './infinite-loading/infinite-loading'; | ||||||
|  | import { CoreUserAvatarComponent } from './user-avatar/user-avatar'; | ||||||
| 
 | 
 | ||||||
| @NgModule({ | @NgModule({ | ||||||
|     declarations: [ |     declarations: [ | ||||||
| @ -85,7 +86,8 @@ import { CoreInfiniteLoadingComponent } from './infinite-loading/infinite-loadin | |||||||
|         CoreAttachmentsComponent, |         CoreAttachmentsComponent, | ||||||
|         CoreIonTabsComponent, |         CoreIonTabsComponent, | ||||||
|         CoreIonTabComponent, |         CoreIonTabComponent, | ||||||
|         CoreInfiniteLoadingComponent |         CoreInfiniteLoadingComponent, | ||||||
|  |         CoreUserAvatarComponent | ||||||
|     ], |     ], | ||||||
|     entryComponents: [ |     entryComponents: [ | ||||||
|         CoreContextMenuPopoverComponent, |         CoreContextMenuPopoverComponent, | ||||||
| @ -128,7 +130,8 @@ import { CoreInfiniteLoadingComponent } from './infinite-loading/infinite-loadin | |||||||
|         CoreAttachmentsComponent, |         CoreAttachmentsComponent, | ||||||
|         CoreIonTabsComponent, |         CoreIonTabsComponent, | ||||||
|         CoreIonTabComponent, |         CoreIonTabComponent, | ||||||
|         CoreInfiniteLoadingComponent |         CoreInfiniteLoadingComponent, | ||||||
|  |         CoreUserAvatarComponent | ||||||
|     ] |     ] | ||||||
| }) | }) | ||||||
| export class CoreComponentsModule {} | export class CoreComponentsModule {} | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								src/components/user-avatar/core-user-avatar.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/components/user-avatar/core-user-avatar.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | <img src="{{profileUrl}}" [alt]="'core.pictureof' | translate:{$a: fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'" role="presentation" [siteId]="siteId || null" (click)="gotoProfile($event)"> | ||||||
|  | <span *ngIf="isOnline()" class="contact-status online"></span> | ||||||
							
								
								
									
										15
									
								
								src/components/user-avatar/user-avatar.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/components/user-avatar/user-avatar.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | ion-avatar.user-avatar { | ||||||
|  |     position: relative; | ||||||
|  | 
 | ||||||
|  |     .contact-status { | ||||||
|  |         position: absolute; | ||||||
|  |         @include position(null, 0, 0, null); | ||||||
|  |         width: 14px; | ||||||
|  |         height: 14px; | ||||||
|  |         border-radius: 50%; | ||||||
|  |         &.online { | ||||||
|  |             border: 1px solid white; | ||||||
|  |             background-color: $core-online-color; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										113
									
								
								src/components/user-avatar/user-avatar.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/components/user-avatar/user-avatar.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,113 @@ | |||||||
|  | // (C) Copyright 2015 Martin Dougiamas
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||||
|  | // you may not use this file except in compliance with the License.
 | ||||||
|  | // You may obtain a copy of the License at
 | ||||||
|  | //
 | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, software
 | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||||
|  | // See the License for the specific language governing permissions and
 | ||||||
|  | // limitations under the License.
 | ||||||
|  | 
 | ||||||
|  | import { Component, Input, OnInit, OnChanges, SimpleChange } from '@angular/core'; | ||||||
|  | import { NavController } from 'ionic-angular'; | ||||||
|  | import { CoreSitesProvider } from '@providers/sites'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Component to display a "user avatar". | ||||||
|  |  * | ||||||
|  |  * Example: <core-user-avatar [user]="participant"></core-user-avatar> | ||||||
|  |  */ | ||||||
|  | @Component({ | ||||||
|  |     selector: 'ion-avatar.user-avatar', | ||||||
|  |     templateUrl: 'core-user-avatar.html' | ||||||
|  | }) | ||||||
|  | export class CoreUserAvatarComponent implements OnInit, OnChanges { | ||||||
|  |     @Input() user: any; | ||||||
|  |     // The following params will override the ones in user object.
 | ||||||
|  |     @Input() profileUrl?: string; | ||||||
|  |     @Input() fullname?: string; | ||||||
|  |     @Input() protected userId?: number; // If provided or found it will be used to link the image to the profile.
 | ||||||
|  |     @Input() protected courseId?: number; | ||||||
|  | 
 | ||||||
|  |     // Variable to check if we consider this user online or not.
 | ||||||
|  |     protected timetoshowusers = 300000; // Miliseconds default.
 | ||||||
|  |     protected myUser = false; | ||||||
|  |     protected currentUserId: number; | ||||||
|  | 
 | ||||||
|  |     constructor(private navCtrl: NavController, private sitesProvider: CoreSitesProvider) { | ||||||
|  |         this.currentUserId = this.sitesProvider.getCurrentSiteUserId(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Component being initialized. | ||||||
|  |      */ | ||||||
|  |     ngOnInit(): void { | ||||||
|  |         console.error(this.user); | ||||||
|  |         this.setFields(); | ||||||
|  | 
 | ||||||
|  |         // @TODO: This setting is not currently available so we are always using the default setting.
 | ||||||
|  |         /*if (!this.myUser) { | ||||||
|  |             let minutes = 5; | ||||||
|  |             this.sitesProvider.getCurrentSite().getConfig('block_online_users_timetosee').then((timetosee) => { | ||||||
|  |                 minutes = timetosee || minutes; | ||||||
|  |             }).catch(() => { | ||||||
|  |                 // Ignore errors.
 | ||||||
|  |             }).finally(() => { | ||||||
|  |                 this.timetoshowusers = minutes * 60000; | ||||||
|  |             }); | ||||||
|  |         }*/ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Listen to changes. | ||||||
|  |      */ | ||||||
|  |     ngOnChanges(changes: { [name: string]: SimpleChange }): void { | ||||||
|  |         // If something change, update the fields.
 | ||||||
|  |         if (changes) { | ||||||
|  |             this.setFields(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Set fields from user. | ||||||
|  |      */ | ||||||
|  |     protected setFields(): void { | ||||||
|  |         this.profileUrl = this.profileUrl || this.user.profileimageurl || this.user.userprofileimageurl || | ||||||
|  |             this.user.userpictureurl || this.user.profileimageurlsmall; | ||||||
|  | 
 | ||||||
|  |         this.fullname = this.fullname || this.user.fullname || this.user.userfullname; | ||||||
|  | 
 | ||||||
|  |         this.userId = this.userId || this.user.userid; | ||||||
|  |         this.courseId = this.courseId || this.user.courseid; | ||||||
|  | 
 | ||||||
|  |         // If not available we cannot ensure the avatar is from the current user.
 | ||||||
|  |         this.myUser = this.userId && this.userId == this.currentUserId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Helper function for checking the time meets the 'online' condition. | ||||||
|  |      * | ||||||
|  |      * @return boolean | ||||||
|  |      */ | ||||||
|  |     isOnline(): boolean { | ||||||
|  |         const time = new Date().getTime() - this.timetoshowusers; | ||||||
|  | 
 | ||||||
|  |         return !this.myUser && ((this.user.lastaccess && this.user.lastaccess * 1000 >= time) || this.user.isonline); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Function executed image clicked. | ||||||
|  |      */ | ||||||
|  |     gotoProfile(event: any): void { | ||||||
|  |         // If the event prevented default action, do nothing.
 | ||||||
|  |         if (!event.defaultPrevented && this.userId) { | ||||||
|  |             event.preventDefault(); | ||||||
|  |             event.stopPropagation(); | ||||||
|  |             this.navCtrl.push('CoreUserProfilePage', { userId: this.userId, courseId: this.courseId }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -12,9 +12,7 @@ | |||||||
| 
 | 
 | ||||||
|         <ion-card *ngFor="let comment of comments"> |         <ion-card *ngFor="let comment of comments"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar item-start> |                 <ion-avatar class="user-avatar" [user]="comment" item-start></ion-avatar> | ||||||
|                     <img [src]="comment.profileimageurl" onError="this.src='assets/img/user-avatar.png'" core-external-content core-user-link [userId]="comment.userid" [alt]="'core.pictureof' | translate:{$a: comment.fullname}" role="presentation"> |  | ||||||
|                 </ion-avatar> |  | ||||||
|                 <h2>{{ comment.fullname }}</h2> |                 <h2>{{ comment.fullname }}</h2> | ||||||
|                 <p>{{ comment.time }}</p> |                 <p>{{ comment.time }}</p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -26,10 +26,8 @@ | |||||||
| 
 | 
 | ||||||
|             <ng-container text-wrap *ngIf="course.contacts && course.contacts.length"> |             <ng-container text-wrap *ngIf="course.contacts && course.contacts.length"> | ||||||
|                 <ion-item-divider color="light">{{ 'core.teachers' | translate }}</ion-item-divider> |                 <ion-item-divider color="light">{{ 'core.teachers' | translate }}</ion-item-divider> | ||||||
|                 <a ion-item text-wrap *ngFor="let contact of course.contacts" core-user-link userId="{{contact.id}}" courseId="{{isEnrolled ? course.id : null}}" [attr.aria-label]="'core.viewprofile' | translate"> |                 <a ion-item text-wrap *ngFor="let contact of course.contacts" core-user-link [userId]="contact.id" [courseId]="isEnrolled ? course.id : null" [attr.aria-label]="'core.viewprofile' | translate"> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="contact" item-start [userId]="contact.id" [courseId]="isEnrolled ? course.id : null"></ion-avatar> | ||||||
|                         <img [src]="contact.userpictureurl" onError="this.src='assets/img/user-avatar.png'" core-external-content [alt]="'core.pictureof' | translate:{$a: contact.userfullname}" role="presentation"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2>{{contact.fullname}}</h2> |                     <h2>{{contact.fullname}}</h2> | ||||||
|                 </a> |                 </a> | ||||||
|                 <ion-item-divider color="light"></ion-item-divider> |                 <ion-item-divider color="light"></ion-item-divider> | ||||||
|  | |||||||
| @ -5,10 +5,8 @@ | |||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <ion-list> |     <ion-list> | ||||||
|         <a ion-item core-user-link userId="{{siteInfo.userid}}"> |         <a ion-item core-user-link [userId]="siteInfo.userid"> | ||||||
|             <ion-avatar item-start> |             <ion-avatar class="user-avatar" [user]="siteInfo" item-start></ion-avatar> | ||||||
|                 <img [src]="siteInfo.userpictureurl" core-external-content alt="{{ 'core.pictureof' | translate:{$a: siteInfo.fullname} }}" role="presentation"> |  | ||||||
|             </ion-avatar> |  | ||||||
|             <p>{{siteInfo.fullname}}</p> |             <p>{{siteInfo.fullname}}</p> | ||||||
|         </a> |         </a> | ||||||
|         <ion-item-divider color="light"></ion-item-divider> |         <ion-item-divider color="light"></ion-item-divider> | ||||||
|  | |||||||
| @ -9,9 +9,7 @@ | |||||||
| 
 | 
 | ||||||
|             <ion-list *ngIf="participants && participants.length > 0" no-margin> |             <ion-list *ngIf="participants && participants.length > 0" no-margin> | ||||||
|                 <a ion-item text-wrap *ngFor="let participant of participants" [title]="participant.fullname" (click)="gotoParticipant(participant.id)" [class.core-split-item-selected]="participant.id == participantId"> |                 <a ion-item text-wrap *ngFor="let participant of participants" [title]="participant.fullname" (click)="gotoParticipant(participant.id)" [class.core-split-item-selected]="participant.id == participantId"> | ||||||
|                     <ion-avatar item-start> |                     <ion-avatar class="user-avatar" [user]="participant" item-start [userId]="participant.id"></ion-avatar> | ||||||
|                         <img src="{{participant.profileimageurl}}" [alt]="'core.pictureof' | translate:{$a: participant.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'"> |  | ||||||
|                     </ion-avatar> |  | ||||||
|                     <h2><core-format-text [text]="participant.fullname"></core-format-text></h2> |                     <h2><core-format-text [text]="participant.fullname"></core-format-text></h2> | ||||||
|                     <p *ngIf="participant.lastaccess"><strong>{{ 'core.lastaccess' | translate }}: </strong>{{ participant.lastaccess * 1000 | coreFormatDate:"dfmediumdate"}}</p> |                     <p *ngIf="participant.lastaccess"><strong>{{ 'core.lastaccess' | translate }}: </strong>{{ participant.lastaccess * 1000 | coreFormatDate:"dfmediumdate"}}</p> | ||||||
|                 </a> |                 </a> | ||||||
|  | |||||||
| @ -111,6 +111,8 @@ $button-md-box-shadow: 0 2px 2px 1px rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, | |||||||
| 
 | 
 | ||||||
| $refresher-icon-color: $core-color !default; | $refresher-icon-color: $core-color !default; | ||||||
| 
 | 
 | ||||||
|  | $core-online-color: #5cb85c; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| // Moodle Mobile variables | // Moodle Mobile variables | ||||||
| // -------------------------------------------------- | // -------------------------------------------------- | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user