MOBILE-2860 message: Allow conversations to be muted

main
Dani Palou 2019-04-04 16:02:40 +02:00
parent c6e01bfa66
commit 791d9b4afa
8 changed files with 131 additions and 1 deletions

View File

@ -197,6 +197,7 @@
"addon.messages.messagenotsent": "local_moodlemobileapp", "addon.messages.messagenotsent": "local_moodlemobileapp",
"addon.messages.messagepreferences": "message", "addon.messages.messagepreferences": "message",
"addon.messages.messages": "message", "addon.messages.messages": "message",
"addon.messages.muteconversation": "message",
"addon.messages.newmessage": "message", "addon.messages.newmessage": "message",
"addon.messages.newmessages": "local_moodlemobileapp", "addon.messages.newmessages": "local_moodlemobileapp",
"addon.messages.nocontactrequests": "message", "addon.messages.nocontactrequests": "message",
@ -230,6 +231,7 @@
"addon.messages.unabletomessage": "message", "addon.messages.unabletomessage": "message",
"addon.messages.unblockuser": "message", "addon.messages.unblockuser": "message",
"addon.messages.unblockuserconfirm": "message", "addon.messages.unblockuserconfirm": "message",
"addon.messages.unmuteconversation": "message",
"addon.messages.useentertosend": "message", "addon.messages.useentertosend": "message",
"addon.messages.useentertosenddescdesktop": "local_moodlemobileapp", "addon.messages.useentertosenddescdesktop": "local_moodlemobileapp",
"addon.messages.useentertosenddescmac": "local_moodlemobileapp", "addon.messages.useentertosenddescmac": "local_moodlemobileapp",

View File

@ -36,6 +36,7 @@
"messagenotsent": "The message was not sent. Please try again later.", "messagenotsent": "The message was not sent. Please try again later.",
"messagepreferences": "Message preferences", "messagepreferences": "Message preferences",
"messages": "Messages", "messages": "Messages",
"muteconversation": "Mute",
"newmessage": "New message", "newmessage": "New message",
"newmessages": "New messages", "newmessages": "New messages",
"nocontactrequests": "No contact requests", "nocontactrequests": "No contact requests",
@ -69,6 +70,7 @@
"unabletomessage": "You are unable to message this user", "unabletomessage": "You are unable to message this user",
"unblockuser": "Unblock user", "unblockuser": "Unblock user",
"unblockuserconfirm": "Are you sure you want to unblock {{$a}}?", "unblockuserconfirm": "Are you sure you want to unblock {{$a}}?",
"unmuteconversation": "Unmute",
"useentertosend": "Use enter to send", "useentertosend": "Use enter to send",
"useentertosenddescdesktop": "If disabled, you can use Ctrl+Enter to send the message.", "useentertosenddescdesktop": "If disabled, you can use Ctrl+Enter to send the message.",
"useentertosenddescmac": "If disabled, you can use Cmd+Enter to send the message.", "useentertosenddescmac": "If disabled, you can use Cmd+Enter to send the message.",

View File

@ -5,6 +5,7 @@
<ion-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" core-user-avatar [user]="otherMember" [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus" item-start (click)="showInfo && viewInfo()"></ion-avatar> <ion-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" core-user-avatar [user]="otherMember" [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus" item-start (click)="showInfo && viewInfo()"></ion-avatar>
<core-format-text [text]="title" (click)="showInfo && !isGroup && viewInfo()"></core-format-text> <core-format-text [text]="title" (click)="showInfo && !isGroup && viewInfo()"></core-format-text>
<core-icon *ngIf="conversation && conversation.isfavourite" name="fa-star"></core-icon> <core-icon *ngIf="conversation && conversation.isfavourite" name="fa-star"></core-icon>
<core-icon *ngIf="conversation && conversation.ismuted" name="volume-off"></core-icon>
</ion-title> </ion-title>
<ion-buttons end></ion-buttons> <ion-buttons end></ion-buttons>
</ion-navbar> </ion-navbar>
@ -15,6 +16,7 @@
<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]="isSelf || !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]="isSelf || !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]="!muteEnabled || !conversation" [priority]="600" [content]="(conversation && conversation.ismuted ? 'addon.messages.unmuteconversation' : 'addon.messages.muteconversation') | translate" (action)="changeMute($event)" [closeOnClick]="false" [iconAction]="muteIcon"></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]="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]="isSelf || !otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" [priority]="100" [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" [iconAction]="addRemoveIcon"></core-context-menu-item>

