Skip to content

Commit

Permalink
Communication: Add profile picture to sidebar element and conversatio…
Browse files Browse the repository at this point in the history
…n header (#9719)
  • Loading branch information
asliayk authored Nov 10, 2024
1 parent bf2fbbd commit cec3866
Show file tree
Hide file tree
Showing 18 changed files with 132 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ export class OneToOneChatDTO extends ConversationDTO {
export function isOneToOneChatDTO(conversation: ConversationDTO): conversation is OneToOneChatDTO {
return conversation.type === ConversationType.ONE_TO_ONE;
}

export function getAsOneToOneChatDTO(conversation: ConversationDTO | undefined): OneToOneChatDTO | undefined {
if (!conversation) {
return undefined;
}
return isOneToOneChatDTO(conversation) ? conversation : undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { GenericConfirmationDialogComponent } from './dialogs/generic-confirmati
import { ConversationSettingsComponent } from './dialogs/conversation-detail-dialog/tabs/conversation-settings/conversation-settings.component';
import { OneToOneChatCreateDialogComponent } from './dialogs/one-to-one-chat-create-dialog/one-to-one-chat-create-dialog.component';
import { GroupChatCreateDialogComponent } from './dialogs/group-chat-create-dialog/group-chat-create-dialog.component';
import { GroupChatIconComponent } from './other/group-chat-icon/group-chat-icon.component';
import { ArtemisMarkdownModule } from 'app/shared/markdown.module';
import { CourseConversationsCodeOfConductComponent } from 'app/overview/course-conversations/code-of-conduct/course-conversations-code-of-conduct.component';
import { CourseWideSearchComponent } from 'app/overview/course-conversations/course-wide-search/course-wide-search.component';
Expand Down Expand Up @@ -79,7 +78,6 @@ const routes: Routes = [
ConversationSettingsComponent,
OneToOneChatCreateDialogComponent,
GroupChatCreateDialogComponent,
GroupChatIconComponent,
CourseWideSearchComponent,
],
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ <h4 class="modal-title">
@if (getAsChannel(activeConversation); as channel) {
<jhi-channel-icon [isPublic]="channel.isPublic!" [isArchived]="channel.isArchived!" [isAnnouncementChannel]="channel.isAnnouncementChannel!" />
}
@if (getAsGroupChat(activeConversation); as groupChat) {
<jhi-group-chat-icon />
@if (getAsGroupChat(activeConversation)) {
<fa-icon [icon]="faPeopleGroup" size="xs" />
}
{{ conversationService.getConversationName(activeConversation, true) }}
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ConversationService } from 'app/shared/metis/conversations/conversation
import { isOneToOneChatDTO } from 'app/entities/metis/conversation/one-to-one-chat.model';
import { getAsGroupChatDTO } from 'app/entities/metis/conversation/group-chat.model';
import { AbstractDialogComponent } from 'app/overview/course-conversations/dialogs/abstract-dialog.component';
import { faPeopleGroup } from '@fortawesome/free-solid-svg-icons';

export enum ConversationDetailTabs {
MEMBERS = 'members',
Expand All @@ -24,6 +25,7 @@ export class ConversationDetailDialogComponent extends AbstractDialogComponent {
@Input() selectedTab: ConversationDetailTabs = ConversationDetailTabs.MEMBERS;

isInitialized = false;
readonly faPeopleGroup = faPeopleGroup;

initialize() {
super.initialize(['course', 'activeConversation', 'selectedTab']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,23 @@ <h4 class="pointer d-inline-block rounded py-2 info mb-0" (click)="openConversat
[isAnnouncementChannel]="activeConversationAsChannel.isAnnouncementChannel!"
/>
}
@if (getAsGroupChat(activeConversation); as groupChat) {
<jhi-group-chat-icon />
@if (getAsGroupChat(activeConversation)) {
<fa-icon [icon]="faPeopleGroup" size="xs" />
}
@if (getAsOneToOneChat(activeConversation) && otherUser) {
<jhi-profile-picture
[imageSizeInRem]="'2'"
[fontSizeInRem]="'0.9'"
[imageId]="'sidebar-profile-picture'"
[defaultPictureId]="'sidebar-default-profile-picture'"
[isGray]="false"
[authorId]="otherUser.id"
[authorName]="otherUser.name"
class="me-2"
[imageUrl]="otherUser.imageUrl"
[isEditable]="false"
>
</jhi-profile-picture>
}
{{ conversationService.getConversationName(activeConversation, true) }}
</h4>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, EventEmitter, OnDestroy, OnInit, Output, inject } from '@angular/core';
import { faChevronLeft, faSearch, faUserGroup, faUserPlus } from '@fortawesome/free-solid-svg-icons';
import { faChevronLeft, faPeopleGroup, faSearch, faUserGroup, faUserPlus } from '@fortawesome/free-solid-svg-icons';
import { ConversationDTO } from 'app/entities/metis/conversation/conversation.model';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { Course } from 'app/entities/course.model';
Expand All @@ -18,6 +18,8 @@ import { defaultFirstLayerDialogOptions, getChannelSubTypeReferenceTranslationKe
import { catchError } from 'rxjs/operators';
import { MetisService } from 'app/shared/metis/metis.service';
import { CourseSidebarService } from 'app/overview/course-sidebar.service';
import { getAsOneToOneChatDTO } from 'app/entities/metis/conversation/one-to-one-chat.model';
import { ConversationUserDTO } from 'app/entities/metis/conversation/conversation-user-dto.model';

@Component({
selector: 'jhi-conversation-header',
Expand All @@ -39,11 +41,13 @@ export class ConversationHeaderComponent implements OnInit, OnDestroy {
activeConversationAsChannel?: ChannelDTO;
channelSubTypeReferenceTranslationKey?: string;
channelSubTypeReferenceRouterLink?: string;
otherUser?: ConversationUserDTO;

faUserPlus = faUserPlus;
faUserGroup = faUserGroup;
faSearch = faSearch;
faChevronLeft = faChevronLeft;
readonly faPeopleGroup = faPeopleGroup;

private courseSidebarService: CourseSidebarService = inject(CourseSidebarService);

Expand All @@ -56,6 +60,7 @@ export class ConversationHeaderComponent implements OnInit, OnDestroy {
) {}

getAsGroupChat = getAsGroupChatDTO;
getAsOneToOneChat = getAsOneToOneChatDTO;

canAddUsers = canAddUsersToConversation;

Expand All @@ -64,6 +69,13 @@ export class ConversationHeaderComponent implements OnInit, OnDestroy {
this.subscribeToActiveConversation();
}

getOtherUser() {
const conversation = getAsOneToOneChatDTO(this.activeConversation);
if (conversation) {
this.otherUser = conversation.members?.find((user) => !user.isRequestingUser);
}
}

ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
Expand All @@ -79,6 +91,7 @@ export class ConversationHeaderComponent implements OnInit, OnDestroy {
this.activeConversationAsChannel = getAsChannelDTO(conversation);
this.channelSubTypeReferenceTranslationKey = getChannelSubTypeReferenceTranslationKey(this.activeConversationAsChannel?.subType);
this.channelSubTypeReferenceRouterLink = this.metisService.getLinkForChannelSubType(this.activeConversationAsChannel);
this.getOtherUser();
});
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@
[class.muted]="sidebarItem.conversation?.isMuted"
[ngClass]="unreadCount() > 0 ? 'fw-bold' : 'fw-normal'"
>
@if (sidebarItem.icon) {
@if (otherUser) {
<jhi-profile-picture
[imageSizeInRem]="'1.1'"
[fontSizeInRem]="'0.5'"
[imageId]="'sidebar-profile-picture'"
[defaultPictureId]="'sidebar-default-profile-picture'"
[isGray]="false"
[authorId]="otherUser.id"
[authorName]="otherUser.name"
[imageUrl]="otherUser.imageUrl"
[isEditable]="false"
>
</jhi-profile-picture>
} @else if (sidebarItem.icon) {
<fa-icon [fixedWidth]="true" [icon]="sidebarItem.icon" />
}
{{ sidebarItem.title }}</span
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges, input } from '@angular/core';
import { SidebarCardElement, SidebarTypes } from 'app/types/sidebar';
import { OneToOneChatDTO } from 'app/entities/metis/conversation/one-to-one-chat.model';
import { faPeopleGroup } from '@fortawesome/free-solid-svg-icons';

@Component({
selector: 'jhi-sidebar-card-item',
Expand All @@ -11,11 +13,15 @@ export class SidebarCardItemComponent implements OnInit, OnChanges {
@Input() sidebarType?: SidebarTypes;
@Input() groupKey?: string;
unreadCount = input<number>(0);
otherUser: any;

readonly faPeopleGroup = faPeopleGroup;

formattedUnreadCount: string = '';

ngOnInit(): void {
this.formattedUnreadCount = this.getFormattedUnreadCount();
this.extractMessageUser();
}

ngOnChanges(changes: SimpleChanges): void {
Expand All @@ -30,4 +36,16 @@ export class SidebarCardItemComponent implements OnInit, OnChanges {
}
return this.unreadCount().toString() || '';
}

extractMessageUser(): void {
if (this.sidebarItem.type === 'oneToOneChat' && (this.sidebarItem.conversation as OneToOneChatDTO)?.members) {
this.otherUser = (this.sidebarItem.conversation as OneToOneChatDTO).members!.find((user) => !user.isRequestingUser);
} else {
this.otherUser = null;
}

if (this.sidebarItem.type === 'groupChat') {
this.sidebarItem.icon = this.faPeopleGroup;
}
}
}
2 changes: 1 addition & 1 deletion src/main/webapp/app/shared/sidebar/sidebar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<span jhiTranslate="artemisApp.courseOverview.sidebar.createDirectChat"></span>
</button>
<button (click)="createGroupChat()" class="p-2" ngbDropdownItem>
<fa-icon [icon]="faUsers" class="item-icon" [fixedWidth]="true"></fa-icon>
<fa-icon [icon]="faPeopleGroup" class="item-icon" [fixedWidth]="true"></fa-icon>
<span jhiTranslate="artemisApp.courseOverview.sidebar.createGroupChat"></span>
</button>
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/webapp/app/shared/sidebar/sidebar.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, effect, input, output } from '@angular/core';
import { faFilter, faFilterCircleXmark, faHashtag, faPlusCircle, faSearch, faUser, faUsers } from '@fortawesome/free-solid-svg-icons';
import { faFilter, faFilterCircleXmark, faHashtag, faPeopleGroup, faPlusCircle, faSearch, faUser } from '@fortawesome/free-solid-svg-icons';
import { ActivatedRoute, Params } from '@angular/router';
import { Subscription, distinctUntilChanged } from 'rxjs';
import { ProfileService } from '../layouts/profiles/profile.service';
Expand Down Expand Up @@ -57,7 +57,7 @@ export class SidebarComponent implements OnDestroy, OnChanges, OnInit {
readonly faFilter = faFilter;
readonly faFilterCurrentlyApplied = faFilterCircleXmark;
readonly faUser = faUser;
readonly faUsers = faUsers;
readonly faPeopleGroup = faPeopleGroup;
readonly faPlusCircle = faPlusCircle;
readonly faSearch = faSearch;
readonly faHashtag = faHashtag;
Expand Down
2 changes: 2 additions & 0 deletions src/main/webapp/app/shared/sidebar/sidebar.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SidebarCardDirective } from 'app/shared/sidebar/sidebar-card.directive'
import { ConversationOptionsComponent } from 'app/shared/sidebar/conversation-options/conversation-options.component';
import { ArtemisExamSharedModule } from 'app/exam/shared/exam-shared.module';
import { SearchFilterComponent } from 'app/shared/search-filter/search-filter.component';
import { ProfilePictureComponent } from 'app/shared/profile-picture/profile-picture.component';

@NgModule({
imports: [
Expand All @@ -29,6 +30,7 @@ import { SearchFilterComponent } from 'app/shared/search-filter/search-filter.co
SidebarCardDirective,
ArtemisExamSharedModule,
SearchFilterComponent,
ProfilePictureComponent,
],
declarations: [
SidebarAccordionComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { AddUsersFormData } from 'app/overview/course-conversations/dialogs/conv
import { initializeDialog } from '../dialog-test-helpers';
import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
import { ChannelIconComponent } from 'app/overview/course-conversations/other/channel-icon/channel-icon.component';
import { GroupChatIconComponent } from 'app/overview/course-conversations/other/group-chat-icon/group-chat-icon.component';
import { UserPublicInfoDTO } from 'app/core/user/user.model';
import { By } from '@angular/platform-browser';
import { isChannelDTO } from 'app/entities/metis/conversation/channel.model';
Expand Down Expand Up @@ -42,13 +41,7 @@ examples.forEach((activeConversation) => {

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
ConversationAddUsersDialogComponent,
ConversationAddUsersFormStubComponent,
MockPipe(ArtemisTranslatePipe),
MockComponent(ChannelIconComponent),
MockComponent(GroupChatIconComponent),
],
declarations: [ConversationAddUsersDialogComponent, ConversationAddUsersFormStubComponent, MockPipe(ArtemisTranslatePipe), MockComponent(ChannelIconComponent)],
providers: [
MockProvider(AlertService),
MockProvider(NgbActiveModal),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Course } from 'app/entities/course.model';
import { ConversationDTO } from 'app/entities/metis/conversation/conversation.model';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import {
ConversationDetailDialogComponent,
ConversationDetailTabs,
Expand All @@ -9,7 +10,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
import { MockComponent, MockPipe, MockProvider } from 'ng-mocks';
import { ChannelIconComponent } from 'app/overview/course-conversations/other/channel-icon/channel-icon.component';
import { GroupChatIconComponent } from 'app/overview/course-conversations/other/group-chat-icon/group-chat-icon.component';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ConversationService } from 'app/shared/metis/conversations/conversation.service';
import { generateExampleChannelDTO, generateExampleGroupChatDTO, generateOneToOneChatDTO } from '../../helpers/conversationExampleModels';
Expand Down Expand Up @@ -82,8 +82,8 @@ examples.forEach((activeConversation) => {
ConversationInfoStubComponent,
MockPipe(ArtemisTranslatePipe),
MockComponent(ChannelIconComponent),
MockComponent(GroupChatIconComponent),
],
imports: [FontAwesomeModule],
providers: [MockProvider(NgbActiveModal), MockProvider(ConversationService)],
}).compileComponents();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ConversationHeaderComponent } from 'app/overview/course-conversations/l
import { Location } from '@angular/common';
import { MockComponent, MockPipe, MockProvider } from 'ng-mocks';
import { ChannelIconComponent } from 'app/overview/course-conversations/other/channel-icon/channel-icon.component';
import { GroupChatIconComponent } from 'app/overview/course-conversations/other/group-chat-icon/group-chat-icon.component';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
Expand All @@ -28,6 +27,7 @@ import { MetisModule } from 'app/shared/metis/metis.module';
import { MockTranslateService } from '../../../../../helpers/mocks/service/mock-translate.service';
import { TranslateService } from '@ngx-translate/core';
import { provideRouter } from '@angular/router';
import { ProfilePictureComponent } from '../../../../../../../../main/webapp/app/shared/profile-picture/profile-picture.component';

const examples: ConversationDTO[] = [
generateOneToOneChatDTO({}),
Expand All @@ -51,7 +51,7 @@ examples.forEach((activeConversation) => {
declarations: [
ConversationHeaderComponent,
MockComponent(ChannelIconComponent),
MockComponent(GroupChatIconComponent),
MockComponent(ProfilePictureComponent),
MockComponent(FaIconComponent),
MockPipe(ArtemisTranslatePipe),
],
Expand Down Expand Up @@ -138,6 +138,19 @@ examples.forEach((activeConversation) => {
});
}));

it('should set otherUser to the non-requesting user in a one-to-one conversation', () => {
const oneToOneChat = generateOneToOneChatDTO({});
oneToOneChat.members = [
{ id: 1, isRequestingUser: true },
{ id: 2, isRequestingUser: false },
];

component.activeConversation = oneToOneChat;
component.getOtherUser();

expect(component.otherUser).toEqual(oneToOneChat.members[1]);
});

if (activeConversation instanceof ChannelDTO && activeConversation.subType !== ChannelSubType.GENERAL) {
it(
'should navigate to ' + activeConversation.subType,
Expand Down

This file was deleted.

Loading

0 comments on commit cec3866

Please sign in to comment.