MOBILE-1486 user: Add online status to the user profile

main
Pau Ferrer Ocaña 2018-11-16 14:41:26 +01:00
parent 5e4e4fc75f
commit dbf3c85f73
34 changed files with 78 additions and 67 deletions

View File

@ -28,7 +28,7 @@
<h3 margin-horizontal *ngIf="competencies && competencies.statistics.competencycount > 0">{{ 'addon.competency.competencies' | translate }}</h3>
<ion-card *ngIf="user">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
</ion-item>
</ion-card>

View File

@ -10,7 +10,7 @@
<core-loading [hideUntil]="competencyLoaded">
<ion-card *ngIf="user">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
</ion-item>
</ion-card>
@ -73,7 +73,7 @@
</p>
<ion-card *ngFor="let evidence of competency.evidence">
<a ion-item text-wrap *ngIf="evidence.actionuser" (click)="openUserProfile(evidence.actionuser.id)">
<ion-avatar class="user-avatar" [user]="evidence.actionuser" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="evidence.actionuser" item-start></ion-avatar>
<h2>{{ evidence.actionuser.fullname }}</h2>
<p>{{ evidence.timemodified | coreToLocaleString }}</p>
</a>

View File

@ -10,7 +10,7 @@
<core-loading [hideUntil]="planLoaded">
<ion-card *ngIf="user">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
</ion-item>
</ion-card>

View File

@ -19,7 +19,7 @@
<ng-container *ngFor="let contact of contacts[contactType]">
<!-- 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>
<ion-avatar class="user-avatar" [user]="contact" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="contact" item-start></ion-avatar>
<h2><core-format-text [text]="contact.fullname"></core-format-text></h2>
</a>
</ng-container>

View File

@ -17,7 +17,7 @@
<ion-note item-end>{{ search.results.length }}</ion-note>
</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>
<ion-avatar class="user-avatar" [user]="result" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="result" item-start></ion-avatar>
<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>
</a>
@ -25,7 +25,7 @@
<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>
<ion-avatar class="user-avatar" [user]="discussion" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="discussion" item-start></ion-avatar>
<h2>
<core-format-text [text]="discussion.fullname"></core-format-text>
<ion-note *ngIf="discussion.message.timecreated > 0 || discussion.unread">

View File

@ -2,7 +2,7 @@
<!-- User and status of the submission. -->
<a ion-item text-wrap *ngIf="!blindMarking && user" (click)="openUserProfile(submitId)" [title]="user.fullname">
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2>{{ user.fullname }}</h2>
<ng-container *ngTemplateOutlet="submissionStatus"></ng-container>
</a>
@ -111,7 +111,7 @@
<h2>{{ 'addon.mod_assign.userswhoneedtosubmit' | translate: {$a: ''} }}</h2>
<div *ngFor="let user of membersToSubmit">
<a ion-item text-wrap *ngIf="user.fullname" (click)="openUserProfile(user.id)" [title]="user.fullname">
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2>{{ user.fullname }}</h2>
</a>
<ion-item text-wrap *ngIf="!user.fullname">
@ -209,7 +209,7 @@
<!-- Data about the grader (teacher who graded). -->
<a ion-item text-wrap *ngIf="grader" (click)="openUserProfile(grader.id)" [title]="grader.fullname" detail-push>
<ion-avatar class="user-avatar" [user]="grader" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="grader" item-start></ion-avatar>
<h2>{{ 'addon.mod_assign.gradedby' | translate }}</h2>
<h2>{{ grader.fullname }}</h2>
<p *ngIf="feedback.gradeddate">{{ feedback.gradeddate * 1000 | coreFormatDate:"dfmediumdate" }}</p>

View File

@ -18,7 +18,7 @@
<!-- List 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">
<ion-avatar class="user-avatar" [user]="submission" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="submission" item-start></ion-avatar>
<h2 *ngIf="submission.userfullname">{{submission.userfullname}}</h2>
<h2 *ngIf="!submission.userfullname">{{ 'addon.mod_assign.hiddenuser' | translate }}{{submission.blindid}}</h2>
<p *ngIf="assign.teamsubmission">

