MOBILE-2962 messages: Support self conversations
parent
13a9dab037
commit
546667d11a
|
@ -179,6 +179,7 @@
|
||||||
"addon.messages.contacts": "message",
|
"addon.messages.contacts": "message",
|
||||||
"addon.messages.decline": "message",
|
"addon.messages.decline": "message",
|
||||||
"addon.messages.deleteallconfirm": "message",
|
"addon.messages.deleteallconfirm": "message",
|
||||||
|
"addon.messages.deleteallselfconfirm": "message",
|
||||||
"addon.messages.deleteconversation": "message",
|
"addon.messages.deleteconversation": "message",
|
||||||
"addon.messages.deletemessage": "local_moodlemobileapp",
|
"addon.messages.deletemessage": "local_moodlemobileapp",
|
||||||
"addon.messages.deletemessageconfirmation": "local_moodlemobileapp",
|
"addon.messages.deletemessageconfirmation": "local_moodlemobileapp",
|
||||||
|
@ -217,6 +218,8 @@
|
||||||
"addon.messages.searchnocontactsfound": "message",
|
"addon.messages.searchnocontactsfound": "message",
|
||||||
"addon.messages.searchnomessagesfound": "message",
|
"addon.messages.searchnomessagesfound": "message",
|
||||||
"addon.messages.searchnononcontactsfound": "message",
|
"addon.messages.searchnononcontactsfound": "message",
|
||||||
|
"addon.messages.selfconversation": "message",
|
||||||
|
"addon.messages.selfconversationdefaultmessage": "message",
|
||||||
"addon.messages.sendcontactrequest": "message",
|
"addon.messages.sendcontactrequest": "message",
|
||||||
"addon.messages.showdeletemessages": "local_moodlemobileapp",
|
"addon.messages.showdeletemessages": "local_moodlemobileapp",
|
||||||
"addon.messages.type_blocked": "local_moodlemobileapp",
|
"addon.messages.type_blocked": "local_moodlemobileapp",
|
||||||
|
@ -1342,6 +1345,7 @@
|
||||||
"core.favourites": "moodle",
|
"core.favourites": "moodle",
|
||||||
"core.filename": "repository",
|
"core.filename": "repository",
|
||||||
"core.filenameexist": "local_moodlemobileapp",
|
"core.filenameexist": "local_moodlemobileapp",
|
||||||
|
"core.filenotfound": "resource",
|
||||||
"core.fileuploader.addfiletext": "repository",
|
"core.fileuploader.addfiletext": "repository",
|
||||||
"core.fileuploader.audio": "local_moodlemobileapp",
|
"core.fileuploader.audio": "local_moodlemobileapp",
|
||||||
"core.fileuploader.camera": "local_moodlemobileapp",
|
"core.fileuploader.camera": "local_moodlemobileapp",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"contacts": "Contacts",
|
"contacts": "Contacts",
|
||||||
"decline": "Decline",
|
"decline": "Decline",
|
||||||
"deleteallconfirm": "Are you sure you would like to delete this entire conversation? This will not delete it for other conversation participants.",
|
"deleteallconfirm": "Are you sure you would like to delete this entire conversation? This will not delete it for other conversation participants.",
|
||||||
|
"deleteallselfconfirm": "Are you sure you would like to delete this entire personal conversation?",
|
||||||
"deleteconversation": "Delete conversation",
|
"deleteconversation": "Delete conversation",
|
||||||
"deletemessage": "Delete message",
|
"deletemessage": "Delete message",
|
||||||
"deletemessageconfirmation": "Are you sure you want to delete this message? It will only be deleted from your messaging history and will still be viewable by the user who sent or received the message.",
|
"deletemessageconfirmation": "Are you sure you want to delete this message? It will only be deleted from your messaging history and will still be viewable by the user who sent or received the message.",
|
||||||
|
@ -56,6 +57,8 @@
|
||||||
"searchnocontactsfound": "No contacts found",
|
"searchnocontactsfound": "No contacts found",
|
||||||
"searchnomessagesfound": "No messages found",
|
"searchnomessagesfound": "No messages found",
|
||||||
"searchnononcontactsfound": "No non contacts found",
|
"searchnononcontactsfound": "No non contacts found",
|
||||||
|
"selfconversation": "Personal space",
|
||||||
|
"selfconversationdefaultmessage": "Save draft messages, links, notes etc. to access later.",
|
||||||
"sendcontactrequest": "Send contact request",
|
"sendcontactrequest": "Send contact request",
|
||||||
"showdeletemessages": "Show delete messages",
|
"showdeletemessages": "Show delete messages",
|
||||||
"type_blocked": "Blocked",
|
"type_blocked": "Blocked",
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
</ion-navbar>
|
</ion-navbar>
|
||||||
<core-navbar-buttons end>
|
<core-navbar-buttons end>
|
||||||
<core-context-menu>
|
<core-context-menu>
|
||||||
<core-context-menu-item [hidden]="!showInfo || isGroup" [priority]="1000" [content]="'addon.messages.info' | translate" (action)="viewInfo()" iconAction="information-circle"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !showInfo || isGroup" [priority]="1000" [content]="'addon.messages.info' | translate" (action)="viewInfo()" iconAction="information-circle"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!showInfo || !isGroup" [priority]="1000" [content]="'addon.messages.groupinfo' | translate" (action)="viewInfo()" iconAction="information-circle"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !showInfo || !isGroup" [priority]="1000" [content]="'addon.messages.groupinfo' | translate" (action)="viewInfo()" iconAction="information-circle"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!groupMessagingEnabled || !conversation" [priority]="800" [content]="(conversation && conversation.isfavourite ? 'addon.messages.removefromfavourites' : 'addon.messages.addtofavourites') | translate" (action)="changeFavourite($event)" [closeOnClick]="false" [iconAction]="favouriteIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="!groupMessagingEnabled || !conversation" [priority]="800" [content]="(conversation && conversation.isfavourite ? 'addon.messages.removefromfavourites' : 'addon.messages.addtofavourites') | translate" (action)="changeFavourite($event)" [closeOnClick]="false" [iconAction]="favouriteIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!otherMember || otherMember.isblocked" [priority]="700" [content]="'addon.messages.blockuser' | translate" (action)="blockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.isblocked" [priority]="700" [content]="'addon.messages.blockuser' | translate" (action)="blockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!otherMember || !otherMember.isblocked" [priority]="700" [content]="'addon.messages.unblockuser' | translate" (action)="unblockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.isblocked" [priority]="700" [content]="'addon.messages.unblockuser' | translate" (action)="unblockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!canDelete" [priority]="400" [content]="'addon.messages.showdeletemessages' | translate" (action)="toggleDelete()" [iconAction]="(showDelete ? 'checkbox-outline' : 'square-outline')"></core-context-menu-item>
|
<core-context-menu-item [hidden]="!canDelete" [priority]="400" [content]="'addon.messages.showdeletemessages' | translate" (action)="toggleDelete()" [iconAction]="(showDelete ? 'checkbox-outline' : 'square-outline')"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!groupMessagingEnabled || !conversationId || isGroup" [priority]="200" [content]="'addon.messages.deleteconversation' | translate" (action)="deleteConversation($event)" [closeOnClick]="false" [iconAction]="deleteIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="!groupMessagingEnabled || !conversationId || isGroup" [priority]="200" [content]="'addon.messages.deleteconversation' | translate" (action)="deleteConversation($event)" [closeOnClick]="false" [iconAction]="deleteIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" [priority]="100" [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" [iconAction]="addRemoveIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" [priority]="100" [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" [iconAction]="addRemoveIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!otherMember || !otherMember.iscontact" [priority]="100" [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" [iconAction]="addRemoveIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.iscontact" [priority]="100" [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" [iconAction]="addRemoveIcon"></core-context-menu-item>
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
@ -26,6 +26,12 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<!-- Load previous messages. -->
|
<!-- Load previous messages. -->
|
||||||
<core-infinite-loading [enabled]="canLoadMore" (action)="loadPrevious($event)" position="top" [error]="loadMoreError"></core-infinite-loading>
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadPrevious($event)" position="top" [error]="loadMoreError"></core-infinite-loading>
|
||||||
|
|
||||||
|
<ng-container *ngIf="isSelf && !canLoadMore">
|
||||||
|
<p text-center>{{ 'addon.messages.selfconversation' | translate }}</p>
|
||||||
|
<p text-center><i>{{ 'addon.messages.selfconversationdefaultmessage' | translate }}</i></p>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ion-list class="addon-messages-discussion-container safe-area-page" [class.addon-messages-discussion-group]="isGroup" [attr.aria-live]="'polite'">
|
<ion-list class="addon-messages-discussion-container safe-area-page" [class.addon-messages-discussion-group]="isGroup" [attr.aria-live]="'polite'">
|
||||||
<ng-container *ngFor="let message of messages; index as index; last as last">
|
<ng-container *ngFor="let message of messages; index as index; last as last">
|
||||||
<h6 text-center *ngIf="message.showDate" class="addon-messages-date">
|
<h6 text-center *ngIf="message.showDate" class="addon-messages-date">
|
||||||
|
|
|
@ -85,6 +85,7 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
footerType: 'message' | 'blocked' | 'requiresContact' | 'requestSent' | 'requestReceived' | 'unable';
|
footerType: 'message' | 'blocked' | 'requiresContact' | 'requestSent' | 'requestReceived' | 'unable';
|
||||||
requestContactSent = false;
|
requestContactSent = false;
|
||||||
requestContactReceived = false;
|
requestContactReceived = false;
|
||||||
|
isSelf = false;
|
||||||
|
|
||||||
constructor(private eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, navParams: NavParams,
|
constructor(private eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, navParams: NavParams,
|
||||||
private userProvider: CoreUserProvider, private navCtrl: NavController, private messagesSync: AddonMessagesSyncProvider,
|
private userProvider: CoreUserProvider, private navCtrl: NavController, private messagesSync: AddonMessagesSyncProvider,
|
||||||
|
@ -402,7 +403,13 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
if (conversationId) {
|
if (conversationId) {
|
||||||
promise = Promise.resolve(conversationId);
|
promise = Promise.resolve(conversationId);
|
||||||
} else {
|
} else {
|
||||||
promise = this.messagesProvider.getConversationBetweenUsers(userId, undefined, true).then((conversation) => {
|
if (userId == this.currentUserId && this.messagesProvider.isSelfConversationEnabled()) {
|
||||||
|
promise = this.messagesProvider.getSelfConversation();
|
||||||
|
} else {
|
||||||
|
promise = this.messagesProvider.getConversationBetweenUsers(userId, undefined, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
promise = promise.then((conversation) => {
|
||||||
fallbackConversation = conversation;
|
fallbackConversation = conversation;
|
||||||
|
|
||||||
return conversation.id;
|
return conversation.id;
|
||||||
|
@ -434,6 +441,7 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
if (!this.isGroup) {
|
if (!this.isGroup) {
|
||||||
this.userId = conversation.userid;
|
this.userId = conversation.userid;
|
||||||
}
|
}
|
||||||
|
this.isSelf = conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_SELF;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -442,7 +450,9 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
});
|
});
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
// Probably conversation does not exist or user is offline. Try to load offline messages.
|
// Probably conversation does not exist or user is offline. Try to load offline messages.
|
||||||
return this.messagesOffline.getMessages(userId).then((messages) => {
|
this.isSelf = userId == this.currentUserId;
|
||||||
|
|
||||||
|
return this.messagesOffline.getMessages(userId).then((messages): any => {
|
||||||
if (messages && messages.length) {
|
if (messages && messages.length) {
|
||||||
// We have offline messages, this probably means that the conversation didn't exist. Don't display error.
|
// We have offline messages, this probably means that the conversation didn't exist. Don't display error.
|
||||||
messages.forEach((message) => {
|
messages.forEach((message) => {
|
||||||
|
@ -455,6 +465,8 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
// Display the error.
|
// Display the error.
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1123,7 +1135,9 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
* @param {Function} [done] Function to call when done.
|
* @param {Function} [done] Function to call when done.
|
||||||
*/
|
*/
|
||||||
deleteConversation(done?: () => void): void {
|
deleteConversation(done?: () => void): void {
|
||||||
this.domUtils.showConfirm(this.translate.instant('addon.messages.deleteallconfirm')).then(() => {
|
const confirmMessage = 'addon.messages.' + (this.isSelf ? 'deleteallselfconfirm' : 'deleteallconfirm');
|
||||||
|
|
||||||
|
this.domUtils.showConfirm(this.translate.instant(confirmMessage)).then(() => {
|
||||||
this.deleteIcon = 'spinner';
|
this.deleteIcon = 'spinner';
|
||||||
|
|
||||||
return this.messagesProvider.deleteConversation(this.conversation.id).then(() => {
|
return this.messagesProvider.deleteConversation(this.conversation.id).then(() => {
|
||||||
|
|
|
@ -91,12 +91,12 @@
|
||||||
<ng-template #conversationsTemplate let-conversations="conversations">
|
<ng-template #conversationsTemplate let-conversations="conversations">
|
||||||
<a ion-item text-wrap *ngFor="let conversation of conversations" [title]="conversation.name" (click)="gotoConversation(conversation.id, conversation.userid)" [class.core-split-item-selected]="(conversation.id && conversation.id == selectedConversationId) || (conversation.userid && conversation.userid == selectedUserId)" class="addon-message-discussion" id="addon-message-conversation-{{ conversation.id ? conversation.id : 'user-' + conversation.userid }}">
|
<a ion-item text-wrap *ngFor="let conversation of conversations" [title]="conversation.name" (click)="gotoConversation(conversation.id, conversation.userid)" [class.core-split-item-selected]="(conversation.id && conversation.id == selectedConversationId) || (conversation.userid && conversation.userid == selectedUserId)" class="addon-message-discussion" id="addon-message-conversation-{{ conversation.id ? conversation.id : 'user-' + conversation.userid }}">
|
||||||
<!-- Group conversation image. -->
|
<!-- Group conversation image. -->
|
||||||
<ion-avatar item-start *ngIf="conversation.type != typeIndividual">
|
<ion-avatar item-start *ngIf="conversation.type == typeGroup">
|
||||||
<img [src]="conversation.imageurl" [alt]="conversation.name" core-external-content onError="this.src='assets/img/group-avatar.png'">
|
<img [src]="conversation.imageurl" [alt]="conversation.name" core-external-content onError="this.src='assets/img/group-avatar.png'">
|
||||||
</ion-avatar>
|
</ion-avatar>
|
||||||
|
|
||||||
<!-- Avatar for individual conversations. -->
|
<!-- Avatar for individual conversations. -->
|
||||||
<ion-avatar *ngIf="conversation.type == typeIndividual" core-user-avatar [user]="conversation.otherUser" [linkProfile]="false" [checkOnline]="conversation.showonlinestatus" item-start></ion-avatar>
|
<ion-avatar *ngIf="conversation.type != typeGroup" core-user-avatar [user]="conversation.otherUser" [linkProfile]="false" [checkOnline]="conversation.showonlinestatus" item-start></ion-avatar>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<core-format-text [text]="conversation.name"></core-format-text>
|
<core-format-text [text]="conversation.name"></core-format-text>
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
<p *ngIf="conversation.subname"><core-format-text [text]="conversation.subname"></core-format-text></p>
|
<p *ngIf="conversation.subname"><core-format-text [text]="conversation.subname"></core-format-text></p>
|
||||||
<p class="addon-message-last-message">
|
<p class="addon-message-last-message">
|
||||||
<span *ngIf="conversation.sentfromcurrentuser" class="addon-message-last-message-user">{{ 'addon.messages.you' | translate }}</span>
|
<span *ngIf="conversation.sentfromcurrentuser" class="addon-message-last-message-user">{{ 'addon.messages.you' | translate }}</span>
|
||||||
<core-format-text *ngIf="conversation.type != typeIndividual && conversation.members[0]" [text]="conversation.members[0].fullname + ':'" class="addon-message-last-message-user"></core-format-text>
|
<core-format-text *ngIf="!conversation.sentfromcurrentuser && conversation.type == typeGroup && conversation.members[0]" [text]="conversation.members[0].fullname + ':'" class="addon-message-last-message-user"></core-format-text>
|
||||||
<core-format-text clean="true" singleLine="true" [text]="conversation.lastmessage" class="addon-message-last-message-text"></core-format-text>
|
<core-format-text clean="true" singleLine="true" [text]="conversation.lastmessage" class="addon-message-last-message-text"></core-format-text>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -63,7 +63,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
count: 0,
|
count: 0,
|
||||||
unread: 0
|
unread: 0
|
||||||
};
|
};
|
||||||
typeIndividual = AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL;
|
typeGroup = AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP;
|
||||||
currentListEl: HTMLElement;
|
currentListEl: HTMLElement;
|
||||||
|
|
||||||
protected loadingString: string;
|
protected loadingString: string;
|
||||||
|
@ -182,7 +182,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
// Update unread conversation counts.
|
// Update unread conversation counts.
|
||||||
this.cronObserver = eventsProvider.on(AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, (data) => {
|
this.cronObserver = eventsProvider.on(AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, (data) => {
|
||||||
this.favourites.unread = data.favourites;
|
this.favourites.unread = data.favourites;
|
||||||
this.individual.unread = data.individual;
|
this.individual.unread = data.individual + data.self; // Self is only returned if it's not favourite.
|
||||||
this.group.unread = data.group;
|
this.group.unread = data.group;
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
return this.messagesProvider.getConversationCounts(this.siteId);
|
return this.messagesProvider.getConversationCounts(this.siteId);
|
||||||
}).then((counts) => {
|
}).then((counts) => {
|
||||||
this.favourites.count = counts.favourites;
|
this.favourites.count = counts.favourites;
|
||||||
this.individual.count = counts.individual;
|
this.individual.count = counts.individual + counts.self; // Self is only returned if it's not favourite.
|
||||||
this.group.count = counts.group;
|
this.group.count = counts.group;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class AddonMessagesMainMenuHandler implements CoreMainMenuHandler, CoreCr
|
||||||
pushNotificationsDelegate: AddonPushNotificationsDelegate, private emulatorHelper: CoreEmulatorHelperProvider) {
|
pushNotificationsDelegate: AddonPushNotificationsDelegate, private emulatorHelper: CoreEmulatorHelperProvider) {
|
||||||
|
|
||||||
eventsProvider.on(AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, (data) => {
|
eventsProvider.on(AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, (data) => {
|
||||||
this.unreadCount = data.favourites + data.individual + data.group;
|
this.unreadCount = data.favourites + data.individual + data.group + data.self;
|
||||||
this.orMore = data.orMore;
|
this.orMore = data.orMore;
|
||||||
this.updateBadge(data.siteId);
|
this.updateBadge(data.siteId);
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,6 +47,7 @@ export class AddonMessagesProvider {
|
||||||
static MESSAGE_PRIVACY_SITE = 2; // Privacy setting for being messaged by anyone on the site.
|
static MESSAGE_PRIVACY_SITE = 2; // Privacy setting for being messaged by anyone on the site.
|
||||||
static MESSAGE_CONVERSATION_TYPE_INDIVIDUAL = 1; // An individual conversation.
|
static MESSAGE_CONVERSATION_TYPE_INDIVIDUAL = 1; // An individual conversation.
|
||||||
static MESSAGE_CONVERSATION_TYPE_GROUP = 2; // A group conversation.
|
static MESSAGE_CONVERSATION_TYPE_GROUP = 2; // A group conversation.
|
||||||
|
static MESSAGE_CONVERSATION_TYPE_SELF = 3; // A self conversation.
|
||||||
static LIMIT_CONTACTS = 50;
|
static LIMIT_CONTACTS = 50;
|
||||||
static LIMIT_MESSAGES = 50;
|
static LIMIT_MESSAGES = 50;
|
||||||
static LIMIT_INITIAL_USER_SEARCH = 3;
|
static LIMIT_INITIAL_USER_SEARCH = 3;
|
||||||
|
@ -297,9 +298,10 @@ export class AddonMessagesProvider {
|
||||||
conversation.lastmessagedate = lastMessage ? lastMessage.timecreated : null;
|
conversation.lastmessagedate = lastMessage ? lastMessage.timecreated : null;
|
||||||
conversation.sentfromcurrentuser = lastMessage ? lastMessage.useridfrom == userId : null;
|
conversation.sentfromcurrentuser = lastMessage ? lastMessage.useridfrom == userId : null;
|
||||||
|
|
||||||
if (conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) {
|
if (conversation.type != AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) {
|
||||||
const otherUser = conversation.members.reduce((carry, member) => {
|
const isIndividual = conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
|
||||||
if (!carry && member.id != userId) {
|
otherUser = conversation.members.reduce((carry, member) => {
|
||||||
|
if (!carry && ((isIndividual && member.id != userId) || (!isIndividual && member.id == userId))) {
|
||||||
carry = member;
|
carry = member;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,6 +480,16 @@ export class AddonMessagesProvider {
|
||||||
return this.ROOT_CACHE_KEY + 'memberInfo:' + userId + ':' + otherUserId;
|
return this.ROOT_CACHE_KEY + 'memberInfo:' + userId + ':' + otherUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for get self conversation.
|
||||||
|
*
|
||||||
|
* @param {number} userId User ID.
|
||||||
|
* @return {string} Cache key.
|
||||||
|
*/
|
||||||
|
protected getCacheKeyForSelfConversation(userId: number): string {
|
||||||
|
return this.ROOT_CACHE_KEY + 'selfconversation:' + userId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get common cache key for get user conversations.
|
* Get common cache key for get user conversations.
|
||||||
*
|
*
|
||||||
|
@ -948,7 +960,21 @@ export class AddonMessagesProvider {
|
||||||
params.favourites = favourites ? 1 : 0;
|
params.favourites = favourites ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return site.read('core_message_get_conversations', params, preSets).then((response) => {
|
if (site.isVersionGreaterEqualThan('3.7') && type != AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) {
|
||||||
|
// Add self conversation to the list.
|
||||||
|
params.mergeself = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return site.read('core_message_get_conversations', params, preSets).catch((error) => {
|
||||||
|
if (params.mergeself) {
|
||||||
|
// Try again without the new param. Maybe the user is offline and he has a previous request cached.
|
||||||
|
delete params.mergeself;
|
||||||
|
|
||||||
|
return site.read('core_message_get_conversations', params, preSets);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error);
|
||||||
|
}).then((response) => {
|
||||||
// Format the conversations, adding some calculated fields.
|
// Format the conversations, adding some calculated fields.
|
||||||
const conversations = response.conversations.slice(0, this.LIMIT_MESSAGES).map((conversation) => {
|
const conversations = response.conversations.slice(0, this.LIMIT_MESSAGES).map((conversation) => {
|
||||||
return this.formatConversation(conversation, userId);
|
return this.formatConversation(conversation, userId);
|
||||||
|
@ -966,11 +992,11 @@ export class AddonMessagesProvider {
|
||||||
* Get conversation counts by type.
|
* Get conversation counts by type.
|
||||||
*
|
*
|
||||||
* @param {string} [siteId] Site ID. If not defined, use current site.
|
* @param {string} [siteId] Site ID. If not defined, use current site.
|
||||||
* @return {Promise<favourites: number, individual: number, group: number>} Promise resolved with favourite, individual and
|
* @return {Promise<favourites: number, individual: number, group: number, self: number>} Promise resolved with favourite,
|
||||||
* group conversation counts.
|
* individual, group and self conversation counts.
|
||||||
* @since 3.6
|
* @since 3.6
|
||||||
*/
|
*/
|
||||||
getConversationCounts(siteId?: string): Promise<{favourites: number, individual: number, group: number}> {
|
getConversationCounts(siteId?: string): Promise<{favourites: number, individual: number, group: number, self: number}> {
|
||||||
|
|
||||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
const preSets = {
|
const preSets = {
|
||||||
|
@ -981,7 +1007,8 @@ export class AddonMessagesProvider {
|
||||||
const counts = {
|
const counts = {
|
||||||
favourites: result.favourites,
|
favourites: result.favourites,
|
||||||
individual: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
|
individual: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
|
||||||
group: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP]
|
group: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP],
|
||||||
|
self: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_SELF] || 0
|
||||||
};
|
};
|
||||||
|
|
||||||
return counts;
|
return counts;
|
||||||
|
@ -1337,6 +1364,40 @@ export class AddonMessagesProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a self conversation.
|
||||||
|
*
|
||||||
|
* @param {number} [messageOffset=0] Offset for messages list.
|
||||||
|
* @param {number} [messageLimit=1] Limit of messages. Defaults to 1 (last message).
|
||||||
|
* We recommend getConversationMessages to get them.
|
||||||
|
* @param {boolean} [newestFirst=true] Whether to order messages by newest first.
|
||||||
|
* @param {string} [siteId] Site ID. If not defined, use current site.
|
||||||
|
* @param {string} [userId] User ID to get the self conversation for. If not defined, current user in the site.
|
||||||
|
* @return {Promise<any>} Promise resolved with the response.
|
||||||
|
* @since 3.7
|
||||||
|
*/
|
||||||
|
getSelfConversation(messageOffset: number = 0, messageLimit: number = 1, newestFirst: boolean = true, siteId?: string,
|
||||||
|
userId?: number): Promise<any> {
|
||||||
|
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
userId = userId || site.getUserId();
|
||||||
|
|
||||||
|
const preSets = {
|
||||||
|
cacheKey: this.getCacheKeyForSelfConversation(userId)
|
||||||
|
},
|
||||||
|
params: any = {
|
||||||
|
userid: userId,
|
||||||
|
messageoffset: messageOffset,
|
||||||
|
messagelimit: messageLimit,
|
||||||
|
newestmessagesfirst: newestFirst ? 1 : 0
|
||||||
|
};
|
||||||
|
|
||||||
|
return site.read('core_message_get_self_conversation', params, preSets).then((conversation) => {
|
||||||
|
return this.formatConversation(conversation, userId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get unread conversation counts by type.
|
* Get unread conversation counts by type.
|
||||||
*
|
*
|
||||||
|
@ -1344,10 +1405,10 @@ export class AddonMessagesProvider {
|
||||||
* @return {Promise<any>} Resolved with the unread favourite, individual and group conversation counts.
|
* @return {Promise<any>} Resolved with the unread favourite, individual and group conversation counts.
|
||||||
*/
|
*/
|
||||||
getUnreadConversationCounts(siteId?: string):
|
getUnreadConversationCounts(siteId?: string):
|
||||||
Promise<{favourites: number, individual: number, group: number, orMore?: boolean}> {
|
Promise<{favourites: number, individual: number, group: number, self: number, orMore?: boolean}> {
|
||||||
|
|
||||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
let promise: Promise<{favourites: number, individual: number, group: number, orMore?: boolean}>;
|
let promise: Promise<{favourites: number, individual: number, group: number, self: number, orMore?: boolean}>;
|
||||||
|
|
||||||
if (this.isGroupMessagingEnabled()) {
|
if (this.isGroupMessagingEnabled()) {
|
||||||
// @since 3.6
|
// @since 3.6
|
||||||
|
@ -1359,7 +1420,8 @@ export class AddonMessagesProvider {
|
||||||
return {
|
return {
|
||||||
favourites: result.favourites,
|
favourites: result.favourites,
|
||||||
individual: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
|
individual: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
|
||||||
group: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP]
|
group: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP],
|
||||||
|
self: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_SELF] || 0
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1374,7 +1436,7 @@ export class AddonMessagesProvider {
|
||||||
};
|
};
|
||||||
|
|
||||||
promise = site.read('core_message_get_unread_conversations_count', params, preSets).then((count) => {
|
promise = site.read('core_message_get_unread_conversations_count', params, preSets).then((count) => {
|
||||||
return { favourites: 0, individual: count, group: 0 };
|
return { favourites: 0, individual: count, group: 0, self: 0 };
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Fallback call.
|
// Fallback call.
|
||||||
|
@ -1399,6 +1461,7 @@ export class AddonMessagesProvider {
|
||||||
favourites: 0,
|
favourites: 0,
|
||||||
individual: count,
|
individual: count,
|
||||||
group: 0,
|
group: 0,
|
||||||
|
self: 0,
|
||||||
orMore: count > this.LIMIT_MESSAGES
|
orMore: count > this.LIMIT_MESSAGES
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1696,6 +1759,21 @@ export class AddonMessagesProvider {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate a self conversation.
|
||||||
|
*
|
||||||
|
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||||
|
* @param {number} [userId] User ID. If not defined, current user in the site.
|
||||||
|
* @return {Promise<any>} Resolved when done.
|
||||||
|
*/
|
||||||
|
invalidateSelfConversation(siteId?: string, userId?: number): Promise<any> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
userId = userId || site.getUserId();
|
||||||
|
|
||||||
|
return site.invalidateWsCacheForKey(this.getCacheKeyForSelfConversation(userId));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate unread conversation counts cache.
|
* Invalidate unread conversation counts cache.
|
||||||
*
|
*
|
||||||
|
@ -1860,6 +1938,34 @@ export class AddonMessagesProvider {
|
||||||
return this.sitesProvider.wsAvailableInCurrentSite('core_message_data_for_messagearea_search_messages');
|
return this.sitesProvider.wsAvailableInCurrentSite('core_message_data_for_messagearea_search_messages');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not self conversation is supported in a certain site.
|
||||||
|
*
|
||||||
|
* @param {CoreSite} [site] Site. If not defined, current site.
|
||||||
|
* @return {boolean} If related WS is available on the site.
|
||||||
|
* @since 3.7
|
||||||
|
*/
|
||||||
|
isSelfConversationEnabled(site?: CoreSite): boolean {
|
||||||
|
site = site || this.sitesProvider.getCurrentSite();
|
||||||
|
|
||||||
|
return site.wsAvailable('core_message_get_self_conversation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not self conversation is supported in a certain site.
|
||||||
|
*
|
||||||
|
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||||
|
* @return {Promise<boolean>} Promise resolved with boolean: whether related WS is available on a certain site.
|
||||||
|
* @since 3.7
|
||||||
|
*/
|
||||||
|
isSelfConversationEnabledInSite(siteId?: string): Promise<boolean> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
return this.isSelfConversationEnabled(site);
|
||||||
|
}).catch(() => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark message as read.
|
* Mark message as read.
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,7 +49,14 @@ export class AddonMessagesSendMessageUserHandler implements CoreUserProfileHandl
|
||||||
* @return {boolean|Promise<boolean>} Promise resolved with true if enabled, resolved with false otherwise.
|
* @return {boolean|Promise<boolean>} Promise resolved with true if enabled, resolved with false otherwise.
|
||||||
*/
|
*/
|
||||||
isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
|
isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
|
||||||
return user.id != this.sitesProvider.getCurrentSiteUserId();
|
const currentSite = this.sitesProvider.getCurrentSite();
|
||||||
|
|
||||||
|
if (!currentSite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From 3.7 you can send messages to yourself.
|
||||||
|
return user.id != currentSite.getUserId() || currentSite.isVersionGreaterEqualThan('3.7');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -179,6 +179,7 @@
|
||||||
"addon.messages.contacts": "Contacts",
|
"addon.messages.contacts": "Contacts",
|
||||||
"addon.messages.decline": "Decline",
|
"addon.messages.decline": "Decline",
|
||||||
"addon.messages.deleteallconfirm": "Are you sure you would like to delete this entire conversation? This will not delete it for other conversation participants.",
|
"addon.messages.deleteallconfirm": "Are you sure you would like to delete this entire conversation? This will not delete it for other conversation participants.",
|
||||||
|
"addon.messages.deleteallselfconfirm": "Are you sure you would like to delete this entire personal conversation?",
|
||||||
"addon.messages.deleteconversation": "Delete conversation",
|
"addon.messages.deleteconversation": "Delete conversation",
|
||||||
"addon.messages.deletemessage": "Delete message",
|
"addon.messages.deletemessage": "Delete message",
|
||||||
"addon.messages.deletemessageconfirmation": "Are you sure you want to delete this message? It will only be deleted from your messaging history and will still be viewable by the user who sent or received the message.",
|
"addon.messages.deletemessageconfirmation": "Are you sure you want to delete this message? It will only be deleted from your messaging history and will still be viewable by the user who sent or received the message.",
|
||||||
|
@ -217,6 +218,8 @@
|
||||||
"addon.messages.searchnocontactsfound": "No contacts found",
|
"addon.messages.searchnocontactsfound": "No contacts found",
|
||||||
"addon.messages.searchnomessagesfound": "No messages found",
|
"addon.messages.searchnomessagesfound": "No messages found",
|
||||||
"addon.messages.searchnononcontactsfound": "No non contacts found",
|
"addon.messages.searchnononcontactsfound": "No non contacts found",
|
||||||
|
"addon.messages.selfconversation": "Personal space",
|
||||||
|
"addon.messages.selfconversationdefaultmessage": "Save draft messages, links, notes etc. to access later.",
|
||||||
"addon.messages.sendcontactrequest": "Send contact request",
|
"addon.messages.sendcontactrequest": "Send contact request",
|
||||||
"addon.messages.showdeletemessages": "Show delete messages",
|
"addon.messages.showdeletemessages": "Show delete messages",
|
||||||
"addon.messages.type_blocked": "Blocked",
|
"addon.messages.type_blocked": "Blocked",
|
||||||
|
@ -1342,6 +1345,7 @@
|
||||||
"core.favourites": "Starred",
|
"core.favourites": "Starred",
|
||||||
"core.filename": "Filename",
|
"core.filename": "Filename",
|
||||||
"core.filenameexist": "File name already exists: {{$a}}",
|
"core.filenameexist": "File name already exists: {{$a}}",
|
||||||
|
"core.filenotfound": "File not found, sorry.",
|
||||||
"core.fileuploader.addfiletext": "Add file",
|
"core.fileuploader.addfiletext": "Add file",
|
||||||
"core.fileuploader.audio": "Audio",
|
"core.fileuploader.audio": "Audio",
|
||||||
"core.fileuploader.camera": "Camera",
|
"core.fileuploader.camera": "Camera",
|
||||||
|
|
Loading…
Reference in New Issue