View File

@ -88,6 +88,8 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
requestContactSent = false; requestContactSent = false;
requestContactReceived = false; requestContactReceived = false;
isSelf = false; isSelf = false;
muteEnabled = false;
muteIcon = 'volume-off';
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,
@ -99,6 +101,7 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
this.siteId = sitesProvider.getCurrentSiteId(); this.siteId = sitesProvider.getCurrentSiteId();
this.currentUserId = sitesProvider.getCurrentSiteUserId(); this.currentUserId = sitesProvider.getCurrentSiteUserId();
this.groupMessagingEnabled = this.messagesProvider.isGroupMessagingEnabled(); this.groupMessagingEnabled = this.messagesProvider.isGroupMessagingEnabled();
this.muteEnabled = this.messagesProvider.isMuteConversationEnabled();
this.logger = logger.getInstance('AddonMessagesDiscussionPage'); this.logger = logger.getInstance('AddonMessagesDiscussionPage');
@ -443,6 +446,7 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
this.conversationImage = conversation.imageurl; this.conversationImage = conversation.imageurl;
this.isGroup = conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP; this.isGroup = conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP;
this.favouriteIcon = conversation.isfavourite ? 'fa-star-o' : 'fa-star'; this.favouriteIcon = conversation.isfavourite ? 'fa-star-o' : 'fa-star';
this.muteIcon = conversation.ismuted ? 'volume-up' : 'volume-off';
if (!this.isGroup) { if (!this.isGroup) {
this.userId = conversation.userid; this.userId = conversation.userid;
} }
@ -1107,6 +1111,33 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
}); });
} }
/**
* Change the mute state of the current conversation.
*
* @param {Function} [done] Function to call when done.
*/
changeMute(done?: () => void): void {
this.muteIcon = 'spinner';
this.messagesProvider.muteConversation(this.conversation.id, !this.conversation.ismuted).then(() => {
this.conversation.ismuted = !this.conversation.ismuted;
// Get the conversation data so it's cached. Don't block the user for this.
this.messagesProvider.getConversation(this.conversation.id, undefined, true);
this.eventsProvider.trigger(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, {
conversationId: this.conversation.id,
action: 'mute',
value: this.conversation.ismuted
}, this.siteId);
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'Error changing muted state.');
}).finally(() => {
this.muteIcon = this.conversation.ismuted ? 'volume-up' : 'volume-off';
done && done();
});
}
/** /**
* Calculate whether there are pending contact requests. * Calculate whether there are pending contact requests.
*/ */

View File

@ -101,6 +101,7 @@
<h2> <h2>
<core-format-text [text]="conversation.name"></core-format-text> <core-format-text [text]="conversation.name"></core-format-text>
<core-icon name="fa-ban" *ngIf="conversation.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> <core-icon name="fa-ban" *ngIf="conversation.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon>
<core-icon *ngIf="conversation.ismuted" name="volume-off"></core-icon>
</h2> </h2>
<ion-note *ngIf="conversation.lastmessagedate > 0 || conversation.unreadcount"> <ion-note *ngIf="conversation.lastmessagedate > 0 || conversation.unreadcount">
<ion-badge *ngIf="conversation.unreadcount > 0">{{ conversation.unreadcount }}</ion-badge> <ion-badge *ngIf="conversation.unreadcount > 0">{{ conversation.unreadcount }}</ion-badge>

View File

@ -166,8 +166,23 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
}); });
// Update conversations if we receive an event to do so. // Update conversations if we receive an event to do so.
this.updateConversationListObserver = eventsProvider.on(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, () => { this.updateConversationListObserver = eventsProvider.on(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, (data) => {
if (data && data.action == 'mute') {
// If the conversation is displayed, change its muted value.
const expandedOption = this.getExpandedOption();
if (expandedOption && expandedOption.conversations) {
const conversation = this.findConversation(data.conversationId, undefined, expandedOption);
if (conversation) {
conversation.ismuted = data.value;
}
}
return;
}
this.refreshData(); this.refreshData();
}, this.siteId); }, this.siteId);
// If a message push notification is received, refresh the view. // If a message push notification is received, refresh the view.

View File

