From efcb7af1a92fd398b5d1cef5e2cb698c4d87af4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 10 Sep 2019 09:09:23 +0200 Subject: [PATCH 1/6] MOBILE-3142 chat: Show user list on a lateral modal --- src/addon/mod/chat/pages/chat/chat.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/addon/mod/chat/pages/chat/chat.ts b/src/addon/mod/chat/pages/chat/chat.ts index 47be73f24..0123de12d 100644 --- a/src/addon/mod/chat/pages/chat/chat.ts +++ b/src/addon/mod/chat/pages/chat/chat.ts @@ -116,7 +116,15 @@ export class AddonModChatChatPage { * Display the chat users modal. */ showChatUsers(): void { - const modal = this.modalCtrl.create('AddonModChatUsersPage', {sessionId: this.sessionId}); + // Create the toc modal. + const modal = this.modalCtrl.create('AddonModChatUsersPage', { + sessionId: this.sessionId + }, { cssClass: 'core-modal-lateral', + showBackdrop: true, + enableBackdropDismiss: true, + enterAnimation: 'core-modal-lateral-transition', + leaveAnimation: 'core-modal-lateral-transition' }); + modal.onDidDismiss((data) => { if (data && data.talkTo) { this.newMessage = `To ${data.talkTo}: `; @@ -125,7 +133,10 @@ export class AddonModChatChatPage { this.sendMessage('', data.beepTo); } }); - modal.present(); + + modal.present({ + ev: event + }); } /** From 4c151051eb6e60ffaa1f4914e9e1ceeb7ca790bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 10 Sep 2019 13:57:06 +0200 Subject: [PATCH 2/6] MOBILE-3142 chat: Change chat look and feel --- .../messages/pages/discussion/discussion.scss | 11 +- src/addon/mod/chat/lang/en.json | 2 + src/addon/mod/chat/pages/chat/chat.html | 82 ++++++++------ src/addon/mod/chat/pages/chat/chat.scss | 5 +- src/addon/mod/chat/pages/chat/chat.ts | 106 ++++++++++++++++-- src/addon/mod/chat/pages/users/users.ts | 8 +- src/assets/lang/en.json | 2 + src/components/ion-tabs/ion-tabs.scss | 3 +- .../core-send-message-form.html | 2 +- .../send-message-form/send-message-form.ts | 9 +- 10 files changed, 173 insertions(+), 57 deletions(-) diff --git a/src/addon/messages/pages/discussion/discussion.scss b/src/addon/messages/pages/discussion/discussion.scss index 5b8ee2a35..4591793e5 100644 --- a/src/addon/messages/pages/discussion/discussion.scss +++ b/src/addon/messages/pages/discussion/discussion.scss @@ -4,8 +4,7 @@ $item-message-note-text: $gray-dark !default; $item-message-note-font-size: 75% !default; $item-message-mine-bg: $gray-light !default; -ion-app.app-root page-addon-messages-discussion.ion-page { - +@mixin message-page { ion-content { background-color: $gray-lighter !important; @include darkmode() { @@ -194,6 +193,12 @@ ion-app.app-root page-addon-messages-discussion.ion-page { .addon-message-not-mine.activated .tail { border-bottom-color: darken($item-message-bg, 10%); } +} + + +ion-app.app-root page-addon-messages-discussion.ion-page { + + @include message-page(); .toolbar-title { padding: 0; @@ -224,4 +229,4 @@ ion-app.app-root page-addon-messages-discussion.ion-page { ion-app.app-root.ios page-addon-messages-discussion ion-footer .toolbar:last-child { padding-bottom: 4px; min-height: 0; -} \ No newline at end of file +} diff --git a/src/addon/mod/chat/lang/en.json b/src/addon/mod/chat/lang/en.json index 4348b5d63..04c334410 100644 --- a/src/addon/mod/chat/lang/en.json +++ b/src/addon/mod/chat/lang/en.json @@ -9,10 +9,12 @@ "errorwhilegettingchatusers": "Error while getting chat users.", "errorwhileretrievingmessages": "Error while retrieving messages from the server.", "errorwhilesendingmessage": "Error while sending the message.", + "messagebeepseveryone": "{{$a}} beeps everyone!", "messagebeepsyou": "{{$a}} has just beeped you!", "messageenter": "{{$a}} has just entered this chat", "messageexit": "{{$a}} has left this chat", "messages": "Messages", + "messageyoubeep": "You beeped {{$a}}", "modulenameplural": "Chats", "mustbeonlinetosendmessages": "You must be online to send messages.", "nomessages": "No messages yet", diff --git a/src/addon/mod/chat/pages/chat/chat.html b/src/addon/mod/chat/pages/chat/chat.html index 47f744618..4141ba329 100644 --- a/src/addon/mod/chat/pages/chat/chat.html +++ b/src/addon/mod/chat/pages/chat/chat.html @@ -8,55 +8,63 @@ - + -
-
+ + -
- - {{ message.timestamp * 1000 | coreFormatDate:"strftimedayshort" }} +
+ {{ message.timestamp * 1000 | coreFormatDate:"strftimedayshort" }} +
+ +
+ + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ 'addon.mod_chat.messagebeepseveryone' | translate:{$a: message.userfullname} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepwho} }}
-
- - {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }} - -
- -
- - {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }} - -
- -
- - {{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }} - -
- - - -

-