View File

@ -38,7 +38,7 @@
</div>
<ion-item text-wrap *ngIf="!message.system && message.message.substr(0, 4) != 'beep'" class="addon-mod-chat-message">
<ion-avatar class="user-avatar" [user]="message" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="message" item-start></ion-avatar>
<h2>
<p float-end>{{ message.timestamp * 1000 | coreFormatDate:"dftimedate" }}</p>
<core-format-text [text]="message.userfullname"></core-format-text>

View File

@ -11,7 +11,7 @@
<ion-content>
<core-loading [hideUntil]="usersLoaded">
<ion-item text-wrap *ngFor="let user of users" [class.addon-mod-chat-user]="currentUserId != user.id && isOnline">
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
<ng-container *ngIf="currentUserId != user.id && isOnline">
<button ion-button clear icon-left (click)="talkTo(user)">

View File

@ -82,7 +82,7 @@
<p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamount} }})</p>
</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>
<ion-avatar class="user-avatar" [user]="user" item-start [courseId]="courseid"></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start [courseId]="courseid"></ion-avatar>
<p>{{user.fullname}}</p>
</a>
</ion-item-group>

View File

@ -7,7 +7,7 @@
<core-loading [hideUntil]="feedbackLoaded">
<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" [courseId]="attempt.courseid" [title]="attempt.fullname">
<ion-avatar class="user-avatar" [user]="attempt" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="attempt" item-start></ion-avatar>
<h2>{{attempt.fullname}}</h2>
<p *ngIf="attempt.timemodified">{{attempt.timemodified * 1000 | coreFormatDate:"LLL"}}</p>
</a>

View File

@ -21,7 +21,7 @@
</ion-item-divider>
<ng-container *ngIf="total > 0">
<ion-item *ngFor="let user of users" text-wrap>
<ion-avatar class="user-avatar" [user]="user" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="user" item-start></ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
<p>
<ion-badge color="success" *ngIf="user.started">

View File

@ -22,7 +22,7 @@
{{ 'addon.mod_feedback.non_anonymous_entries' | translate : {$a: responses.total } }}
</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">
<ion-avatar class="user-avatar" [user]="attempt" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="attempt" item-start></ion-avatar>
<h2><core-format-text [text]="attempt.fullname"></core-format-text></h2>
<p *ngIf="attempt.timemodified">{{attempt.timemodified * 1000 | coreFormatDate: "LLL"}}</p>
</a>

View File

@ -27,7 +27,7 @@
<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-item text-wrap>
<ion-avatar class="user-avatar" [user]="discussion" item-start [courseId]="courseId"></ion-avatar>
<ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId"></ion-avatar>
<h2><core-format-text [text]="discussion.subject"></core-format-text></h2>
<p *ngIf="discussion.userfullname">
<ion-note float-end padding-left><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note>
@ -43,7 +43,7 @@
</ion-card>
<ion-card *ngFor="let discussion of discussions" (click)="openDiscussion(discussion)" [class.addon-forum-discussion-selected]="discussion.discussion == selectedDiscussion">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="discussion" item-start [courseId]="courseId"></ion-avatar>
<ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId"></ion-avatar>
<h2><core-icon name="fa-map-pin" *ngIf="discussion.pinned"></core-icon> <core-format-text [text]="discussion.subject"></core-format-text></h2>
<p>
<ion-note float-end padding-left text-end>

View File

@ -1,6 +1,6 @@
<ion-card-header text-wrap no-padding >
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="post" item-start (click)="openUserProfile(post.userid)"></ion-avatar>
<ion-avatar core-user-avatar [user]="post" item-start (click)="openUserProfile(post.userid)"></ion-avatar>
<h2><span [class.core-bold]="post.parent == 0"><core-format-text [text]="post.subject"></core-format-text></span></h2>
<p>
<ion-note float-end padding-left *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note>

View File

