From e337bc64d5b3960ea373f3aabe26dbe383442468 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Thu, 9 Jun 2022 11:01:59 +0200
Subject: [PATCH] MOBILE-4061 core: Create a new message component to fix
animations
---
.../messages/pages/discussion/discussion.html | 43 +-----
.../pages/discussion/discussion.page.ts | 21 +--
.../messages/tests/behat/basic_usage.feature | 1 -
src/addons/mod/chat/pages/chat/chat.html | 25 +--
src/addons/mod/chat/pages/chat/chat.ts | 2 -
.../session-messages/session-messages.html | 23 +--
src/core/components/animations.ts | 8 +-
src/core/components/components.module.ts | 3 +
src/core/components/message/message.html | 45 ++++++
src/core/components/message/message.scss | 138 +++++++++++++++++
src/core/components/message/message.ts | 121 +++++++++++++++
.../components/user-avatar/user-avatar.ts | 2 +-
.../comments/pages/viewer/viewer.html | 75 ++-------
.../comments/pages/viewer/viewer.page.ts | 23 +--
.../comments/pages/viewer/viewer.scss | 4 +
src/theme/components/discussion.scss | 145 ------------------
src/theme/theme.dark.scss | 14 +-
src/theme/theme.light.scss | 18 +--
upgrade.txt | 3 +-
19 files changed, 378 insertions(+), 336 deletions(-)
create mode 100644 src/core/components/message/message.html
create mode 100644 src/core/components/message/message.scss
create mode 100644 src/core/components/message/message.ts
diff --git a/src/addons/messages/pages/discussion/discussion.html b/src/addons/messages/pages/discussion/discussion.html
index bb9cc05ff..f5c3e8dba 100644
--- a/src/addons/messages/pages/discussion/discussion.html
+++ b/src/addons/messages/pages/discussion/discussion.html
@@ -81,47 +81,16 @@
-
-
-
-
-
-
-
{{ members[message.useridfrom].fullname }}
-
-
- {{ message.useridfrom == currentUserId
- ? ('addon.messages.you' | translate)
- : members[message.useridfrom].fullname }}
-
-
-
-
-
-
-
- {{ message.timecreated | coreFormatDate: "strftimetime" }}
-
-
-
-
-
-
-
-
-
+
+
+ [message]="'addon.messages.nomessagesfound' | translate">
+
0">
diff --git a/src/addons/messages/pages/discussion/discussion.page.ts b/src/addons/messages/pages/discussion/discussion.page.ts
index 4f009de55..17cca33e9 100644
--- a/src/addons/messages/pages/discussion/discussion.page.ts
+++ b/src/addons/messages/pages/discussion/discussion.page.ts
@@ -37,7 +37,6 @@ import { CoreApp } from '@services/app';
import { CoreInfiniteLoadingComponent } from '@components/infinite-loading/infinite-loading';
import { Md5 } from 'ts-md5/dist/md5';
import moment from 'moment';
-import { CoreAnimations } from '@components/animations';
import { CoreError } from '@classes/errors/error';
import { Translate } from '@singletons';
import { CoreNavigator } from '@services/navigator';
@@ -53,7 +52,6 @@ import { CoreDom } from '@singletons/dom';
@Component({
selector: 'page-addon-messages-discussion',
templateUrl: 'discussion.html',
- animations: [CoreAnimations.SLIDE_IN_OUT],
styleUrls: ['discussion.scss'],
})
export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterViewInit {
@@ -305,7 +303,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
} else {
if (this.userId) {
// Fake the user member info.
- promises.push(CoreUser.getProfile(this.userId!).then(async (user) => {
+ promises.push(CoreUser.getProfile(this.userId).then(async (user) => {
this.otherMember = {
id: user.id,
fullname: user.fullname,
@@ -524,7 +522,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
return;
}
- const messages = Array.from(this.hostElement.querySelectorAll('.addon-message-not-mine'))
+ const messages = Array.from(this.hostElement.querySelectorAll('core-message:not(.is-mine)'))
.slice(-this.newMessages)
.reverse();
@@ -555,7 +553,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
// Try to get the conversationId if we don't have it.
if (!conversationId && userId) {
try {
- if (userId == this.currentUserId && AddonMessages.isSelfConversationEnabled()) {
+ if (userId === this.currentUserId && AddonMessages.isSelfConversationEnabled()) {
fallbackConversation = await AddonMessages.getSelfConversation();
} else {
fallbackConversation = await AddonMessages.getConversationBetweenUsers(userId, undefined, true);
@@ -563,7 +561,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
conversationId = fallbackConversation.id;
} catch (error) {
// Probably conversation does not exist or user is offline. Try to load offline messages.
- this.isSelf = userId == this.currentUserId;
+ this.isSelf = userId === this.currentUserId;
const messages = await AddonMessagesOffline.getMessages(userId);
@@ -584,11 +582,15 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
}
}
+ if (!conversationId) {
+ return false;
+ }
+
// Retrieve the conversation. Invalidate data first to get the right unreadcount.
- await AddonMessages.invalidateConversation(conversationId!);
+ await AddonMessages.invalidateConversation(conversationId);
try {
- this.conversation = await AddonMessages.getConversation(conversationId!, undefined, true);
+ this.conversation = await AddonMessages.getConversation(conversationId, undefined, true);
} catch (error) {
// Get conversation failed, use the fallback one if we have it.
if (fallbackConversation) {
@@ -947,7 +949,6 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
message: AddonMessagesConversationMessageFormatted,
index: number,
): Promise {
-
const canDeleteAll = this.conversation && this.conversation.candeletemessagesforallusers;
const langKey = message.pending || canDeleteAll || this.isSelf ? 'core.areyousure' :
'addon.messages.deletemessageconfirmation';
@@ -1099,7 +1100,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
*/
scrollToFirstUnreadMessage(): void {
if (this.newMessages > 0) {
- const messages = Array.from(this.hostElement.querySelectorAll('.addon-message-not-mine'));
+ const messages = Array.from(this.hostElement.querySelectorAll('core-message:not(.is-mine)'));
CoreDom.scrollToElement(messages[messages.length - this.newMessages]);
}
diff --git a/src/addons/messages/tests/behat/basic_usage.feature b/src/addons/messages/tests/behat/basic_usage.feature
index c84ed18fd..0fcc067db 100755
--- a/src/addons/messages/tests/behat/basic_usage.feature
+++ b/src/addons/messages/tests/behat/basic_usage.feature
@@ -106,7 +106,6 @@ Feature: Test basic usage of messages in app
And I should find "hi" in the app
And I should find "byee" in the app
- # TODO Fix this test in all Moodle versions
Scenario: User profile: send message, add/remove contact
Given I entered the app as "teacher1"
When I press "Messages" in the app
diff --git a/src/addons/mod/chat/pages/chat/chat.html b/src/addons/mod/chat/pages/chat/chat.html
index cc3112b5b..dafc0260e 100644
--- a/src/addons/mod/chat/pages/chat/chat.html
+++ b/src/addons/mod/chat/pages/chat/chat.html
@@ -81,27 +81,10 @@
-
-
-
-
-
-
-
{{ message.userfullname }}
-
-
-
-
-
-
-
- {{ message.timestamp * 1000 | coreFormatDate: "strftimetime" }}
-
-
+
+
diff --git a/src/addons/mod/chat/pages/chat/chat.ts b/src/addons/mod/chat/pages/chat/chat.ts
index 01cfcdb99..0fce55789 100644
--- a/src/addons/mod/chat/pages/chat/chat.ts
+++ b/src/addons/mod/chat/pages/chat/chat.ts
@@ -13,7 +13,6 @@
// limitations under the License.
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core';
-import { CoreAnimations } from '@components/animations';
import { CoreSendMessageFormComponent } from '@components/send-message-form/send-message-form';
import { CanLeave } from '@guards/can-leave';
import { IonContent } from '@ionic/angular';
@@ -36,7 +35,6 @@ import { AddonModChatFormattedMessage, AddonModChatHelper } from '../../services
@Component({
selector: 'page-addon-mod-chat-chat',
templateUrl: 'chat.html',
- animations: [CoreAnimations.SLIDE_IN_OUT],
styleUrls: ['chat.scss'],
})
export class AddonModChatChatPage implements OnInit, OnDestroy, CanLeave {
diff --git a/src/addons/mod/chat/pages/session-messages/session-messages.html b/src/addons/mod/chat/pages/session-messages/session-messages.html
index 9e18962a8..fd9f65e02 100644
--- a/src/addons/mod/chat/pages/session-messages/session-messages.html
+++ b/src/addons/mod/chat/pages/session-messages/session-messages.html
@@ -75,26 +75,9 @@
-
-
-
-
-
-
-
{{ message.userfullname }}
-
-
-
-
-
-
-
- {{ message.timestamp * 1000 | coreFormatDate: "strftimetime" }}
-
-
+
+
diff --git a/src/core/components/animations.ts b/src/core/components/animations.ts
index 0f5d36215..d149fe5e2 100644
--- a/src/core/components/animations.ts
+++ b/src/core/components/animations.ts
@@ -36,7 +36,7 @@ export class CoreAnimations {
animate(300, keyframes([
style({ opacity: 0, transform: 'translateX(-100%)', offset: 0 }),
style({ opacity: 1, transform: 'translateX(5%)', offset: 0.7 }),
- style({ opacity: 1, transform: 'translateX(0)', offset: 1.0 }),
+ style({ opacity: 1, transform: 'translateX(0)', offset: 1 }),
])),
]),
// Leave animation.
@@ -44,7 +44,7 @@ export class CoreAnimations {
animate(300, keyframes([
style({ opacity: 1, transform: 'translateX(0)', offset: 0 }),
style({ opacity: 1, transform: 'translateX(5%)', offset: 0.3 }),
- style({ opacity: 0, transform: 'translateX(-100%)', offset: 1.0 }),
+ style({ opacity: 0, transform: 'translateX(-100%)', offset: 1 }),
])),
]),
// Enter animation.
@@ -52,7 +52,7 @@ export class CoreAnimations {
animate(300, keyframes([
style({ opacity: 0, transform: 'translateX(100%)', offset: 0 }),
style({ opacity: 1, transform: 'translateX(-5%)', offset: 0.7 }),
- style({ opacity: 1, transform: 'translateX(0)', offset: 1.0 }),
+ style({ opacity: 1, transform: 'translateX(0)', offset: 1 }),
])),
]),
// Leave animation.
@@ -60,7 +60,7 @@ export class CoreAnimations {
animate(300, keyframes([
style({ opacity: 1, transform: 'translateX(0)', offset: 0 }),
style({ opacity: 1, transform: 'translateX(-5%)', offset: 0.3 }),
- style({ opacity: 0, transform: 'translateX(100%)', offset: 1.0 }),
+ style({ opacity: 0, transform: 'translateX(100%)', offset: 1 }),
])),
]),
]);
diff --git a/src/core/components/components.module.ts b/src/core/components/components.module.ts
index 2ab8a0a30..7ad2d0279 100644
--- a/src/core/components/components.module.ts
+++ b/src/core/components/components.module.ts
@@ -61,6 +61,7 @@ import { CoreHorizontalScrollControlsComponent } from './horizontal-scroll-contr
import { CoreButtonWithSpinnerComponent } from './button-with-spinner/button-with-spinner';
import { CoreSwipeSlidesComponent } from './swipe-slides/swipe-slides';
import { CoreSwipeNavigationTourComponent } from './swipe-navigation-tour/swipe-navigation-tour';
+import { CoreMessageComponent } from './message/message';
@NgModule({
declarations: [
@@ -84,6 +85,7 @@ import { CoreSwipeNavigationTourComponent } from './swipe-navigation-tour/swipe-
CoreLoadingComponent,
CoreLocalFileComponent,
CoreMarkRequiredComponent,
+ CoreMessageComponent,
CoreModIconComponent,
CoreNavBarButtonsComponent,
CoreNavigationBarComponent,
@@ -134,6 +136,7 @@ import { CoreSwipeNavigationTourComponent } from './swipe-navigation-tour/swipe-
CoreLoadingComponent,
CoreLocalFileComponent,
CoreMarkRequiredComponent,
+ CoreMessageComponent,
CoreModIconComponent,
CoreNavBarButtonsComponent,
CoreNavigationBarComponent,
diff --git a/src/core/components/message/message.html b/src/core/components/message/message.html
new file mode 100644
index 000000000..80ee993ad
--- /dev/null
+++ b/src/core/components/message/message.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
{{ userFullname }}
+
+
+ {{ isMine
+ ? ('addon.messages.you' | translate)
+ : userFullname }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/components/message/message.scss b/src/core/components/message/message.scss
new file mode 100644
index 000000000..64b90e61c
--- /dev/null
+++ b/src/core/components/message/message.scss
@@ -0,0 +1,138 @@
+@import "~theme/globals";
+
+:host {
+ --message-background: var(--core-messages-message-bg);
+ --message-activated-background: var(--core-messages-message-activated-bg);
+ --message-alignment: flex-start;
+
+ display: flex;
+ justify-content: var(--message-alignment);
+
+
+ .message-box {
+ --background: var(--message-background);
+ --min-height: var(--a11y-min-target-size);
+
+ display: flex;
+ flex-direction: row;
+ position: relative;
+
+ border: 0;
+ border-radius: var(--medium-radius);
+ margin: 8px;
+ width: 90%;
+ max-width: var(--list-item-max-width);
+ min-height: 36px;
+
+ font-size: var(--text-size);
+ color: var(--ion-text-color);
+
+ background: var(--message-background);
+ @include core-transition(width);
+
+ // This is needed to display bubble tails.
+ overflow: visible;
+
+ &:hover {
+ -webkit-filter: drop-shadow(2px 2px 2px rgba(0,0,0,.3));
+ filter: drop-shadow(2px 2px 2px rgba(0,0,0,.3));
+ }
+
+ &[tappable]:active {
+ --message-background: var(--message-activated-background);
+ }
+
+ .main {
+ padding: 8px;
+ flex-grow: 1;
+
+ .message-user {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: .5rem;
+ margin-top: 0;
+ color: var(--ion-text-color);
+
+ core-user-avatar {
+ display: block;
+ --core-avatar-size: var(--core-messages-avatar-size);
+ margin: 0;
+ }
+
+ div {
+ font-weight: 500;
+ flex-grow: 1;
+ padding-left: .5rem;
+ padding-right: .5rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ font-size: 16px;
+ }
+ }
+
+ .message-text {
+ ::ng-deep > p:only-child {
+ display: inline;
+ margin: 0;
+ }
+ }
+ }
+
+ .extra {
+ flex-shrink: 1;
+ display: flex;
+ flex-direction: row;
+ padding-left: 8px;
+ padding-right: 8px;
+
+ .message-time {
+ padding-top: 8px;
+ color: var(--core-messages-message-note-text);
+ font-size: var(--core-messages-message-note-font-size);
+ }
+
+ .delete-button {
+ min-height: initial;
+ line-height: initial;
+ margin: 0px;
+ align-self: flex-end;
+
+ ::ng-deep ion-icon {
+ font-size: 1.2em;
+ }
+ }
+ }
+
+ .tail {
+ content: '';
+ width: 0;
+ height: 0;
+ border: 0.5rem solid transparent;
+ position: absolute;
+ touch-action: none;
+ bottom: 0;
+ border-bottom-color: var(--message-background);
+ @include position(null, null, null, -8px);
+ }
+ }
+
+ &.no-user .message-box {
+ margin-top: 0px;
+ }
+
+ &.is-mine {
+ // Defined when a message is the user's.
+ --message-background: var(--core-messages-message-mine-bg);
+ --message-activated-background: var(--core-messages-message-mine-activated-bg);
+ --message-alignment: flex-end;
+
+ .message-box {
+ .tail {
+ @include position(null, -8px, null, unset);
+ }
+ }
+ }
+}
diff --git a/src/core/components/message/message.ts b/src/core/components/message/message.ts
new file mode 100644
index 000000000..818638aef
--- /dev/null
+++ b/src/core/components/message/message.ts
@@ -0,0 +1,121 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// 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 { ContextLevel } from '@/core/constants';
+import { Component, EventEmitter, HostBinding, Input, OnInit, Output } from '@angular/core';
+import { CoreAnimations } from '@components/animations';
+import { CoreSites } from '@services/sites';
+import { CoreUtils } from '@services/utils/utils';
+import { CoreTextUtils } from '@services/utils/text';
+import { CoreUserWithAvatar } from '@components/user-avatar/user-avatar';
+
+/**
+ * Component to handle a message in a conversation.
+ */
+@Component({
+ selector: 'core-message',
+ templateUrl: 'message.html',
+ styleUrls: ['message.scss'],
+ animations: [CoreAnimations.SLIDE_IN_OUT],
+})
+export class CoreMessageComponent implements OnInit {
+
+ @Input() message?: CoreMessageData; // The message object.
+ @Input() user?: CoreUserWithAvatar; // The user object.
+
+ @Input() text = ''; // Message text.
+ @Input() time = 0; // Message time.
+ @Input() instanceId = 0;
+ @Input() courseId?: number;
+ @Input() contextLevel: ContextLevel = ContextLevel.SYSTEM;
+ @Input() showDelete = false;
+ @Output() onDeleteMessage = new EventEmitter();
+ @Output() onUndoDeleteMessage = new EventEmitter();
+ @Output() afterRender = new EventEmitter();
+
+ protected deleted = false; // Needed to fix animation to void in Behat tests.
+
+ // @TODO Recover the animation using native css or wait for Angular 13.1
+ // where the bug https://github.com/angular/angular/issues/30693 is solved.
+ // @HostBinding('@coreSlideInOut') get animation(): string {
+ // return this.isMine ? '' : 'fromLeft';
+ // }
+
+ @HostBinding('class.is-mine') isMine = false;
+
+ @HostBinding('class.no-user') get showUser(): boolean {
+ return !this.message?.showUserData;
+ };
+
+ get userId(): number | undefined {
+ return this.user && (this.user.userid || this.user.id);
+ }
+
+ get userFullname(): string | undefined {
+ return this.user && (this.user.fullname || this.user.userfullname);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ async ngOnInit(): Promise {
+ const currentUserId = CoreSites.getCurrentSiteUserId();
+
+ this.isMine = this.userId === currentUserId;
+ }
+
+ /**
+ * Emits the delete action.
+ *
+ * @param event Event.
+ */
+ delete(event: Event): void {
+ event.preventDefault();
+ event.stopPropagation();
+ this.onDeleteMessage.emit();
+ }
+
+ /**
+ * Emits the undo delete action.
+ *
+ * @param event Event.
+ */
+ undoDelete(event: Event): void {
+ event.preventDefault();
+ event.stopPropagation();
+ this.onUndoDeleteMessage.emit();
+
+ }
+
+ /**
+ * Copy message to clipboard.
+ */
+ copyMessage(): void {
+ CoreUtils.copyToClipboard(CoreTextUtils.decodeHTMLEntities(this.text));
+ }
+
+}
+
+/**
+ * Conversation message with some calculated data.
+ */
+type CoreMessageData = {
+ pending?: boolean; // Whether the message is pending to be sent.
+ sending?: boolean; // Whether the message is being sent right now.
+ showDate?: boolean; // Whether to show the date before the message.
+ deleted?: boolean; // Whether the message has been deleted.
+ showUserData?: boolean; // Whether to show the user data in the message.
+ showTail?: boolean; // Whether to show a "tail" in the message.
+ delete?: boolean; // Permission to delete=true/false.
+};
diff --git a/src/core/components/user-avatar/user-avatar.ts b/src/core/components/user-avatar/user-avatar.ts
index 96f7afd80..85a087c19 100644
--- a/src/core/components/user-avatar/user-avatar.ts
+++ b/src/core/components/user-avatar/user-avatar.ts
@@ -156,7 +156,7 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges, OnDestroy {
/**
* Type with all possible formats of user.
*/
-type CoreUserWithAvatar = CoreUserBasicData & {
+export type CoreUserWithAvatar = CoreUserBasicData & {
userpictureurl?: string;
userprofileimageurl?: string;
profileimageurlsmall?: string;
diff --git a/src/core/features/comments/pages/viewer/viewer.html b/src/core/features/comments/pages/viewer/viewer.html
index 94ed52d8d..0df89ba27 100644
--- a/src/core/features/comments/pages/viewer/viewer.html
+++ b/src/core/features/comments/pages/viewer/viewer.html
@@ -45,71 +45,20 @@
{{ comment.timecreated * 1000 | coreFormatDate: "strftimedayshort" }}
-
-
-
-
-
-
-
{{ comment.fullname }}
-
-
-
-
-
-
-
-
-
- {{ comment.timecreated * 1000 | coreFormatDate: 'strftimetime' }}
-
-
-
- {{ 'core.deletedoffline' | translate }}
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
- {{ 'core.thereisdatatosync' | translate:{$a: 'core.comments.comments' | translate | lowercase } }}
-
-
-
-
-
-
-
-
- {{ 'core.notsent' | translate }}
-
-
-
-
-
-
+
+
+ {{ 'core.thereisdatatosync' | translate:{$a: 'core.comments.comments' | translate | lowercase } }}
+
+
+
diff --git a/src/core/features/comments/pages/viewer/viewer.page.ts b/src/core/features/comments/pages/viewer/viewer.page.ts
index 6e46394cf..4b79eedfe 100644
--- a/src/core/features/comments/pages/viewer/viewer.page.ts
+++ b/src/core/features/comments/pages/viewer/viewer.page.ts
@@ -14,7 +14,6 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
-import { CoreAnimations } from '@components/animations';
import { ActivatedRoute } from '@angular/router';
import { CoreSites } from '@services/sites';
import {
@@ -43,6 +42,7 @@ import { CoreApp } from '@services/app';
import { CoreNetwork } from '@services/network';
import moment from 'moment';
import { Subscription } from 'rxjs';
+import { CoreAnimations } from '@components/animations';
/**
* Page that displays comments.
@@ -75,7 +75,7 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
hasOffline = false;
refreshIcon = CoreConstants.ICON_LOADING;
syncIcon = CoreConstants.ICON_LOADING;
- offlineComment?: CoreCommentsOfflineWithUser;
+ offlineComment?: CoreCommentsOfflineWithUser & { pending?: boolean };
currentUserId: number;
sending = false;
newComment = '';
@@ -361,13 +361,9 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
/**
* Delete a comment.
*
- * @param e Click event.
* @param comment Comment to delete.
*/
- async deleteComment(e: Event, comment: CoreCommentsDataToDisplay | CoreCommentsOfflineWithUser): Promise {
- e.preventDefault();
- e.stopPropagation();
-
+ async deleteComment(comment: CoreCommentsDataToDisplay | CoreCommentsOfflineWithUser): Promise {
const modified = 'lastmodified' in comment
? comment.lastmodified
: comment.timecreated;
@@ -529,15 +525,16 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
).then(async (offlineComment) => {
this.offlineComment = offlineComment;
- if (!offlineComment) {
+ if (!this.offlineComment) {
return;
}
if (this.newComment == '') {
- this.newComment = this.offlineComment!.content;
+ this.newComment = this.offlineComment.content;
}
- this.offlineComment!.userid = this.currentUserId;
+ this.offlineComment.userid = this.currentUserId;
+ this.offlineComment.pending = true;
return;
}));
@@ -573,13 +570,9 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
/**
* Restore a comment.
*
- * @param e Click event.
* @param comment Comment to delete.
*/
- async undoDeleteComment(e: Event, comment: CoreCommentsDataToDisplay): Promise {
- e.preventDefault();
- e.stopPropagation();
-
+ async undoDeleteComment(comment: CoreCommentsDataToDisplay): Promise {
await CoreCommentsOffline.undoDeleteComment(comment.id);
comment.deleted = false;
diff --git a/src/core/features/comments/pages/viewer/viewer.scss b/src/core/features/comments/pages/viewer/viewer.scss
index 7fb2d0cc4..cf231da48 100644
--- a/src/core/features/comments/pages/viewer/viewer.scss
+++ b/src/core/features/comments/pages/viewer/viewer.scss
@@ -1 +1,5 @@
@import "~theme/components/discussion.scss";
+
+ion-badge {
+ margin: 8px auto;
+}
diff --git a/src/theme/components/discussion.scss b/src/theme/components/discussion.scss
index 540188a0e..fcb653a9d 100644
--- a/src/theme/components/discussion.scss
+++ b/src/theme/components/discussion.scss
@@ -27,148 +27,3 @@ ion-content {
font-weight: normal;
font-size: 0.9rem;
}
-
-// Message item.
-ion-item.addon-message {
- --message-background: var(--addon-messages-message-bg);
- --message-activated-background: var(--addon-messages-message-activated-bg);
- --message-alignment: flex-start;
-
- border: 0;
- border-radius: var(--medium-radius);
- padding: 0 8px 0 8px;
- margin: 8px;
- --background: var(--message-background);
- background: var(--message-background);
- align-self: var(--message-alignment);
- width: 90%;
- max-width: var(--list-item-max-width);
- --min-height: var(--a11y-min-target-size);
- position: relative;
- @include core-transition(width);
- // This is needed to display bubble tails.
- overflow: visible;
-
- &::part(native) {
- --inner-border-width: 0px;
- --inner-padding-end: 0px;
- padding: 0;
- margin: 0;
- }
-
- &:hover {
- -webkit-filter: drop-shadow(2px 2px 2px rgba(0,0,0,.3));
- filter: drop-shadow(2px 2px 2px rgba(0,0,0,.3));
- }
-
- core-format-text > p:only-child {
- display: inline;
- }
-
- .addon-message-user {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- margin-bottom: .5rem;
- margin-top: 0;
- color: var(--ion-text-color);
-
- core-user-avatar {
- display: block;
- --core-avatar-size: var(--addon-messages-avatar-size);
- margin: 0;
- }
-
- div {
- font-weight: 500;
- flex-grow: 1;
- padding-left: .5rem;
- padding-right: .5rem;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- }
-
- ion-note {
- color: var(--addon-messages-message-note-text);
- font-size: var(--addon-messages-message-note-font-size);
- margin: 0;
- padding: 8px 0;
- align-self: flex-start;
- }
-
- &[tappable]:active {
- --message-background: var(--message-activated-background);
- }
-
- ion-label {
- margin: 0;
- padding: 8px 0;
- }
-
- .addon-message-text {
- display: inline-flex;
- * {
- color: var(--ion-text-color);
- }
- }
-
- .tail {
- content: '';
- width: 0;
- height: 0;
- border: 0.5rem solid transparent;
- position: absolute;
- touch-action: none;
- bottom: 0;
- border-bottom-color: var(--message-background);
- }
-
- // Defines when an item-message is the user's.
- &.addon-message-mine {
- --message-background: var(--addon-messages-message-mine-bg);
- --message-activated-background: var(--addon-messages-message-mine-activated-bg);
- --message-alignment: flex-end;
-
- .spinner {
- @include float(end);
- @include margin(2px, -3px, -2px, 5px);
-
- svg {
- width: 16px;
- height: 16px;
- }
- }
-
- .tail {
- @include position(null, -8px, null, null);
- @include margin-horizontal(null, -0.5rem);
- }
- }
-
- &.addon-message-not-mine .tail {
- @include position(null, null, null, -8px);
- @include margin-horizontal(-0.5rem, null);
- }
-
- .addon-messages-delete-button {
- min-height: initial;
- line-height: initial;
- margin-top: 0px;
- margin-bottom: 0px;
- height: var(--a11y-min-target-size) !important;
- align-self: flex-end;
-
- ion-icon {
- font-size: 1.4em;
- line-height: initial;
- color: var(--danger);
- }
- }
-
- &.addon-message-no-user {
- margin-top: 0px;
- }
-}
diff --git a/src/theme/theme.dark.scss b/src/theme/theme.dark.scss
index ecd188b0c..a526f82ea 100644
--- a/src/theme/theme.dark.scss
+++ b/src/theme/theme.dark.scss
@@ -146,13 +146,13 @@
--core-collapsible-footer-background: var(--contrast-background);
- --addon-messages-message-bg: var(--gray-800);
- --addon-messages-message-activated-bg: var(--gray-700);
- --addon-messages-message-note-text: var(--subdued-text-color);
- --addon-messages-message-mine-bg: var(--gray-700);
- --addon-messages-message-mine-activated-bg: var(--gray-600);
- --addon-messages-discussion-badge: var(--primary);
- --addon-messages-discussion-badge-text: var(--gray-100);
+ --core-messages-message-bg: var(--gray-800);
+ --core-messages-message-activated-bg: var(--gray-700);
+ --core-messages-message-note-text: var(--subdued-text-color);
+ --core-messages-message-mine-bg: var(--gray-700);
+ --core-messages-message-mine-activated-bg: var(--gray-600);
+ --core-messages-discussion-badge: var(--primary);
+ --core-messages-discussion-badge-text: var(--gray-100);
--addon-forum-border-color: var(--gray-500);
--addon-forum-highlight-color: var(--gray-200);
diff --git a/src/theme/theme.light.scss b/src/theme/theme.light.scss
index f13f3aee1..780297398 100644
--- a/src/theme/theme.light.scss
+++ b/src/theme/theme.light.scss
@@ -344,15 +344,15 @@
--addon-calendar-today-border-color: var(--primary);
--addon-calendar-border-color: var(--stroke);
- --addon-messages-message-bg: var(--white);
- --addon-messages-message-activated-bg: var(--gray-200);
- --addon-messages-message-note-text: var(--gray-500);
- --addon-messages-message-note-font-size: 75%;
- --addon-messages-message-mine-bg: var(--gray-300);
- --addon-messages-message-mine-activated-bg: var(--gray-400);
- --addon-messages-avatar-size: 30px;
- --addon-messages-discussion-badge: var(--primary);
- --addon-messages-discussion-badge-text: var(--white);
+ --core-messages-message-bg: var(--white);
+ --core-messages-message-activated-bg: var(--gray-200);
+ --core-messages-message-note-text: var(--gray-500);
+ --core-messages-message-note-font-size: 75%;
+ --core-messages-message-mine-bg: var(--gray-300);
+ --core-messages-message-mine-activated-bg: var(--gray-400);
+ --core-messages-avatar-size: 30px;
+ --core-messages-discussion-badge: var(--primary);
+ --core-messages-discussion-badge-text: var(--white);
--addon-forum-avatar-size: var(--core-avatar-size);
--addon-forum-border-color: var(--stroke);
diff --git a/upgrade.txt b/upgrade.txt
index ead37e419..7576f9804 100644
--- a/upgrade.txt
+++ b/upgrade.txt
@@ -1,9 +1,10 @@
This files describes API changes in the Moodle Mobile app,
information provided here is intended especially for developers.
-=== 4.0.1 ===
+=== 4.1.0 ===
- Zoom levels changed from "normal / low / high" to " none / medium / high".
+- --addon-messages-* CSS3 variables have been renamed to --core-messages-*
=== 4.0.0 ===