@ -1938,6 +1938,34 @@ export class AddonMessagesProvider {
}); });
} }
/**
* Returns whether or not a site supports muting or unmuting a conversation.
*
* @param {CoreSite} [site] The site to check, undefined for current site.
* @return {boolean} If related WS is available on current site.
* @since 3.7
*/
isMuteConversationEnabled(site?: CoreSite): boolean {
site = site || this.sitesProvider.getCurrentSite();
return site.wsAvailable('core_message_mute_conversations');
}
/**
* Returns whether or not a site supports muting or unmuting a conversation.
*
* @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
*/
isMuteConversationEnabledInSite(siteId?: string): Promise<boolean> {
return this.sitesProvider.getSite(siteId).then((site) => {
return this.isMuteConversationEnabled(site);
}).catch(() => {
return false;
});
}
/** /**
* Returns whether or not the plugin is enabled in a certain site. * Returns whether or not the plugin is enabled in a certain site.
* *
@ -2043,6 +2071,53 @@ export class AddonMessagesProvider {
return this.sitesProvider.getCurrentSite().write('core_message_mark_all_messages_as_read', params, preSets); return this.sitesProvider.getCurrentSite().write('core_message_mark_all_messages_as_read', params, preSets);
} }
/**
* Mute or unmute a conversation.
*
* @param {number} conversationId Conversation ID.
* @param {boolean} set Whether to mute or unmute.
* @param {string} [siteId] Site ID. If not defined, use current site.
* @param {number} [userId] User ID. If not defined, current user in the site.
* @return {Promise<any>} Resolved when done.
*/
muteConversation(conversationId: number, set: boolean, siteId?: string, userId?: number): Promise<any> {
return this.muteConversations([conversationId], set, siteId, userId);
}
/**
* Mute or unmute some conversations.
*
* @param {number[]} conversations Conversation IDs.
* @param {boolean} set Whether to mute or unmute.
* @param {string} [siteId] Site ID. If not defined, use current site.
* @param {number} [userId] User ID. If not defined, current user in the site.
* @return {Promise<any>} Resolved when done.
*/
muteConversations(conversations: number[], set: boolean, siteId?: string, userId?: number): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
userId = userId || site.getUserId();
const params = {
userid: userId,
conversationids: conversations
},
wsName = set ? 'core_message_mute_conversations' : 'core_message_unmute_conversations';
return site.write(wsName, params).then(() => {
// Invalidate the conversations data.
const promises = [];
conversations.forEach((conversationId) => {
promises.push(this.invalidateConversation(conversationId, site.getId(), userId));
});
return Promise.all(promises).catch(() => {
// Ignore errors.
});
});
});
}
/** /**
* Refresh the number of contact requests sent to the current user. * Refresh the number of contact requests sent to the current user.
* *

View File

@ -197,6 +197,7 @@
"addon.messages.messagenotsent": "The message was not sent. Please try again later.", "addon.messages.messagenotsent": "The message was not sent. Please try again later.",
"addon.messages.messagepreferences": "Message preferences", "addon.messages.messagepreferences": "Message preferences",
"addon.messages.messages": "Messages", "addon.messages.messages": "Messages",
"addon.messages.muteconversation": "Mute",
"addon.messages.newmessage": "New message", "addon.messages.newmessage": "New message",
"addon.messages.newmessages": "New messages", "addon.messages.newmessages": "New messages",
"addon.messages.nocontactrequests": "No contact requests", "addon.messages.nocontactrequests": "No contact requests",
@ -230,6 +231,7 @@
"addon.messages.unabletomessage": "You are unable to message this user", "addon.messages.unabletomessage": "You are unable to message this user",
"addon.messages.unblockuser": "Unblock user", "addon.messages.unblockuser": "Unblock user",
"addon.messages.unblockuserconfirm": "Are you sure you want to unblock {{$a}}?", "addon.messages.unblockuserconfirm": "Are you sure you want to unblock {{$a}}?",
"addon.messages.unmuteconversation": "Unmute",
"addon.messages.useentertosend": "Use enter to send", "addon.messages.useentertosend": "Use enter to send",
"addon.messages.useentertosenddescdesktop": "If disabled, you can use Ctrl+Enter to send the message.", "addon.messages.useentertosenddescdesktop": "If disabled, you can use Ctrl+Enter to send the message.",
"addon.messages.useentertosenddescmac": "If disabled, you can use Cmd+Enter to send the message.", "addon.messages.useentertosenddescmac": "If disabled, you can use Cmd+Enter to send the message.",