@ -11,7 +11,7 @@
<core-loading [hideUntil]="loaded">
<ng-container *ngIf="entry">
<ion-item text-wrap *ngIf="showAuthor">
<ion-avatar class="user-avatar" [user]="entry" (click)="openUserProfile(post.userid)" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="entry" (click)="openUserProfile(post.userid)" item-start></ion-avatar>
<h2><core-format-text [text]="entry.concept"></core-format-text></h2>
<ion-note item-end *ngIf="showDate">{{ entry.timemodified | coreDateDayOrTime }}</ion-note>
<p><core-format-text [text]="entry.userfullname"></core-format-text></p>

View File

@ -233,7 +233,7 @@
</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}">
<ion-avatar class="user-avatar" [user]="student" item-start [userId]="student.id" [courseId]="courseId"></ion-avatar>
<ion-avatar core-user-avatar [user]="student" item-start [userId]="student.id" [courseId]="courseId"></ion-avatar>
<h2>{{ student.fullname }}</h2>
<core-progress-bar [progress]="student.bestgrade"></core-progress-bar>
</a>

View File

@ -12,7 +12,7 @@
<ion-list *ngIf="student">
<!-- Student data. -->
<a ion-item text-wrap core-user-link [userId]="student.id" [courseId]="courseId" [title]="student.fullname">
<ion-avatar class="user-avatar" [user]="student" item-start [userId]="student.id" [courseId]="courseId"></ion-avatar>
<ion-avatar core-user-avatar [user]="student" item-start [userId]="student.id" [courseId]="courseId"></ion-avatar>
<h2>{{student.fullname}}</h2>
<core-progress-bar [progress]="student.bestgrade"></core-progress-bar>
</a>

View File

@ -1,6 +1,6 @@
<core-loading [hideUntil]="loaded">
<a ion-item *ngIf="summary" text-wrap [attr.detail-none]="canViewAssessment && !canSelfAssess? null : true" (click)="gotoAssessment()">
<ion-avatar class="user-avatar" [user]="profile" item-start [courseId]="courseId" [userId]="profile && profile.id"></ion-avatar>
<ion-avatar core-user-avatar [user]="profile" item-start [courseId]="courseId" [userId]="profile && profile.id"></ion-avatar>
<h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2>
<p *ngIf="showGrade(assessment.grade)">

View File

