MOBILE-3142 chat: Change chat look and feel
This commit is contained in:
		
							parent
							
								
									efcb7af1a9
								
							
						
					
					
						commit
						4c151051eb
					
				@ -4,8 +4,7 @@ $item-message-note-text: $gray-dark !default;
 | 
				
			|||||||
$item-message-note-font-size: 75% !default;
 | 
					$item-message-note-font-size: 75% !default;
 | 
				
			||||||
$item-message-mine-bg: $gray-light !default;
 | 
					$item-message-mine-bg: $gray-light !default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ion-app.app-root page-addon-messages-discussion.ion-page {
 | 
					@mixin message-page {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ion-content {
 | 
					    ion-content {
 | 
				
			||||||
        background-color: $gray-lighter !important;
 | 
					        background-color: $gray-lighter !important;
 | 
				
			||||||
        @include darkmode() {
 | 
					        @include darkmode() {
 | 
				
			||||||
@ -194,6 +193,12 @@ ion-app.app-root page-addon-messages-discussion.ion-page {
 | 
				
			|||||||
    .addon-message-not-mine.activated .tail {
 | 
					    .addon-message-not-mine.activated .tail {
 | 
				
			||||||
        border-bottom-color: darken($item-message-bg, 10%);
 | 
					        border-bottom-color: darken($item-message-bg, 10%);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ion-app.app-root page-addon-messages-discussion.ion-page {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @include message-page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .toolbar-title {
 | 
					    .toolbar-title {
 | 
				
			||||||
        padding: 0;
 | 
					        padding: 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -9,10 +9,12 @@
 | 
				
			|||||||
    "errorwhilegettingchatusers": "Error while getting chat users.",
 | 
					    "errorwhilegettingchatusers": "Error while getting chat users.",
 | 
				
			||||||
    "errorwhileretrievingmessages": "Error while retrieving messages from the server.",
 | 
					    "errorwhileretrievingmessages": "Error while retrieving messages from the server.",
 | 
				
			||||||
    "errorwhilesendingmessage": "Error while sending the message.",
 | 
					    "errorwhilesendingmessage": "Error while sending the message.",
 | 
				
			||||||
 | 
					    "messagebeepseveryone": "{{$a}} beeps everyone!",
 | 
				
			||||||
    "messagebeepsyou": "{{$a}} has just beeped you!",
 | 
					    "messagebeepsyou": "{{$a}} has just beeped you!",
 | 
				
			||||||
    "messageenter": "{{$a}} has just entered this chat",
 | 
					    "messageenter": "{{$a}} has just entered this chat",
 | 
				
			||||||
    "messageexit": "{{$a}} has left this chat",
 | 
					    "messageexit": "{{$a}} has left this chat",
 | 
				
			||||||
    "messages": "Messages",
 | 
					    "messages": "Messages",
 | 
				
			||||||
 | 
					    "messageyoubeep": "You beeped {{$a}}",
 | 
				
			||||||
    "modulenameplural": "Chats",
 | 
					    "modulenameplural": "Chats",
 | 
				
			||||||
    "mustbeonlinetosendmessages": "You must be online to send messages.",
 | 
					    "mustbeonlinetosendmessages": "You must be online to send messages.",
 | 
				
			||||||
    "nomessages": "No messages yet",
 | 
					    "nomessages": "No messages yet",
 | 
				
			||||||
 | 
				
			|||||||
@ -10,53 +10,61 @@
 | 
				
			|||||||
</ion-header>
 | 
					</ion-header>
 | 
				
			||||||
<ion-content class="has-footer">
 | 
					<ion-content class="has-footer">
 | 
				
			||||||
    <core-loading [hideUntil]="loaded">
 | 
					    <core-loading [hideUntil]="loaded">
 | 
				
			||||||
        <div aria-live="polite">
 | 
					        <ion-list class="addon-messages-discussion-container safe-area-page" aria-live="polite">
 | 
				
			||||||
            <div *ngFor="let message of messages; index as index; last as last">
 | 
					            <ng-container *ngFor="let message of messages; index as index; last as last">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <div text-center *ngIf="showDate(messages[index], messages[index - 1])" class="addon-mod-chat-notice">
 | 
					                <h6 text-center *ngIf="message.showDate" class="addon-messages-date">
 | 
				
			||||||
                    <ion-badge text-wrap color="light">
 | 
					                    {{ message.timestamp * 1000 | coreFormatDate:"strftimedayshort" }}
 | 
				
			||||||
                        <span>{{ message.timestamp * 1000 | coreFormatDate:"strftimedayshort" }}</span>
 | 
					                </h6>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <div text-center *ngIf="message.special" class="addon-mod-chat-notice">
 | 
				
			||||||
 | 
					                    <ion-badge text-wrap color="success" *ngIf="message.system && message.message == 'enter'">
 | 
				
			||||||
 | 
					                        <span><core-icon name="fa-sign-in"></core-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }}</span>
 | 
				
			||||||
 | 
					                    </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <ion-badge text-wrap color="danger" *ngIf="message.system && message.message == 'exit'">
 | 
				
			||||||
 | 
					                        <span><core-icon name="fa-sign-out"></core-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }}</span>
 | 
				
			||||||
 | 
					                    </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <ion-badge text-wrap color="primary" *ngIf="message.beep == 'all'">
 | 
				
			||||||
 | 
					                        <span><ion-icon name="notifications"></ion-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
				
			||||||
 | 
					                        {{ 'addon.mod_chat.messagebeepseveryone' | translate:{$a: message.userfullname} }} </span>
 | 
				
			||||||
 | 
					                    </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <ion-badge text-wrap color="primary" *ngIf="message.userid != currentUserId && message.beep == currentUserId">
 | 
				
			||||||
 | 
					                        <span><ion-icon name="notifications"></ion-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
				
			||||||
 | 
					                        {{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }} </span>
 | 
				
			||||||
 | 
					                    </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <ion-badge text-wrap color="light" *ngIf="message.userid == currentUserId && message.beep && message.beep != 'all'">
 | 
				
			||||||
 | 
					                        <span><ion-icon name="notifications"></ion-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
				
			||||||
 | 
					                        {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepwho} }} </span>
 | 
				
			||||||
                    </ion-badge>
 | 
					                    </ion-badge>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <div text-center *ngIf="message.system && message.message == 'enter'" class="addon-mod-chat-notice">
 | 
					                <ion-item text-wrap *ngIf="!message.special" class="addon-message" [class.addon-message-mine]="message.userid == currentUserId" [class.addon-message-not-mine]="message.userid != currentUserId" [class.addon-message-no-user]="!message.showUserData" [@coreSlideInOut]="message.userid == currentUserId ? '' : 'fromLeft'">
 | 
				
			||||||
                    <ion-badge text-wrap color="light">
 | 
					                    <!-- User data. -->
 | 
				
			||||||
                        <span>{{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }}</span>
 | 
					                    <h2 class="addon-message-user">
 | 
				
			||||||
                    </ion-badge>
 | 
					                        <ion-avatar item-start core-user-avatar [user]="message" [linkProfile]="false" *ngIf="message.showUserData"></ion-avatar>
 | 
				
			||||||
                </div>
 | 
					                        <div *ngIf="message.showUserData">{{ message.userfullname }}</div>
 | 
				
			||||||
 | 
					                        <ion-note>{{ message.timestamp * 1000 | coreFormatDate: "strftimetime" }}</ion-note>
 | 
				
			||||||
                <div text-center *ngIf="message.system && message.message == 'exit'" class="addon-mod-chat-notice">
 | 
					 | 
				
			||||||
                    <ion-badge text-wrap color="light">
 | 
					 | 
				
			||||||
                        <span>{{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }}</span>
 | 
					 | 
				
			||||||
                    </ion-badge>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <div text-center *ngIf="message.message == currentUserBeep" class="addon-mod-chat-notice">
 | 
					 | 
				
			||||||
                    <ion-badge text-wrap color="light">
 | 
					 | 
				
			||||||
                        <span>{{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }}</span>
 | 
					 | 
				
			||||||
                    </ion-badge>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <ion-item text-wrap *ngIf="!message.system && message.message.substr(0, 4) != 'beep'" class="addon-mod-chat-message">
 | 
					 | 
				
			||||||
                    <ion-avatar core-user-avatar [user]="message" item-start></ion-avatar>
 | 
					 | 
				
			||||||
                    <h2>
 | 
					 | 
				
			||||||
                        <p float-end>{{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}</p>
 | 
					 | 
				
			||||||
                        <core-format-text [text]="message.userfullname"></core-format-text>
 | 
					 | 
				
			||||||
                    </h2>
 | 
					                    </h2>
 | 
				
			||||||
                    <core-format-text [text]="message.message" (afterRender)="last && scrollToBottom()"></core-format-text>
 | 
					 | 
				
			||||||
                </ion-item>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div text-center margin *ngIf="!messages || messages.length <= 0">
 | 
					                    <p class="addon-message-text">
 | 
				
			||||||
                <p>{{ 'addon.mod_chat.nomessages' | translate}}</p>
 | 
					                        <core-format-text [text]="message.message" (afterRender)="last && scrollToBottom()"></core-format-text>
 | 
				
			||||||
            </div>
 | 
					                    </p>
 | 
				
			||||||
        </div>
 | 
					                    <div class="tail" *ngIf="message.showTail"></div>
 | 
				
			||||||
 | 
					                </ion-item>
 | 
				
			||||||
 | 
					            </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </ion-list>
 | 
				
			||||||
 | 
					        <core-empty-box *ngIf="!messages || messages.length <= 0" icon="chatbubbles" [message]="'addon.mod_chat.nomessages' | translate"></core-empty-box>
 | 
				
			||||||
    </core-loading>
 | 
					    </core-loading>
 | 
				
			||||||
</ion-content>
 | 
					</ion-content>
 | 
				
			||||||
<ion-footer color="light" class="footer-adjustable">
 | 
					<ion-footer color="light" class="footer-adjustable">
 | 
				
			||||||
    <ion-toolbar color="light" position="bottom">
 | 
					    <ion-toolbar color="light" position="bottom">
 | 
				
			||||||
        <p text-center *ngIf="!isOnline">{{ 'addon.mod_chat.mustbeonlinetosendmessages' | translate }}</p>
 | 
					        <p text-center *ngIf="!isOnline">{{ 'addon.mod_chat.mustbeonlinetosendmessages' | translate }}</p>
 | 
				
			||||||
        <core-send-message-form *ngIf="isOnline && polling && loaded" [message]="newMessage" (onSubmit)="sendMessage($event)" [showKeyboard]="showKeyboard" [placeholder]="'addon.messages.newmessage' | translate" (onResize)="resizeContent()"></core-send-message-form>
 | 
					        <core-send-message-form [sendDisabled]="sending" *ngIf="isOnline && polling && loaded" [message]="newMessage" (onSubmit)="sendMessage($event)" [showKeyboard]="showKeyboard" [placeholder]="'addon.messages.newmessage' | translate" (onResize)="resizeContent()"></core-send-message-form>
 | 
				
			||||||
        <button *ngIf="isOnline && !polling && loaded" (click)="reconnect()" ion-button block color="light">{{ 'core.login.reconnect' | translate }}</button>
 | 
					        <button *ngIf="isOnline && !polling && loaded" (click)="reconnect()" ion-button block color="light">{{ 'core.login.reconnect' | translate }}</button>
 | 
				
			||||||
    </ion-toolbar>
 | 
					    </ion-toolbar>
 | 
				
			||||||
</ion-footer>
 | 
					</ion-footer>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,8 @@
 | 
				
			|||||||
ion-app.app-root page-addon-mod-chat-chat {
 | 
					ion-app.app-root page-addon-mod-chat-chat {
 | 
				
			||||||
 | 
					    @include message-page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .addon-mod-chat-notice {
 | 
					    .addon-mod-chat-notice {
 | 
				
			||||||
        margin-top: 10px;
 | 
					        margin-top: 10px;
 | 
				
			||||||
        margin-bottom: 10px;
 | 
					        margin-bottom: 10px;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    .addon-mod-chat-message {
 | 
					 | 
				
			||||||
        align-items: flex-start;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,6 +22,8 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom';
 | 
				
			|||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
 | 
					import { CoreTextUtilsProvider } from '@providers/utils/text';
 | 
				
			||||||
import { AddonModChatProvider, AddonModChatMessageWithUserData } from '../../providers/chat';
 | 
					import { AddonModChatProvider, AddonModChatMessageWithUserData } from '../../providers/chat';
 | 
				
			||||||
import { Network } from '@ionic-native/network';
 | 
					import { Network } from '@ionic-native/network';
 | 
				
			||||||
 | 
					import { coreSlideInOut } from '@classes/animations';
 | 
				
			||||||
 | 
					import { CoreSendMessageFormComponent } from '@components/send-message-form/send-message-form';
 | 
				
			||||||
import * as moment from 'moment';
 | 
					import * as moment from 'moment';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -31,9 +33,11 @@ import * as moment from 'moment';
 | 
				
			|||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
    selector: 'page-addon-mod-chat-chat',
 | 
					    selector: 'page-addon-mod-chat-chat',
 | 
				
			||||||
    templateUrl: 'chat.html',
 | 
					    templateUrl: 'chat.html',
 | 
				
			||||||
 | 
					    animations: [coreSlideInOut]
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class AddonModChatChatPage {
 | 
					export class AddonModChatChatPage {
 | 
				
			||||||
    @ViewChild(Content) content: Content;
 | 
					    @ViewChild(Content) content: Content;
 | 
				
			||||||
 | 
					    @ViewChild(CoreSendMessageFormComponent) sendMessageForm: CoreSendMessageFormComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loaded = false;
 | 
					    loaded = false;
 | 
				
			||||||
    title: string;
 | 
					    title: string;
 | 
				
			||||||
@ -41,7 +45,8 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
    newMessage: string;
 | 
					    newMessage: string;
 | 
				
			||||||
    polling: any;
 | 
					    polling: any;
 | 
				
			||||||
    isOnline: boolean;
 | 
					    isOnline: boolean;
 | 
				
			||||||
    currentUserBeep: string;
 | 
					    currentUserId: number;
 | 
				
			||||||
 | 
					    sending: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected logger;
 | 
					    protected logger;
 | 
				
			||||||
    protected courseId: number;
 | 
					    protected courseId: number;
 | 
				
			||||||
@ -53,6 +58,7 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
    protected keyboardObserver: any;
 | 
					    protected keyboardObserver: any;
 | 
				
			||||||
    protected viewDestroyed = false;
 | 
					    protected viewDestroyed = false;
 | 
				
			||||||
    protected pollingRunning = false;
 | 
					    protected pollingRunning = false;
 | 
				
			||||||
 | 
					    protected users = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(navParams: NavParams, logger: CoreLoggerProvider, network: Network,  zone: NgZone, private navCtrl: NavController,
 | 
					    constructor(navParams: NavParams, logger: CoreLoggerProvider, network: Network,  zone: NgZone, private navCtrl: NavController,
 | 
				
			||||||
            private chatProvider: AddonModChatProvider, private appProvider: CoreAppProvider, sitesProvider: CoreSitesProvider,
 | 
					            private chatProvider: AddonModChatProvider, private appProvider: CoreAppProvider, sitesProvider: CoreSitesProvider,
 | 
				
			||||||
@ -63,7 +69,7 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
        this.courseId = navParams.get('courseId');
 | 
					        this.courseId = navParams.get('courseId');
 | 
				
			||||||
        this.title = navParams.get('title');
 | 
					        this.title = navParams.get('title');
 | 
				
			||||||
        this.logger = logger.getInstance('AddonModChoiceChoicePage');
 | 
					        this.logger = logger.getInstance('AddonModChoiceChoicePage');
 | 
				
			||||||
        this.currentUserBeep = 'beep ' + sitesProvider.getCurrentSiteUserId();
 | 
					        this.currentUserId = sitesProvider.getCurrentSiteUserId();
 | 
				
			||||||
        this.isOnline = this.appProvider.isOnline();
 | 
					        this.isOnline = this.appProvider.isOnline();
 | 
				
			||||||
        this.onlineObserver = network.onchange().subscribe(() => {
 | 
					        this.onlineObserver = network.onchange().subscribe(() => {
 | 
				
			||||||
            // Execute the callback in the Angular zone, so change detection doesn't stop working.
 | 
					            // Execute the callback in the Angular zone, so change detection doesn't stop working.
 | 
				
			||||||
@ -127,11 +133,14 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        modal.onDidDismiss((data) => {
 | 
					        modal.onDidDismiss((data) => {
 | 
				
			||||||
            if (data && data.talkTo) {
 | 
					            if (data && data.talkTo) {
 | 
				
			||||||
                this.newMessage = `To ${data.talkTo}: `;
 | 
					                this.newMessage = `To ${data.talkTo}: ` + this.sendMessageForm.message;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (data && data.beepTo) {
 | 
					            if (data && data.beepTo) {
 | 
				
			||||||
                this.sendMessage('', data.beepTo);
 | 
					                this.sendMessage('', data.beepTo);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            if (data && data.users) {
 | 
				
			||||||
 | 
					                this.users = data.users;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        modal.present({
 | 
					        modal.present({
 | 
				
			||||||
@ -139,6 +148,38 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the user fullname for a beep.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  id User Id before parsing.
 | 
				
			||||||
 | 
					     * @return User fullname.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected getUserFullname(id: string): Promise<string> {
 | 
				
			||||||
 | 
					        if (isNaN(parseInt(id, 10))) {
 | 
				
			||||||
 | 
					            return Promise.resolve(id);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const user = this.users.find((user) => user.id == id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (user) {
 | 
				
			||||||
 | 
					            return Promise.resolve(user.fullname);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this.chatProvider.getChatUsers(this.sessionId).then((data) => {
 | 
				
			||||||
 | 
					            this.users = data.users;
 | 
				
			||||||
 | 
					            const user = this.users.find((user) => user.id == id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (user) {
 | 
				
			||||||
 | 
					                return user.fullname;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return id;
 | 
				
			||||||
 | 
					        }).catch((error) => {
 | 
				
			||||||
 | 
					            // Ignore errors.
 | 
				
			||||||
 | 
					            return id;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Convenience function to login the user.
 | 
					     * Convenience function to login the user.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -160,8 +201,33 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
            this.lastTime = messagesInfo.chatnewlasttime || 0;
 | 
					            this.lastTime = messagesInfo.chatnewlasttime || 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return this.chatProvider.getMessagesUserData(messagesInfo.messages, this.courseId).then((messages) => {
 | 
					            return this.chatProvider.getMessagesUserData(messagesInfo.messages, this.courseId).then((messages) => {
 | 
				
			||||||
                this.messages = this.messages.concat(<AddonModChatMessageWithUserData[]> messages);
 | 
					 | 
				
			||||||
                if (messages.length) {
 | 
					                if (messages.length) {
 | 
				
			||||||
 | 
					                    const previousLength = this.messages.length;
 | 
				
			||||||
 | 
					                    this.messages = this.messages.concat(<AddonModChatMessageWithUserData[]> messages);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // Calculate which messages need to display the date or user data.
 | 
				
			||||||
 | 
					                    for (let index = previousLength ; index < this.messages.length; index++) {
 | 
				
			||||||
 | 
					                        const message = this.messages[index];
 | 
				
			||||||
 | 
					                        const prevMessage = index > 0 ? this.messages[index - 1] : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        message.showDate = this.showDate(message, prevMessage);
 | 
				
			||||||
 | 
					                        message.beep = message.message.substr(0, 5) == 'beep ' && message.message.substr(5).trim();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (message.beep && message.beep != this.currentUserId) {
 | 
				
			||||||
 | 
					                            this.getUserFullname(message.beep).then((fullname) => {
 | 
				
			||||||
 | 
					                                message.beepwho = fullname;
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        message.special = message.system || !!message.beep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        message.showUserData = this.showUserData(message, prevMessage);
 | 
				
			||||||
 | 
					                        prevMessage ?
 | 
				
			||||||
 | 
					                            prevMessage.showTail = this.showTail(prevMessage, message) : null;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.messages[this.messages.length - 1].showTail = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // New messages or beeps, scroll to bottom.
 | 
					                    // New messages or beeps, scroll to bottom.
 | 
				
			||||||
                    setTimeout(() => this.scrollToBottom());
 | 
					                    setTimeout(() => this.scrollToBottom());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -196,6 +262,30 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if the user info should be displayed for the current message.
 | 
				
			||||||
 | 
					     * User data is only displayed if the previous message was from another user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param message Current message where to show the user info.
 | 
				
			||||||
 | 
					     * @param prevMessage Previous message.
 | 
				
			||||||
 | 
					     * @return Whether user data should be shown.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    showUserData(message: any, prevMessage?: any): boolean {
 | 
				
			||||||
 | 
					        return message.userid != this.currentUserId &&
 | 
				
			||||||
 | 
					            (!prevMessage || prevMessage.userid != message.userid || message.showDate || prevMessage.special);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if a css tail should be shown.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param message Current message where to show the user info.
 | 
				
			||||||
 | 
					     * @param nextMessage Next message.
 | 
				
			||||||
 | 
					     * @return Whether user data should be shown.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    showTail(message: any, nextMessage?: any): boolean {
 | 
				
			||||||
 | 
					        return !nextMessage || nextMessage.userid != message.userid || nextMessage.showDate || nextMessage.special;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Convenience function to be called every certain time to fetch chat messages.
 | 
					     * Convenience function to be called every certain time to fetch chat messages.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -259,9 +349,8 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
            // Silent error.
 | 
					            // Silent error.
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        text = this.textUtils.replaceNewLines(text, '<br>');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const modal = this.domUtils.showModalLoading('core.sending', true);
 | 
					        this.sending = true;
 | 
				
			||||||
        this.chatProvider.sendMessage(this.sessionId, text, beep).then(() => {
 | 
					        this.chatProvider.sendMessage(this.sessionId, text, beep).then(() => {
 | 
				
			||||||
            // Update messages to show the sent message.
 | 
					            // Update messages to show the sent message.
 | 
				
			||||||
            this.fetchMessagesInterval().catch(() => {
 | 
					            this.fetchMessagesInterval().catch(() => {
 | 
				
			||||||
@ -272,9 +361,12 @@ export class AddonModChatChatPage {
 | 
				
			|||||||
              messages without the keyboard being closed. */
 | 
					              messages without the keyboard being closed. */
 | 
				
			||||||
            this.appProvider.closeKeyboard();
 | 
					            this.appProvider.closeKeyboard();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.newMessage = text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.domUtils.showErrorModalDefault(error, 'addon.mod_chat.errorwhilesendingmessage', true);
 | 
					            this.domUtils.showErrorModalDefault(error, 'addon.mod_chat.errorwhilesendingmessage', true);
 | 
				
			||||||
        }).finally(() => {
 | 
					        }).finally(() => {
 | 
				
			||||||
            modal.dismiss();
 | 
					            this.sending = false;
 | 
				
			||||||
 | 
					            this.sendMessageForm.focus();
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -69,7 +69,7 @@ export class AddonModChatUsersPage {
 | 
				
			|||||||
     * Close the chat users modal.
 | 
					     * Close the chat users modal.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    closeModal(): void {
 | 
					    closeModal(): void {
 | 
				
			||||||
        this.viewCtrl.dismiss();
 | 
					        this.viewCtrl.dismiss({users: this.users});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -78,7 +78,7 @@ export class AddonModChatUsersPage {
 | 
				
			|||||||
     * @param user User object.
 | 
					     * @param user User object.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    talkTo(user: AddonModChatUser): void {
 | 
					    talkTo(user: AddonModChatUser): void {
 | 
				
			||||||
        this.viewCtrl.dismiss({talkTo: user.fullname});
 | 
					        this.viewCtrl.dismiss({talkTo: user.fullname, users: this.users});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -87,7 +87,7 @@ export class AddonModChatUsersPage {
 | 
				
			|||||||
     * @param user User object.
 | 
					     * @param user User object.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    beepTo(user: AddonModChatUser): void {
 | 
					    beepTo(user: AddonModChatUser): void {
 | 
				
			||||||
        this.viewCtrl.dismiss({beepTo: user.id});
 | 
					        this.viewCtrl.dismiss({beepTo: user.id, users: this.users});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -432,10 +432,12 @@
 | 
				
			|||||||
    "addon.mod_chat.errorwhilegettingchatusers": "Error while getting chat users.",
 | 
					    "addon.mod_chat.errorwhilegettingchatusers": "Error while getting chat users.",
 | 
				
			||||||
    "addon.mod_chat.errorwhileretrievingmessages": "Error while retrieving messages from the server.",
 | 
					    "addon.mod_chat.errorwhileretrievingmessages": "Error while retrieving messages from the server.",
 | 
				
			||||||
    "addon.mod_chat.errorwhilesendingmessage": "Error while sending the message.",
 | 
					    "addon.mod_chat.errorwhilesendingmessage": "Error while sending the message.",
 | 
				
			||||||
 | 
					    "addon.mod_chat.messagebeepseveryone": "{{$a}} beeps everyone!",
 | 
				
			||||||
    "addon.mod_chat.messagebeepsyou": "{{$a}} has just beeped you!",
 | 
					    "addon.mod_chat.messagebeepsyou": "{{$a}} has just beeped you!",
 | 
				
			||||||
    "addon.mod_chat.messageenter": "{{$a}} has just entered this chat",
 | 
					    "addon.mod_chat.messageenter": "{{$a}} has just entered this chat",
 | 
				
			||||||
    "addon.mod_chat.messageexit": "{{$a}} has left this chat",
 | 
					    "addon.mod_chat.messageexit": "{{$a}} has left this chat",
 | 
				
			||||||
    "addon.mod_chat.messages": "Messages",
 | 
					    "addon.mod_chat.messages": "Messages",
 | 
				
			||||||
 | 
					    "addon.mod_chat.messageyoubeep": "You beeped {{$a}}",
 | 
				
			||||||
    "addon.mod_chat.modulenameplural": "Chats",
 | 
					    "addon.mod_chat.modulenameplural": "Chats",
 | 
				
			||||||
    "addon.mod_chat.mustbeonlinetosendmessages": "You must be online to send messages.",
 | 
					    "addon.mod_chat.mustbeonlinetosendmessages": "You must be online to send messages.",
 | 
				
			||||||
    "addon.mod_chat.nomessages": "No messages yet",
 | 
					    "addon.mod_chat.nomessages": "No messages yet",
 | 
				
			||||||
 | 
				
			|||||||
@ -60,7 +60,8 @@ ion-app.app-root core-ion-tabs {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .scroll-content, .fixed-content {
 | 
					        ion-content:not(.has-footer) > .scroll-content,
 | 
				
			||||||
 | 
					        ion-content:not(.has-footer) > .fixed-content {
 | 
				
			||||||
            margin-bottom: 0 !important;
 | 
					            margin-bottom: 0 !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<form>
 | 
					<form>
 | 
				
			||||||
    <textarea class="core-send-message-input" [core-auto-focus]="showKeyboard" [placeholder]="placeholder" rows="1" core-auto-rows [(ngModel)]="message" name="message" (onResize)="textareaResized()" (keydown.enter)="enterClicked($event)" (keydown.control.enter)="enterClicked($event, 'control')" (keydown.meta.enter)="enterClicked($event, 'meta')" aria-multiline="true"></textarea>
 | 
					    <textarea class="core-send-message-input" [core-auto-focus]="showKeyboard" [placeholder]="placeholder" rows="1" core-auto-rows [(ngModel)]="message" name="message" (onResize)="textareaResized()" (keydown.enter)="enterClicked($event)" (keydown.control.enter)="enterClicked($event, 'control')" (keydown.meta.enter)="enterClicked($event, 'meta')" aria-multiline="true"></textarea>
 | 
				
			||||||
    <ion-buttons end>
 | 
					    <ion-buttons end>
 | 
				
			||||||
        <button ion-button icon-only clear="true" type="submit" [disabled]="!message" [attr.aria-label]="'core.send' | translate" [core-suppress-events] (onClick)="submitForm($event)">
 | 
					        <button ion-button icon-only clear="true" type="submit" [disabled]="!message || sendDisabled" [attr.aria-label]="'core.send' | translate" [core-suppress-events] (onClick)="submitForm($event)">
 | 
				
			||||||
            <ion-icon name="send" color="dark"></ion-icon>
 | 
					            <ion-icon name="send" color="dark"></ion-icon>
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
    </ion-buttons>
 | 
					    </ion-buttons>
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ import { CoreEventsProvider } from '@providers/events';
 | 
				
			|||||||
import { CoreSitesProvider } from '@providers/sites';
 | 
					import { CoreSitesProvider } from '@providers/sites';
 | 
				
			||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
 | 
					import { CoreUtilsProvider } from '@providers/utils/utils';
 | 
				
			||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
 | 
					import { CoreTextUtilsProvider } from '@providers/utils/text';
 | 
				
			||||||
 | 
					import { CoreDomUtilsProvider } from '@providers/utils/dom';
 | 
				
			||||||
import { CoreConstants } from '@core/constants';
 | 
					import { CoreConstants } from '@core/constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -39,13 +40,15 @@ export class CoreSendMessageFormComponent implements OnInit {
 | 
				
			|||||||
    @Input() message: string; // Input text.
 | 
					    @Input() message: string; // Input text.
 | 
				
			||||||
    @Input() placeholder = ''; // Placeholder for the input area.
 | 
					    @Input() placeholder = ''; // Placeholder for the input area.
 | 
				
			||||||
    @Input() showKeyboard = false; // If keyboard is shown or not.
 | 
					    @Input() showKeyboard = false; // If keyboard is shown or not.
 | 
				
			||||||
 | 
					    @Input() sendDisabled = false; // If send is disabled.
 | 
				
			||||||
    @Output() onSubmit: EventEmitter<string>; // Send data when submitting the message form.
 | 
					    @Output() onSubmit: EventEmitter<string>; // Send data when submitting the message form.
 | 
				
			||||||
    @Output() onResize: EventEmitter<void>; // Emit when resizing the textarea.
 | 
					    @Output() onResize: EventEmitter<void>; // Emit when resizing the textarea.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected sendOnEnter: boolean;
 | 
					    protected sendOnEnter: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, configProvider: CoreConfigProvider,
 | 
					    constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, configProvider: CoreConfigProvider,
 | 
				
			||||||
            eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider) {
 | 
					            eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider,
 | 
				
			||||||
 | 
					            private domUtils: CoreDomUtilsProvider) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.onSubmit = new EventEmitter();
 | 
					        this.onSubmit = new EventEmitter();
 | 
				
			||||||
        this.onResize = new EventEmitter();
 | 
					        this.onResize = new EventEmitter();
 | 
				
			||||||
@ -99,6 +102,10 @@ export class CoreSendMessageFormComponent implements OnInit {
 | 
				
			|||||||
     * @param other The name of the other key that was clicked, undefined if no other key.
 | 
					     * @param other The name of the other key that was clicked, undefined if no other key.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    enterClicked(e: Event, other: string): void {
 | 
					    enterClicked(e: Event, other: string): void {
 | 
				
			||||||
 | 
					        if (this.sendDisabled) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.sendOnEnter && !other) {
 | 
					        if (this.sendOnEnter && !other) {
 | 
				
			||||||
            // Enter clicked, send the message.
 | 
					            // Enter clicked, send the message.
 | 
				
			||||||
            this.submitForm(e);
 | 
					            this.submitForm(e);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user