{{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}

- + + +

+ +
{{ message.userfullname }}
+ {{ message.timestamp * 1000 | coreFormatDate: "strftimetime" }}

- -
-

-
-

{{ 'addon.mod_chat.nomessages' | translate}}

-
-
+

+ +

+
+ + + + +

{{ 'addon.mod_chat.mustbeonlinetosendmessages' | translate }}

- +
diff --git a/src/addon/mod/chat/pages/chat/chat.scss b/src/addon/mod/chat/pages/chat/chat.scss index fe62c5619..3e34e5324 100644 --- a/src/addon/mod/chat/pages/chat/chat.scss +++ b/src/addon/mod/chat/pages/chat/chat.scss @@ -1,9 +1,8 @@ ion-app.app-root page-addon-mod-chat-chat { + @include message-page(); + .addon-mod-chat-notice { margin-top: 10px; margin-bottom: 10px; } - .addon-mod-chat-message { - align-items: flex-start; - } } diff --git a/src/addon/mod/chat/pages/chat/chat.ts b/src/addon/mod/chat/pages/chat/chat.ts index 0123de12d..a8a0760cc 100644 --- a/src/addon/mod/chat/pages/chat/chat.ts +++ b/src/addon/mod/chat/pages/chat/chat.ts @@ -22,6 +22,8 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { AddonModChatProvider, AddonModChatMessageWithUserData } from '../../providers/chat'; 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'; /** @@ -31,9 +33,11 @@ import * as moment from 'moment'; @Component({ selector: 'page-addon-mod-chat-chat', templateUrl: 'chat.html', + animations: [coreSlideInOut] }) export class AddonModChatChatPage { @ViewChild(Content) content: Content; + @ViewChild(CoreSendMessageFormComponent) sendMessageForm: CoreSendMessageFormComponent; loaded = false; title: string; @@ -41,7 +45,8 @@ export class AddonModChatChatPage { newMessage: string; polling: any; isOnline: boolean; - currentUserBeep: string; + currentUserId: number; + sending: boolean; protected logger; protected courseId: number; @@ -53,6 +58,7 @@ export class AddonModChatChatPage { protected keyboardObserver: any; protected viewDestroyed = false; protected pollingRunning = false; + protected users = []; constructor(navParams: NavParams, logger: CoreLoggerProvider, network: Network, zone: NgZone, private navCtrl: NavController, private chatProvider: AddonModChatProvider, private appProvider: CoreAppProvider, sitesProvider: CoreSitesProvider, @@ -63,7 +69,7 @@ export class AddonModChatChatPage { this.courseId = navParams.get('courseId'); this.title = navParams.get('title'); this.logger = logger.getInstance('AddonModChoiceChoicePage'); - this.currentUserBeep = 'beep ' + sitesProvider.getCurrentSiteUserId(); + this.currentUserId = sitesProvider.getCurrentSiteUserId(); this.isOnline = this.appProvider.isOnline(); this.onlineObserver = network.onchange().subscribe(() => { // Execute the callback in the Angular zone, so change detection doesn't stop working. @@ -127,11 +133,14 @@ export class AddonModChatChatPage { modal.onDidDismiss((data) => { if (data && data.talkTo) { - this.newMessage = `To ${data.talkTo}: `; + this.newMessage = `To ${data.talkTo}: ` + this.sendMessageForm.message; } if (data && data.beepTo) { this.sendMessage('', data.beepTo); } + if (data && data.users) { + this.users = data.users; + } }); 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 { + 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. * @@ -160,8 +201,33 @@ export class AddonModChatChatPage { this.lastTime = messagesInfo.chatnewlasttime || 0; return this.chatProvider.getMessagesUserData(messagesInfo.messages, this.courseId).then((messages) => { - this.messages = this.messages.concat( messages); if (messages.length) { + const previousLength = this.messages.length; + this.messages = this.messages.concat( 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. 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. * @@ -259,9 +349,8 @@ export class AddonModChatChatPage { // Silent error. return; } - text = this.textUtils.replaceNewLines(text, '
'); - const modal = this.domUtils.showModalLoading('core.sending', true); + this.sending = true; this.chatProvider.sendMessage(this.sessionId, text, beep).then(() => { // Update messages to show the sent message. this.fetchMessagesInterval().catch(() => { @@ -272,9 +361,12 @@ export class AddonModChatChatPage { messages without the keyboard being closed. */ this.appProvider.closeKeyboard(); + this.newMessage = text; + this.domUtils.showErrorModalDefault(error, 'addon.mod_chat.errorwhilesendingmessage', true); }).finally(() => { - modal.dismiss(); + this.sending = false; + this.sendMessageForm.focus(); }); } diff --git a/src/addon/mod/chat/pages/users/users.ts b/src/addon/mod/chat/pages/users/users.ts index f54560ba3..3ec2b36e4 100644 --- a/src/addon/mod/chat/pages/users/users.ts +++ b/src/addon/mod/chat/pages/users/users.ts @@ -69,7 +69,7 @@ export class AddonModChatUsersPage { * Close the chat users modal. */ closeModal(): void { - this.viewCtrl.dismiss(); + this.viewCtrl.dismiss({users: this.users}); } /** @@ -77,8 +77,8 @@ export class AddonModChatUsersPage { * * @param user User object. */ - talkTo(user: AddonModChatUser): void { - this.viewCtrl.dismiss({talkTo: user.fullname}); + talkTo(user: AddonModChatUser): void { + this.viewCtrl.dismiss({talkTo: user.fullname, users: this.users}); } /** @@ -87,7 +87,7 @@ export class AddonModChatUsersPage { * @param user User object. */ beepTo(user: AddonModChatUser): void { - this.viewCtrl.dismiss({beepTo: user.id}); + this.viewCtrl.dismiss({beepTo: user.id, users: this.users}); } /** diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index d4514cc94..2d744257b 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -432,10 +432,12 @@ "addon.mod_chat.errorwhilegettingchatusers": "Error while getting chat users.", "addon.mod_chat.errorwhileretrievingmessages": "Error while retrieving messages from the server.", "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.messageenter": "{{$a}} has just entered this chat", "addon.mod_chat.messageexit": "{{$a}} has left this chat", "addon.mod_chat.messages": "Messages", + "addon.mod_chat.messageyoubeep": "You beeped {{$a}}", "addon.mod_chat.modulenameplural": "Chats", "addon.mod_chat.mustbeonlinetosendmessages": "You must be online to send messages.", "addon.mod_chat.nomessages": "No messages yet", diff --git a/src/components/ion-tabs/ion-tabs.scss b/src/components/ion-tabs/ion-tabs.scss index 31f667650..ec2e85b66 100644 --- a/src/components/ion-tabs/ion-tabs.scss +++ b/src/components/ion-tabs/ion-tabs.scss @@ -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; } } diff --git a/src/components/send-message-form/core-send-message-form.html b/src/components/send-message-form/core-send-message-form.html index b1829854a..8caa886c3 100644 --- a/src/components/send-message-form/core-send-message-form.html +++ b/src/components/send-message-form/core-send-message-form.html @@ -1,7 +1,7 @@
- diff --git a/src/components/send-message-form/send-message-form.ts b/src/components/send-message-form/send-message-form.ts index 48a7a87c6..ac7f82578 100644 --- a/src/components/send-message-form/send-message-form.ts +++ b/src/components/send-message-form/send-message-form.ts @@ -19,6 +19,7 @@ import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreTextUtilsProvider } from '@providers/utils/text'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreConstants } from '@core/constants'; /** @@ -39,13 +40,15 @@ export class CoreSendMessageFormComponent implements OnInit { @Input() message: string; // Input text. @Input() placeholder = ''; // Placeholder for the input area. @Input() showKeyboard = false; // If keyboard is shown or not. + @Input() sendDisabled = false; // If send is disabled. @Output() onSubmit: EventEmitter; // Send data when submitting the message form. @Output() onResize: EventEmitter; // Emit when resizing the textarea. protected sendOnEnter: boolean; 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.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. */ enterClicked(e: Event, other: string): void { + if (this.sendDisabled) { + return; + } + if (this.sendOnEnter && !other) { // Enter clicked, send the message. this.submitForm(e); From e01cce68dcea0cb4dc91af4826dd829439f4a4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 10 Sep 2019 14:28:24 +0200 Subject: [PATCH 3/6] MOBILE-3142 chat: Implement me command --- src/addon/mod/chat/pages/chat/chat.html | 5 +++++ src/addon/mod/chat/pages/chat/chat.ts | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/addon/mod/chat/pages/chat/chat.html b/src/addon/mod/chat/pages/chat/chat.html index 4141ba329..2e08fe598 100644 --- a/src/addon/mod/chat/pages/chat/chat.html +++ b/src/addon/mod/chat/pages/chat/chat.html @@ -40,6 +40,11 @@ {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepwho} }} + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ message.userfullname }} +
diff --git a/src/addon/mod/chat/pages/chat/chat.ts b/src/addon/mod/chat/pages/chat/chat.ts index a8a0760cc..feba43697 100644 --- a/src/addon/mod/chat/pages/chat/chat.ts +++ b/src/addon/mod/chat/pages/chat/chat.ts @@ -221,6 +221,11 @@ export class AddonModChatChatPage { message.special = message.system || !!message.beep; + if (message.message.substr(0, 4) == '/me ') { + message.special = true; + message.message = message.message.substr(4).trim(); + } + message.showUserData = this.showUserData(message, prevMessage); prevMessage ? prevMessage.showTail = this.showTail(prevMessage, message) : null; From 0dd869d59e4430c125c2c0a80acaedfe4b27c4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 10 Sep 2019 14:59:08 +0200 Subject: [PATCH 4/6] MOBILE-3142 chat: Past sessions look and feel --- src/addon/mod/chat/chat.module.ts | 2 + src/addon/mod/chat/pages/chat/chat.ts | 63 ++----------- .../session-messages/session-messages.html | 73 +++++++++------ .../session-messages/session-messages.scss | 5 +- .../session-messages/session-messages.ts | 46 ++++++---- src/addon/mod/chat/providers/helper.ts | 88 +++++++++++++++++++ 6 files changed, 173 insertions(+), 104 deletions(-) create mode 100644 src/addon/mod/chat/providers/helper.ts diff --git a/src/addon/mod/chat/chat.module.ts b/src/addon/mod/chat/chat.module.ts index 7d90566e0..de0349837 100644 --- a/src/addon/mod/chat/chat.module.ts +++ b/src/addon/mod/chat/chat.module.ts @@ -18,6 +18,7 @@ import { CoreCourseModuleDelegate } from '@core/course/providers/module-delegate import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate'; import { AddonModChatComponentsModule } from './components/components.module'; import { AddonModChatProvider } from './providers/chat'; +import { AddonModChatHelperProvider } from './providers/helper'; import { AddonModChatLinkHandler } from './providers/link-handler'; import { AddonModChatListLinkHandler } from './providers/list-link-handler'; import { AddonModChatModuleHandler } from './providers/module-handler'; @@ -36,6 +37,7 @@ export const ADDON_MOD_CHAT_PROVIDERS: any[] = [ ], providers: [ AddonModChatProvider, + AddonModChatHelperProvider, AddonModChatLinkHandler, AddonModChatListLinkHandler, AddonModChatModuleHandler, diff --git a/src/addon/mod/chat/pages/chat/chat.ts b/src/addon/mod/chat/pages/chat/chat.ts index feba43697..880d2cd2a 100644 --- a/src/addon/mod/chat/pages/chat/chat.ts +++ b/src/addon/mod/chat/pages/chat/chat.ts @@ -21,10 +21,10 @@ import { CoreSitesProvider } from '@providers/sites'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { AddonModChatProvider, AddonModChatMessageWithUserData } from '../../providers/chat'; +import { AddonModChatHelperProvider } from '../../providers/helper'; 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'; /** * Page that displays a chat session. @@ -62,8 +62,8 @@ export class AddonModChatChatPage { constructor(navParams: NavParams, logger: CoreLoggerProvider, network: Network, zone: NgZone, private navCtrl: NavController, private chatProvider: AddonModChatProvider, private appProvider: CoreAppProvider, sitesProvider: CoreSitesProvider, - private modalCtrl: ModalController, private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, - private eventsProvider: CoreEventsProvider) { + private modalCtrl: ModalController, private domUtils: CoreDomUtilsProvider, + private eventsProvider: CoreEventsProvider, private chatHelper: AddonModChatHelperProvider) { this.chatId = navParams.get('chatId'); this.courseId = navParams.get('courseId'); @@ -210,25 +210,13 @@ export class AddonModChatChatPage { 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(); + this.chatHelper.formatMessage(this.currentUserId, message, prevMessage); if (message.beep && message.beep != this.currentUserId) { this.getUserFullname(message.beep).then((fullname) => { message.beepwho = fullname; }); } - - message.special = message.system || !!message.beep; - - if (message.message.substr(0, 4) == '/me ') { - message.special = true; - message.message = message.message.substr(4).trim(); - } - - message.showUserData = this.showUserData(message, prevMessage); - prevMessage ? - prevMessage.showTail = this.showTail(prevMessage, message) : null; } this.messages[this.messages.length - 1].showTail = true; @@ -267,34 +255,10 @@ 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. * - * @return Promised resolved when done. + * @return Promise resolved when done. */ protected fetchMessagesInterval(): Promise { this.logger.debug('Polling for messages'); @@ -324,22 +288,6 @@ export class AddonModChatChatPage { }); } - /** - * Check if the date should be displayed between messages (when the day changes at midnight for example). - * - * @param message New message object. - * @param prevMessage Previous message object. - * @return True if messages are from diferent days, false othetwise. - */ - showDate(message: AddonModChatMessageWithUserData, prevMessage: AddonModChatMessageWithUserData): boolean { - if (!prevMessage) { - return true; - } - - // Check if day has changed. - return !moment(message.timestamp * 1000).isSame(prevMessage.timestamp * 1000, 'day'); - } - /** * Send a message to the chat. * @@ -371,7 +319,6 @@ export class AddonModChatChatPage { this.domUtils.showErrorModalDefault(error, 'addon.mod_chat.errorwhilesendingmessage', true); }).finally(() => { this.sending = false; - this.sendMessageForm.focus(); }); } diff --git a/src/addon/mod/chat/pages/session-messages/session-messages.html b/src/addon/mod/chat/pages/session-messages/session-messages.html index a315ebecf..1383e37e0 100644 --- a/src/addon/mod/chat/pages/session-messages/session-messages.html +++ b/src/addon/mod/chat/pages/session-messages/session-messages.html @@ -8,33 +8,56 @@ -
-
- - {{ message.timestamp * 1000 | coreFormatDate:"strftimedayshort" }} - -
+ + +
+ {{ message.timestamp * 1000 | coreFormatDate:"strftimedayshort" }} +
-
- - {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }} - -
+
+ + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }} + -
- - {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }} - -
+ + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }} + - - -

-

{{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}

- -

- -
-
+ + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ 'addon.mod_chat.messagebeepseveryone' | translate:{$a: message.userfullname} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepwho} }} + + + + {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} + {{ message.userfullname }} + +
+ + + +

+ +
{{ message.userfullname }}
+ {{ message.timestamp * 1000 | coreFormatDate: "strftimetime" }} +

+ +

+ +

+
+
+ +
diff --git a/src/addon/mod/chat/pages/session-messages/session-messages.scss b/src/addon/mod/chat/pages/session-messages/session-messages.scss index a8d1e96e8..ec4792983 100644 --- a/src/addon/mod/chat/pages/session-messages/session-messages.scss +++ b/src/addon/mod/chat/pages/session-messages/session-messages.scss @@ -1,9 +1,8 @@ ion-app.app-root page-addon-mod-chat-session-messages { + @include message-page(); + .addon-mod-chat-notice { margin-top: 10px; margin-bottom: 10px; } - .addon-mod-chat-message { - align-items: flex-start; - } } diff --git a/src/addon/mod/chat/pages/session-messages/session-messages.ts b/src/addon/mod/chat/pages/session-messages/session-messages.ts index 1a29a8365..3696a65c9 100644 --- a/src/addon/mod/chat/pages/session-messages/session-messages.ts +++ b/src/addon/mod/chat/pages/session-messages/session-messages.ts @@ -15,8 +15,10 @@ import { Component } from '@angular/core'; import { IonicPage, NavParams } from 'ionic-angular'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreUserProvider } from '@core/user/providers/user'; import { AddonModChatProvider, AddonModChatSessionMessageWithUserData } from '../../providers/chat'; -import * as moment from 'moment'; +import { AddonModChatHelperProvider } from '../../providers/helper'; /** * Page that displays list of chat session messages. @@ -28,6 +30,8 @@ import * as moment from 'moment'; }) export class AddonModChatSessionMessagesPage { + currentUserId: number; + protected courseId: number; protected chatId: number; protected sessionStart: number; @@ -36,12 +40,14 @@ export class AddonModChatSessionMessagesPage { protected loaded = false; protected messages: AddonModChatSessionMessageWithUserData[] = []; - constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private chatProvider: AddonModChatProvider) { + constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private chatProvider: AddonModChatProvider, + sitesProvider: CoreSitesProvider, private chatHelper: AddonModChatHelperProvider, private userProvider: CoreUserProvider) { this.courseId = navParams.get('courseId'); this.chatId = navParams.get('chatId'); this.groupId = navParams.get('groupId'); this.sessionStart = navParams.get('sessionStart'); this.sessionEnd = navParams.get('sessionEnd'); + this.currentUserId = sitesProvider.getCurrentSiteUserId(); this.fetchMessages(); } @@ -55,7 +61,7 @@ export class AddonModChatSessionMessagesPage { return this.chatProvider.getSessionMessages(this.chatId, this.sessionStart, this.sessionEnd, this.groupId) .then((messages) => { return this.chatProvider.getMessagesUserData(messages, this.courseId).then((messages) => { - this.messages = messages; + }); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'core.errorloadingcontent', true); @@ -64,6 +70,25 @@ export class AddonModChatSessionMessagesPage { }); } + /** + * Get the user fullname for a beep. + * + * @param id User Id before parsing. + * @return User fullname. + */ + protected getUserFullname(id: string): Promise { + if (isNaN(parseInt(id, 10))) { + return Promise.resolve(id); + } + + return this.userProvider.getProfile(parseInt(id, 10), this.courseId, true).then((user) => { + return user.fullname; + }).catch(() => { + // Error getting profile. + return id; + }); + } + /** * Refresh session messages. * @@ -77,19 +102,4 @@ export class AddonModChatSessionMessagesPage { }); } - /** - * Check if the date should be displayed between messages (when the day changes at midnight for example). - * - * @param message New message object. - * @param prevMessage Previous message object. - * @return True if messages are from diferent days, false othetwise. - */ - showDate(message: AddonModChatSessionMessageWithUserData, prevMessage: AddonModChatSessionMessageWithUserData): boolean { - if (!prevMessage) { - return true; - } - - // Check if day has changed. - return !moment(message.timestamp * 1000).isSame(prevMessage.timestamp * 1000, 'day'); - } } diff --git a/src/addon/mod/chat/providers/helper.ts b/src/addon/mod/chat/providers/helper.ts new file mode 100644 index 000000000..6e7b7fedf --- /dev/null +++ b/src/addon/mod/chat/providers/helper.ts @@ -0,0 +1,88 @@ +// (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 { Injectable } from '@angular/core'; +import * as moment from 'moment'; +import AddonModChatMessageWithUserData from './chat'; + +/** + * Helper service that provides some features for quiz. + */ +@Injectable() +export class AddonModChatHelperProvider { + + /** + * Give some format info about messages. + * + * @param currentUserId User Id. + * @param message Message in a discussion. + * @param prevMessage Previous Message in a discussion (if any). + * @return Message with additional info. + */ + formatMessage(currentUserId: number, message: AddonModChatMessageWithUserData, prevMessage?: any): any { + message.showDate = this.showDate(message, prevMessage); + message.beep = message.message.substr(0, 5) == 'beep ' && message.message.substr(5).trim(); + + message.special = message.issystem || message.system || !!message.beep; + + if (message.message.substr(0, 4) == '/me ') { + message.special = true; + message.message = message.message.substr(4).trim(); + } + + message.showUserData = this.showUserData(currentUserId, message, prevMessage); + prevMessage ? + prevMessage.showTail = this.showTail(prevMessage, message) : null; + } + + /** + * 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. + */ + protected showUserData(currentUserId: number, message: any, prevMessage?: any): boolean { + return message.userid != 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. + */ + protected showTail(message: AddonModChatMessageWithUserData, nextMessage?: AddonModChatMessageWithUserData): boolean { + return !nextMessage || nextMessage.userid != message.userid || nextMessage.showDate || nextMessage.special; + } + + /** + * Check if the date should be displayed between messages (when the day changes at midnight for example). + * + * @param message New message object. + * @param prevMessage Previous message object. + * @return True if messages are from diferent days, false othetwise. + */ + protected showDate(message: AddonModChatMessageWithUserData, prevMessage: AddonModChatMessageWithUserData): boolean { + if (!prevMessage) { + return true; + } + + // Check if day has changed. + return !moment(message.timestamp * 1000).isSame(prevMessage.timestamp * 1000, 'day'); + } +} From 273d88262c368869be0c44d8242fa7ba238d40a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 10 Sep 2019 16:40:53 +0200 Subject: [PATCH 5/6] MOBILE-3142 chat: Translate said to string --- scripts/langindex.json | 3 +++ src/addon/mod/chat/lang/en.json | 1 + src/addon/mod/chat/pages/chat/chat.html | 2 +- src/addon/mod/chat/pages/chat/chat.ts | 2 +- src/addon/mod/chat/providers/helper.ts | 20 +++++++++++++++++++- src/assets/lang/en.json | 1 + 6 files changed, 26 insertions(+), 3 deletions(-) diff --git a/scripts/langindex.json b/scripts/langindex.json index e8a555bb2..0ed0824bc 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -433,14 +433,17 @@ "addon.mod_chat.errorwhilegettingchatusers": "local_moodlemobileapp", "addon.mod_chat.errorwhileretrievingmessages": "local_moodlemobileapp", "addon.mod_chat.errorwhilesendingmessage": "local_moodlemobileapp", + "addon.mod_chat.messagebeepseveryone": "chat", "addon.mod_chat.messagebeepsyou": "chat", "addon.mod_chat.messageenter": "chat", "addon.mod_chat.messageexit": "chat", "addon.mod_chat.messages": "chat", + "addon.mod_chat.messageyoubeep": "chat", "addon.mod_chat.modulenameplural": "chat", "addon.mod_chat.mustbeonlinetosendmessages": "local_moodlemobileapp", "addon.mod_chat.nomessages": "chat", "addon.mod_chat.nosessionsfound": "local_moodlemobileapp", + "addon.mod_chat.saidto": "chat", "addon.mod_chat.send": "chat", "addon.mod_chat.sessionstart": "chat", "addon.mod_chat.showincompletesessions": "local_moodlemobileapp", diff --git a/src/addon/mod/chat/lang/en.json b/src/addon/mod/chat/lang/en.json index 04c334410..ad8f86ce8 100644 --- a/src/addon/mod/chat/lang/en.json +++ b/src/addon/mod/chat/lang/en.json @@ -19,6 +19,7 @@ "mustbeonlinetosendmessages": "You must be online to send messages.", "nomessages": "No messages yet", "nosessionsfound": "No sessions found", + "saidto": "said to", "send": "Send", "sessionstart": "The next chat session will start on {{$a.date}}, ({{$a.fromnow}} from now)", "showincompletesessions": "Show incomplete sessions", diff --git a/src/addon/mod/chat/pages/chat/chat.html b/src/addon/mod/chat/pages/chat/chat.html index 2e08fe598..7e3de79b3 100644 --- a/src/addon/mod/chat/pages/chat/chat.html +++ b/src/addon/mod/chat/pages/chat/chat.html @@ -69,7 +69,7 @@

{{ 'addon.mod_chat.mustbeonlinetosendmessages' | translate }}

- +
diff --git a/src/addon/mod/chat/pages/chat/chat.ts b/src/addon/mod/chat/pages/chat/chat.ts index 880d2cd2a..de3640946 100644 --- a/src/addon/mod/chat/pages/chat/chat.ts +++ b/src/addon/mod/chat/pages/chat/chat.ts @@ -133,7 +133,7 @@ export class AddonModChatChatPage { modal.onDidDismiss((data) => { if (data && data.talkTo) { - this.newMessage = `To ${data.talkTo}: ` + this.sendMessageForm.message; + this.newMessage = `To ${data.talkTo}: ` + (this.sendMessageForm.message || ''); } if (data && data.beepTo) { this.sendMessage('', data.beepTo); diff --git a/src/addon/mod/chat/providers/helper.ts b/src/addon/mod/chat/providers/helper.ts index 6e7b7fedf..9c88bed68 100644 --- a/src/addon/mod/chat/providers/helper.ts +++ b/src/addon/mod/chat/providers/helper.ts @@ -13,6 +13,8 @@ // limitations under the License. import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreTextUtilsProvider } from '@providers/utils/text'; import * as moment from 'moment'; import AddonModChatMessageWithUserData from './chat'; @@ -22,6 +24,13 @@ import AddonModChatMessageWithUserData from './chat'; @Injectable() export class AddonModChatHelperProvider { + static patternto = new RegExp(/^To\s([^:]+):(.*)/); + + constructor(protected translate: TranslateService, + protected textUtils: CoreTextUtilsProvider) { + + } + /** * Give some format info about messages. * @@ -30,7 +39,10 @@ export class AddonModChatHelperProvider { * @param prevMessage Previous Message in a discussion (if any). * @return Message with additional info. */ - formatMessage(currentUserId: number, message: AddonModChatMessageWithUserData, prevMessage?: any): any { + formatMessage(currentUserId: number, message: AddonModChatMessageWithUserData, + prevMessage?: AddonModChatMessageWithUserData): any { + message.message = message.message.trim(); + message.showDate = this.showDate(message, prevMessage); message.beep = message.message.substr(0, 5) == 'beep ' && message.message.substr(5).trim(); @@ -41,6 +53,12 @@ export class AddonModChatHelperProvider { message.message = message.message.substr(4).trim(); } + if (!message.special && message.message.match(AddonModChatHelperProvider.patternto)) { + const matches = message.message.match(AddonModChatHelperProvider.patternto); + message.message = '' + this.translate.instant('addon.mod_chat.saidto') + + ' ' + matches[1] + ': ' + matches[2]; + } + message.showUserData = this.showUserData(currentUserId, message, prevMessage); prevMessage ? prevMessage.showTail = this.showTail(prevMessage, message) : null; diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index 2d744257b..58ceb5175 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -442,6 +442,7 @@ "addon.mod_chat.mustbeonlinetosendmessages": "You must be online to send messages.", "addon.mod_chat.nomessages": "No messages yet", "addon.mod_chat.nosessionsfound": "No sessions found", + "addon.mod_chat.saidto": "said to", "addon.mod_chat.send": "Send", "addon.mod_chat.sessionstart": "The next chat session will start on {{$a.date}}, ({{$a.fromnow}} from now)", "addon.mod_chat.showincompletesessions": "Show incomplete sessions", From 81b03dedc9be64ef83c8d16a99b968455f736a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 26 Sep 2019 09:22:05 +0200 Subject: [PATCH 6/6] MOBILE-3142 chat: Adapt return types on chat --- .../messages/pages/discussion/discussion.scss | 91 ++++++++++--------- src/addon/mod/chat/pages/chat/chat.html | 2 +- src/addon/mod/chat/pages/chat/chat.scss | 2 +- src/addon/mod/chat/pages/chat/chat.ts | 13 ++- .../session-messages/session-messages.html | 2 +- .../session-messages/session-messages.scss | 2 +- .../session-messages/session-messages.ts | 24 ++++- src/addon/mod/chat/providers/chat.ts | 9 +- src/addon/mod/chat/providers/helper.ts | 42 +++++++-- .../send-message-form/send-message-form.ts | 4 +- src/theme/dark.scss | 2 +- 11 files changed, 118 insertions(+), 75 deletions(-) diff --git a/src/addon/messages/pages/discussion/discussion.scss b/src/addon/messages/pages/discussion/discussion.scss index 4591793e5..0c2237fc2 100644 --- a/src/addon/messages/pages/discussion/discussion.scss +++ b/src/addon/messages/pages/discussion/discussion.scss @@ -34,7 +34,7 @@ $item-message-mine-bg: $gray-light !default; } // Message item. - .addon-message { + .item.item-block.addon-message { border: 0; border-radius: 4px; padding: 8px; @@ -59,7 +59,7 @@ $item-message-mine-bg: $gray-light !default; flex-direction: row; justify-content: space-between; align-items: center; - margin-bottom: .5rem!important; + margin-bottom: .5rem; margin-top: 0; color: $text-color; @@ -98,7 +98,7 @@ $item-message-mine-bg: $gray-light !default; background-color: darken($item-message-bg, 10%); } - &.item-block .item-inner { + .item-inner { border-bottom: 0; padding: 0; margin: 0; @@ -130,6 +130,7 @@ $item-message-mine-bg: $gray-light !default; .icon { font-size: 1.4em; line-height: initial; + color: $danger; } } @@ -141,10 +142,50 @@ $item-message-mine-bg: $gray-light !default; position: absolute; touch-action: none; } + + // Defines when an item-message is the user's. + &.addon-message-mine { + background-color: $item-message-mine-bg; + align-self: flex-end; + + &.activated { + background-color: darken($item-message-mine-bg, 10%); + } + + .spinner { + @include float(end); + @include margin(2px, -3px, -2px, 5px); + + svg { + width: 16px; + height: 16px; + } + } + + .tail { + @include position(null, 0, 0, null); + @include margin-horizontal(null, -0.5rem); + border-bottom-color: $item-message-mine-bg; + } + + &.activated .tail { + border-bottom-color: darken($item-message-mine-bg, 10%); + } + } + + &.addon-message-not-mine .tail { + @include position(null, null, 0, 0); + @include margin-horizontal(-0.5rem, null); + border-bottom-color: $item-message-bg; + } + + &.addon-message-not-mine.activated .tail { + border-bottom-color: darken($item-message-bg, 10%); + } } - .addon-message.addon-message-mine + .addon-message-no-user.addon-message-mine, - .addon-message.addon-message-not-mine + .addon-message-no-user.addon-message-not-mine { + .item.addon-message.addon-message-mine + .item.addon-message.addon-message-no-user.addon-message-mine, + .item.addon-message.addon-message-not-mine + .item.addon-message.addon-message-no-user.addon-message-not-mine { h2 { margin-bottom: 0; } @@ -153,46 +194,6 @@ $item-message-mine-bg: $gray-light !default; border-top-right-radius: 0; border-top-left-radius: 0; } - - // Defines when an item-message is the user's. - .addon-message-mine { - background-color: $item-message-mine-bg; - align-self: flex-end; - - &.activated { - background-color: darken($item-message-mine-bg, 10%); - } - - .spinner { - @include float(end); - @include margin(2px, -3px, -2px, 5px); - - svg { - width: 16px; - height: 16px; - } - } - - .tail { - @include position(null, 0, 0, null); - @include margin-horizontal(null, -0.5rem); - border-bottom-color: $item-message-mine-bg; - } - - &.activated .tail { - border-bottom-color: darken($item-message-mine-bg, 10%); - } - } - - .addon-message-not-mine .tail { - @include position(null, null, 0, 0); - @include margin-horizontal(-0.5rem, null); - border-bottom-color: $item-message-bg; - } - - .addon-message-not-mine.activated .tail { - border-bottom-color: darken($item-message-bg, 10%); - } } diff --git a/src/addon/mod/chat/pages/chat/chat.html b/src/addon/mod/chat/pages/chat/chat.html index 7e3de79b3..220b2bab0 100644 --- a/src/addon/mod/chat/pages/chat/chat.html +++ b/src/addon/mod/chat/pages/chat/chat.html @@ -38,7 +38,7 @@ {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} - {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepwho} }} + {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepWho} }} diff --git a/src/addon/mod/chat/pages/chat/chat.scss b/src/addon/mod/chat/pages/chat/chat.scss index 3e34e5324..e9eb2ef73 100644 --- a/src/addon/mod/chat/pages/chat/chat.scss +++ b/src/addon/mod/chat/pages/chat/chat.scss @@ -1,4 +1,4 @@ -ion-app.app-root page-addon-mod-chat-chat { +ion-app.app-root page-addon-mod-chat-chat.ion-page { @include message-page(); .addon-mod-chat-notice { diff --git a/src/addon/mod/chat/pages/chat/chat.ts b/src/addon/mod/chat/pages/chat/chat.ts index de3640946..18f5ce956 100644 --- a/src/addon/mod/chat/pages/chat/chat.ts +++ b/src/addon/mod/chat/pages/chat/chat.ts @@ -19,9 +19,8 @@ import { CoreEventsProvider } from '@providers/events'; import { CoreLoggerProvider } from '@providers/logger'; import { CoreSitesProvider } from '@providers/sites'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; -import { CoreTextUtilsProvider } from '@providers/utils/text'; -import { AddonModChatProvider, AddonModChatMessageWithUserData } from '../../providers/chat'; -import { AddonModChatHelperProvider } from '../../providers/helper'; +import { AddonModChatProvider } from '../../providers/chat'; +import { AddonModChatHelperProvider, AddonModChatMessageForView } from '../../providers/helper'; import { Network } from '@ionic-native/network'; import { coreSlideInOut } from '@classes/animations'; import { CoreSendMessageFormComponent } from '@components/send-message-form/send-message-form'; @@ -41,7 +40,7 @@ export class AddonModChatChatPage { loaded = false; title: string; - messages: AddonModChatMessageWithUserData[] = []; + messages: AddonModChatMessageForView[] = []; newMessage: string; polling: any; isOnline: boolean; @@ -203,7 +202,7 @@ export class AddonModChatChatPage { return this.chatProvider.getMessagesUserData(messagesInfo.messages, this.courseId).then((messages) => { if (messages.length) { const previousLength = this.messages.length; - this.messages = this.messages.concat( messages); + this.messages = this.messages.concat( messages); // Calculate which messages need to display the date or user data. for (let index = previousLength ; index < this.messages.length; index++) { @@ -212,9 +211,9 @@ export class AddonModChatChatPage { this.chatHelper.formatMessage(this.currentUserId, message, prevMessage); - if (message.beep && message.beep != this.currentUserId) { + if (message.beep && message.beep != this.currentUserId + '') { this.getUserFullname(message.beep).then((fullname) => { - message.beepwho = fullname; + message.beepWho = fullname; }); } } diff --git a/src/addon/mod/chat/pages/session-messages/session-messages.html b/src/addon/mod/chat/pages/session-messages/session-messages.html index 1383e37e0..1f2a2ce14 100644 --- a/src/addon/mod/chat/pages/session-messages/session-messages.html +++ b/src/addon/mod/chat/pages/session-messages/session-messages.html @@ -35,7 +35,7 @@ {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} - {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepwho} }} + {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepWho} }} diff --git a/src/addon/mod/chat/pages/session-messages/session-messages.scss b/src/addon/mod/chat/pages/session-messages/session-messages.scss index ec4792983..ef01df6e2 100644 --- a/src/addon/mod/chat/pages/session-messages/session-messages.scss +++ b/src/addon/mod/chat/pages/session-messages/session-messages.scss @@ -1,4 +1,4 @@ -ion-app.app-root page-addon-mod-chat-session-messages { +ion-app.app-root page-addon-mod-chat-session-messages.ion-page { @include message-page(); .addon-mod-chat-notice { diff --git a/src/addon/mod/chat/pages/session-messages/session-messages.ts b/src/addon/mod/chat/pages/session-messages/session-messages.ts index 3696a65c9..a70eda770 100644 --- a/src/addon/mod/chat/pages/session-messages/session-messages.ts +++ b/src/addon/mod/chat/pages/session-messages/session-messages.ts @@ -17,8 +17,8 @@ import { IonicPage, NavParams } from 'ionic-angular'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreSitesProvider } from '@providers/sites'; import { CoreUserProvider } from '@core/user/providers/user'; -import { AddonModChatProvider, AddonModChatSessionMessageWithUserData } from '../../providers/chat'; -import { AddonModChatHelperProvider } from '../../providers/helper'; +import { AddonModChatProvider } from '../../providers/chat'; +import { AddonModChatHelperProvider, AddonModChatSessionMessageForView } from '../../providers/helper'; /** * Page that displays list of chat session messages. @@ -38,7 +38,7 @@ export class AddonModChatSessionMessagesPage { protected sessionEnd: number; protected groupId: number; protected loaded = false; - protected messages: AddonModChatSessionMessageWithUserData[] = []; + protected messages: AddonModChatSessionMessageForView[] = []; constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private chatProvider: AddonModChatProvider, sitesProvider: CoreSitesProvider, private chatHelper: AddonModChatHelperProvider, private userProvider: CoreUserProvider) { @@ -61,7 +61,25 @@ export class AddonModChatSessionMessagesPage { return this.chatProvider.getSessionMessages(this.chatId, this.sessionStart, this.sessionEnd, this.groupId) .then((messages) => { return this.chatProvider.getMessagesUserData(messages, this.courseId).then((messages) => { + this.messages = messages; + if (messages.length) { + // Calculate which messages need to display the date or user data. + for (let index = 0 ; index < this.messages.length; index++) { + const message = this.messages[index]; + const prevMessage = index > 0 ? this.messages[index - 1] : null; + + this.chatHelper.formatMessage(this.currentUserId, message, prevMessage); + + if (message.beep && message.beep != this.currentUserId + '') { + this.getUserFullname(message.beep).then((fullname) => { + message.beepWho = fullname; + }); + } + } + + this.messages[this.messages.length - 1].showTail = true; + } }); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'core.errorloadingcontent', true); diff --git a/src/addon/mod/chat/providers/chat.ts b/src/addon/mod/chat/providers/chat.ts index f656375a7..45a102a06 100644 --- a/src/addon/mod/chat/providers/chat.ts +++ b/src/addon/mod/chat/providers/chat.ts @@ -20,6 +20,7 @@ import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; import { CoreWSExternalWarning, CoreWSExternalFile } from '@providers/ws'; +import { AddonModChatMessageForView, AddonModChatSessionMessageForView } from './helper'; /** * Service that provides some features for chats. @@ -157,9 +158,9 @@ export class AddonModChatProvider { * @return Promise always resolved with the formatted messages. */ getMessagesUserData(messages: (AddonModChatMessage | AddonModChatSessionMessage)[], courseId: number) - : Promise<(AddonModChatMessageWithUserData | AddonModChatSessionMessageWithUserData)[]> { + : Promise<(AddonModChatMessageForView | AddonModChatSessionMessageForView)[]> { - const promises = messages.map((message: AddonModChatMessageWithUserData | AddonModChatSessionMessageWithUserData) => { + const promises = messages.map((message: AddonModChatMessageForView | AddonModChatSessionMessageForView) => { return this.userProvider.getProfile(message.userid, courseId, true).then((user) => { message.userfullname = user.fullname; message.userprofileimageurl = user.profileimageurl; @@ -448,7 +449,7 @@ export type AddonModChatMessage = { }; /** - * Message with user data + * Message with user data. */ export type AddonModChatMessageWithUserData = AddonModChatMessage & AddonModChatMessageUserData; @@ -484,7 +485,7 @@ export type AddonModChatSessionMessage = { }; /** - * Message with user data + * Session message with user data. */ export type AddonModChatSessionMessageWithUserData = AddonModChatSessionMessage & AddonModChatMessageUserData; diff --git a/src/addon/mod/chat/providers/helper.ts b/src/addon/mod/chat/providers/helper.ts index 9c88bed68..c575b64a7 100644 --- a/src/addon/mod/chat/providers/helper.ts +++ b/src/addon/mod/chat/providers/helper.ts @@ -16,10 +16,10 @@ import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import * as moment from 'moment'; -import AddonModChatMessageWithUserData from './chat'; +import { AddonModChatMessageWithUserData, AddonModChatSessionMessageWithUserData } from './chat'; /** - * Helper service that provides some features for quiz. + * Helper service that provides some features for chat. */ @Injectable() export class AddonModChatHelperProvider { @@ -39,14 +39,15 @@ export class AddonModChatHelperProvider { * @param prevMessage Previous Message in a discussion (if any). * @return Message with additional info. */ - formatMessage(currentUserId: number, message: AddonModChatMessageWithUserData, - prevMessage?: AddonModChatMessageWithUserData): any { + formatMessage(currentUserId: number, message: AddonModChatMessageForView | AddonModChatSessionMessageForView, + prevMessage?: AddonModChatMessageForView | AddonModChatSessionMessageForView): any { message.message = message.message.trim(); message.showDate = this.showDate(message, prevMessage); message.beep = message.message.substr(0, 5) == 'beep ' && message.message.substr(5).trim(); - message.special = message.issystem || message.system || !!message.beep; + message.special = ( message).issystem || ( message).system || + !!message.beep; if (message.message.substr(0, 4) == '/me ') { message.special = true; @@ -72,7 +73,8 @@ export class AddonModChatHelperProvider { * @param prevMessage Previous message. * @return Whether user data should be shown. */ - protected showUserData(currentUserId: number, message: any, prevMessage?: any): boolean { + protected showUserData(currentUserId: number, message: AddonModChatMessageForView | AddonModChatSessionMessageForView, + prevMessage?: AddonModChatMessageForView | AddonModChatSessionMessageForView): boolean { return message.userid != currentUserId && (!prevMessage || prevMessage.userid != message.userid || message.showDate || prevMessage.special); } @@ -84,7 +86,8 @@ export class AddonModChatHelperProvider { * @param nextMessage Next message. * @return Whether user data should be shown. */ - protected showTail(message: AddonModChatMessageWithUserData, nextMessage?: AddonModChatMessageWithUserData): boolean { + protected showTail(message: AddonModChatMessageForView | AddonModChatSessionMessageForView, + nextMessage?: AddonModChatMessageForView | AddonModChatSessionMessageForView): boolean { return !nextMessage || nextMessage.userid != message.userid || nextMessage.showDate || nextMessage.special; } @@ -95,7 +98,8 @@ export class AddonModChatHelperProvider { * @param prevMessage Previous message object. * @return True if messages are from diferent days, false othetwise. */ - protected showDate(message: AddonModChatMessageWithUserData, prevMessage: AddonModChatMessageWithUserData): boolean { + protected showDate(message: AddonModChatMessageForView | AddonModChatSessionMessageForView, + prevMessage: AddonModChatMessageForView | AddonModChatSessionMessageForView): boolean { if (!prevMessage) { return true; } @@ -104,3 +108,25 @@ export class AddonModChatHelperProvider { return !moment(message.timestamp * 1000).isSame(prevMessage.timestamp * 1000, 'day'); } } + +/** + * Special info for view usage. + */ +type AddonModChatInfoForView = { + showDate?: boolean; // If date should be displayed before the message. + beep?: string; // User id of the beeped user or 'all'. + special?: boolean; // True if is an special message (system, beep or command). + showUserData?: boolean; // If user data should be displayed. + showTail?: boolean; // If tail should be displayed (decoration). + beepWho?: string; // Fullname of the beeped user. +}; + +/** + * Message with data for view usage. + */ +export type AddonModChatMessageForView = AddonModChatMessageWithUserData & AddonModChatInfoForView; + +/** + * Session message with data for view usage. + */ +export type AddonModChatSessionMessageForView = AddonModChatSessionMessageWithUserData & AddonModChatInfoForView; diff --git a/src/components/send-message-form/send-message-form.ts b/src/components/send-message-form/send-message-form.ts index ac7f82578..7076f0d4f 100644 --- a/src/components/send-message-form/send-message-form.ts +++ b/src/components/send-message-form/send-message-form.ts @@ -19,7 +19,6 @@ import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreTextUtilsProvider } from '@providers/utils/text'; -import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreConstants } from '@core/constants'; /** @@ -47,8 +46,7 @@ export class CoreSendMessageFormComponent implements OnInit { protected sendOnEnter: boolean; constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, configProvider: CoreConfigProvider, - eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, - private domUtils: CoreDomUtilsProvider) { + eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider) { this.onSubmit = new EventEmitter(); this.onResize = new EventEmitter(); diff --git a/src/theme/dark.scss b/src/theme/dark.scss index 27800e723..fe18c049a 100644 --- a/src/theme/dark.scss +++ b/src/theme/dark.scss @@ -21,7 +21,7 @@ ion-app.app-root .ion-page { color: $core-dark-text-color; background-color: $core-dark-item-bg-color; - a { + a:not(.button) { color: $core-dark-link-color; }