@ -1,7 +1,7 @@
<core-loading [hideUntil]="loaded">
<div *ngIf="!summary">
<ion-list-header text-wrap>
<ion-avatar class="user-avatar" [user]="profile" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="profile" item-start></ion-avatar>
<h2>{{submission.title}}</h2>
<p *ngIf="profile && profile.fullname">{{profile.fullname}}</p>
<p *ngIf="showGrade(submission.submissiongrade)" [class.addon-has-overriden-grade]="showGrade(submission.submissiongradeover)">
@ -32,7 +32,7 @@
<core-local-file *ngIf="attachment.name" [file]="attachment"></core-local-file>
</ion-item>
<ion-item text-wrap *ngIf="viewDetails && submission.feedbackauthor">
<ion-avatar class="user-avatar" [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar>
<ion-avatar core-user-avatar [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar>
<h2 *ngIf="evaluateByProfile && evaluateByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateByProfile.fullname} }}</h2>
<core-format-text [text]="submission.feedbackauthor"></core-format-text>
@ -46,7 +46,7 @@
</div>
<a ion-item text-wrap *ngIf="summary" [attr.detail-none]="submission.timemodified ? null : true" (click)="gotoSubmission()">
<ion-avatar class="user-avatar" [user]="profile" item-start [courseId]="courseId" [userId]="profile && profile.id"></ion-avatar>
<ion-avatar core-user-avatar [user]="profile" item-start [courseId]="courseId" [userId]="profile && profile.id"></ion-avatar>
<h2>{{submission.title}}</h2>
<p *ngIf="profile && profile.fullname">{{profile.fullname}}</p>

View File

@ -15,7 +15,7 @@
<core-loading [hideUntil]="loaded">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="profile" item-start [courseId]="courseId" [userId]="profile.id"></ion-avatar>
<ion-avatar *ngIf="profile" core-user-avatar [user]="profile" item-start [courseId]="courseId" [userId]="profile.id"></ion-avatar>
<h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2>
@ -65,7 +65,7 @@
</form>
<ion-list *ngIf="!evaluating && evaluate && evaluate.text">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="evaluateGradingByProfile" item-start [courseId]="courseId" [userId]="evaluateGradingByProfile.id"></ion-avatar>
<ion-avatar core-user-avatar *ngIf="evaluateGradingByProfile" [user]="evaluateGradingByProfile" item-start [courseId]="courseId" [userId]="evaluateGradingByProfile.id"></ion-avatar>
<h2 *ngIf="evaluateGradingByProfile && evaluateGradingByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateGradingByProfile.fullname} }}</h2>
<core-format-text [text]="evaluate.text"></core-format-text>
</ion-item>

View File

@ -36,7 +36,7 @@
<ion-list *ngIf="!canAddFeedback && evaluate && evaluate.text">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar>
<ion-avatar core-user-avatar *ngIf="evaluateByProfile" [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar>
<h2 *ngIf="evaluateByProfile && evaluateByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateByProfile.fullname} }}</h2>
<core-format-text [text]="evaluate.text"></core-format-text>
</ion-item>
@ -95,7 +95,7 @@
<ion-list *ngIf="assessmentId && !access.assessingallowed && assessment.feedbackreviewer">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="evaluateGradingByProfile" item-start [courseId]="courseId" [userId]="evaluateGradingByProfile.id"></ion-avatar>
<ion-avatar core-user-avatar *ngIf="evaluateGradingByProfile" [user]="evaluateGradingByProfile" item-start [courseId]="courseId" [userId]="evaluateGradingByProfile.id"></ion-avatar>
<h2 *ngIf="evaluateGradingByProfile && evaluateGradingByProfile.fullname">{{ 'addon.mod_workshop.feedbackby' | translate : {$a: evaluateGradingByProfile.fullname} }}</h2>
<core-format-text [text]="assessment.feedbackreviewer"></core-format-text>
</ion-item>

View File

@ -27,7 +27,7 @@
<ion-list *ngIf="notes && notes.length > 0">
<ion-card *ngFor="let note of notes">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="note" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="note" item-start></ion-avatar>
<h2>{{note.userfullname}}</h2>
<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>

View File

@ -19,7 +19,7 @@
</div>
<ion-card *ngFor="let notification of notifications">
<ion-item>
<ion-avatar class="user-avatar" [user]="notification" item-start [profileUrl]="notification.profileimageurlfrom" [fullname]="notification.userfromfullname" [userId]="notification.useridfrom" [courseId]="notification.courseid"></ion-avatar>
<ion-avatar core-user-avatar [user]="notification" item-start [profileUrl]="notification.profileimageurlfrom" [fullname]="notification.userfromfullname" [userId]="notification.useridfrom"></ion-avatar>
<h2>{{notification.userfromfullname}}</h2>
<div item-end *ngIf="!notification.timeread"><core-icon name="fa-circle" color="primary"></core-icon></div>
<p>{{notification.timecreated | coreDateDayOrTime}}</p>

View File

@ -173,6 +173,7 @@ ion-app.app-root {
border-radius : 50%;
padding: 4px;
border: 1px solid #ddd;
background-color: white;
&.avatar-full {
border-radius: 2%;

View File

@ -1,2 +1,3 @@
<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>
<span *ngIf="checkOnline && isOnline()" class="contact-status online"></span>
<ng-content></ng-content>

View File

@ -1,4 +1,4 @@
ion-avatar.user-avatar {
ion-avatar[core-user-avatar] {
position: relative;
.contact-status {

View File

@ -19,21 +19,24 @@ import { CoreSitesProvider } from '@providers/sites';
/**
* Component to display a "user avatar".
*
* Example: <core-user-avatar [user]="participant"></core-user-avatar>
* Example: <ion-avatar core-user-avatar [user]="participant"></ion-avatar>
*/
@Component({
selector: 'ion-avatar.user-avatar',
selector: 'ion-avatar[core-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() protected linkProfile = true; // Avoid linking to the profile if wanted.
@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;
@Input() checkOnline = false; // If want to check and show online status.
// Variable to check if we consider this user online or not.
// @TODO: Use setting when available (see MDL-63972) so we can use site setting.
protected timetoshowusers = 300000; // Miliseconds default.
protected myUser = false;
protected currentUserId: number;
@ -46,20 +49,7 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges {
* 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;
});
}*/
}
/**
@ -76,16 +66,18 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges {
* Set fields from user.
*/
protected setFields(): void {
this.profileUrl = this.profileUrl || this.user.profileimageurl || this.user.userprofileimageurl ||
this.user.userpictureurl || this.user.profileimageurlsmall;
if (this.user) {
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.fullname = this.fullname || this.user.fullname || this.user.userfullname;
this.userId = this.userId || this.user.userid;
this.courseId = this.courseId || this.user.courseid;
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;
// If not available we cannot ensure the avatar is from the current user.
this.myUser = this.userId && this.userId == this.currentUserId;
}
}
/**
@ -104,7 +96,7 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges {
*/
gotoProfile(event: any): void {
// If the event prevented default action, do nothing.
if (!event.defaultPrevented && this.userId) {
if (this.linkProfile && this.userId) {
event.preventDefault();
event.stopPropagation();
this.navCtrl.push('CoreUserProfilePage', { userId: this.userId, courseId: this.courseId });

View File

@ -12,7 +12,7 @@
<ion-card *ngFor="let comment of comments">
<ion-item text-wrap>
<ion-avatar class="user-avatar" [user]="comment" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="comment" item-start></ion-avatar>
<h2>{{ comment.fullname }}</h2>
<p>{{ comment.time }}</p>
</ion-item>

View File

@ -27,7 +27,7 @@
<ng-container text-wrap *ngIf="course.contacts && course.contacts.length">
<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">
<ion-avatar class="user-avatar" [user]="contact" item-start [userId]="contact.id" [courseId]="isEnrolled ? course.id : null"></ion-avatar>
<ion-avatar core-user-avatar [user]="contact" item-start [userId]="contact.id" [courseId]="isEnrolled ? course.id : null"></ion-avatar>
<h2>{{contact.fullname}}</h2>
</a>
<ion-item-divider color="light"></ion-item-divider>

View File

@ -6,7 +6,7 @@
<ion-content>
<ion-list>
<a ion-item core-user-link [userId]="siteInfo.userid">
<ion-avatar class="user-avatar" [user]="siteInfo" item-start></ion-avatar>
<ion-avatar core-user-avatar [user]="siteInfo" item-start></ion-avatar>
<p>{{siteInfo.fullname}}</p>
</a>
<ion-item-divider color="light"></ion-item-divider>

View File

@ -9,7 +9,7 @@
<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">
<ion-avatar class="user-avatar" [user]="participant" item-start [userId]="participant.id"></ion-avatar>
<ion-avatar core-user-avatar [user]="participant" item-start [userId]="participant.id" [checkOnline]="true"></ion-avatar>
<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>
</a>

View File

@ -10,10 +10,9 @@
<core-loading [hideUntil]="userLoaded">
<ion-list *ngIf="user && !isDeleted">
<ion-item text-center>
<div class="item-avatar-center">
<img class="avatar" [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 class="user-avatar item-avatar-center" [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="true">
<ion-icon name="create" class="core-icon-foreground" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"></ion-icon>
</div>
</ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
<p><core-format-text *ngIf="user.address" [text]="user.address"></core-format-text></p>
<p *ngIf="user.roles" text-wrap>

View File

@ -1,9 +1,27 @@
ion-app.app-root page-core-user-profile {
.core-icon-foreground {
position: relative;
@include position(null, null, 30px, 60px);
position: absolute;
@include position(null, 0, 0, null);
font-size: 24px;
line-height: 30px;
text-align: center;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: white;
}
.user-avatar.item-avatar-center {
display: inline-block;
img {
margin: 0;
}
.contact-status {
width: 24px;
height: 24px;
}
}
.core-user-communication-handlers {
background: $list-background-color;
border-bottom: 1px solid $list-border-color;