MDL-65896 message: add emoji auto complete to message app

This commit is contained in:
Ryan Wyllie 2019-10-21 10:54:01 +08:00
parent 75962db917
commit 9f536ec696
19 changed files with 148 additions and 12 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -69,6 +69,7 @@ define(
'core_message/message_drawer_view_conversation_state_manager',
'core_message/message_drawer_router',
'core_message/message_drawer_routes',
'core/emoji/auto_complete',
'core/emoji/picker'
],
function(
@ -87,6 +88,7 @@ function(
StateManager,
MessageDrawerRouter,
MessageDrawerRoutes,
initialiseEmojiAutoComplete,
initialiseEmojiPicker
) {
@ -1556,6 +1558,7 @@ function(
var isLoadingMoreMessages = false;
var messagesContainer = getMessagesContainer(body);
var emojiPickerElement = footer.find(SELECTORS.EMOJI_PICKER);
var emojiAutoCompleteContainer = footer.find(SELECTORS.EMOJI_AUTO_COMPLETE_CONTAINER);
var messageTextArea = footer.find(SELECTORS.MESSAGE_TEXT_AREA);
var headerActivateHandlers = [
[SELECTORS.ACTION_REQUEST_BLOCK, generateConfirmActionHandler(requestBlockUser)],
@ -1597,6 +1600,30 @@ function(
AutoRows.init(footer);
initialiseEmojiAutoComplete(
emojiAutoCompleteContainer[0],
messageTextArea[0],
function(hasSuggestions) {
var newState = StateManager.setShowEmojiAutoComplete(viewState, hasSuggestions);
render(newState);
},
function(emoji) {
var newState = StateManager.setShowEmojiAutoComplete(viewState, false);
render(newState);
messageTextArea.focus();
var cursorPos = messageTextArea.prop('selectionStart');
var currentText = messageTextArea.val();
var textBefore = currentText.substring(0, cursorPos).replace(/\S*$/, '');
var textAfter = currentText.substring(cursorPos).replace(/^\S*/, '');
messageTextArea.val(textBefore + emoji + textAfter);
// Set the cursor position to after the inserted emoji.
messageTextArea.prop('selectionStart', textBefore.length + emoji.length);
messageTextArea.prop('selectionEnd', textBefore.length + emoji.length);
}
);
initialiseEmojiPicker(emojiPickerElement[0], function(emoji) {
var newState = StateManager.setShowEmojiPicker(viewState, !viewState.showEmojiPicker);
render(newState);

View File

@ -65,6 +65,7 @@ define([], function() {
DAY_MESSAGES_CONTAINER: '[data-region="day-messages-container"]',
DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE: '[data-region="delete-messages-for-all-users-toggle"]',
DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE_CONTAINER: '[data-region="delete-messages-for-all-users-toggle-container"]',
EMOJI_AUTO_COMPLETE_CONTAINER: '[data-region="emoji-auto-complete-container"]',
EMOJI_PICKER_CONTAINER: '[data-region="emoji-picker-container"]',
EMOJI_PICKER: '[data-region="emoji-picker"]',
EMOJI_PICKER_SEARCH_INPUT: '[data-region="search-input"]',

View File

@ -601,6 +601,23 @@ function(
}
};
/**
* Determine if we should show the emoji auto complete.
*
* @param {Object} state The current state.
* @param {Object} newState The new state.
* @return {Bool|Null}
*/
var buildShowEmojiAutoComplete = function(state, newState) {
if (!state.showEmojiAutoComplete && newState.showEmojiAutoComplete) {
return true;
} else if (state.showEmojiAutoComplete && !newState.showEmojiAutoComplete) {
return false;
} else {
return null;
}
};
/**
* Get the user Object of user to be blocked if pending.
*
@ -1353,7 +1370,8 @@ function(
selectedMessages: buildSelectedMessages,
isFavourite: buildIsFavourite,
isMuted: buildIsMuted,
showEmojiPicker: buildShowEmojiPicker
showEmojiPicker: buildShowEmojiPicker,
showEmojiAutoComplete: buildShowEmojiAutoComplete
}
};
// These build functions are only applicable to private conversations.

View File

@ -430,6 +430,16 @@ function(
return footer.find(SELECTORS.EMOJI_PICKER_CONTAINER);
};
/**
* Get the emoji picker container element.
*
* @param {Object} footer Conversation footer container element.
* @return {Object} The emoji picker container element.
*/
var getEmojiAutoCompleteContainer = function(footer) {
return footer.find(SELECTORS.EMOJI_AUTO_COMPLETE_CONTAINER);
};
/**
* Get a message element.
*
@ -1001,6 +1011,26 @@ function(
}
};
/**
* Hide or show the emoji auto complete.
*
* @param {Object} header The header container element.
* @param {Object} body The body container element.
* @param {Object} footer The footer container element.
* @param {Bool} show Should the emoji picker be visible.
*/
var renderShowEmojiAutoComplete = function(header, body, footer, show) {
var container = getEmojiAutoCompleteContainer(footer);
if (show) {
container.removeClass('hidden');
container.attr('aria-hidden', false);
} else {
container.addClass('hidden');
container.attr('aria-hidden', true);
}
};
/**
* Show a confirmation dialogue
*
@ -1669,7 +1699,8 @@ function(
isMuted: renderIsMuted,
loadingConfirmAction: renderLoadingConfirmAction,
inEditMode: renderInEditMode,
showEmojiPicker: renderShowEmojiPicker
showEmojiPicker: renderShowEmojiPicker,
showEmojiAutoComplete: renderShowEmojiAutoComplete,
},
{
// Scrolling should be last to make sure everything

View File

@ -145,6 +145,7 @@ define(['jquery'], function($) {
pendingSendMessageIds: [],
pendingDeleteConversation: false,
selectedMessageIds: [],
showEmojiAutoComplete: false,
showEmojiPicker: false
};
};
@ -541,6 +542,19 @@ define(['jquery'], function($) {
return newState;
};
/**
* Set whether emojis auto complete suggestions should be shown.
*
* @param {Object} state Current state.
* @param {Bool} show Show the autocomplete
* @return {Object} New state with array of pending delete message ids.
*/
var setShowEmojiAutoComplete = function(state, show) {
var newState = cloneState(state);
newState.showEmojiAutoComplete = show;
return newState;
};
/**
* Set the state pending block userids.
*
@ -845,6 +859,7 @@ define(['jquery'], function($) {
setMessagesSendPendingById: setMessagesSendPendingById,
setMessagesSendSuccessById: setMessagesSendSuccessById,
setMessagesSendFailById: setMessagesSendFailById,
setShowEmojiAutoComplete: setShowEmojiAutoComplete,
setShowEmojiPicker: setShowEmojiPicker,
addPendingBlockUsersById: addPendingBlockUsersById,
addPendingRemoveContactsById: addPendingRemoveContactsById,

View File

@ -35,6 +35,13 @@
}}
<div
class="emoji-auto-complete-container w-100 hidden"
data-region="emoji-auto-complete-container"
aria-live="polite"
aria-hidden="true"
>
</div>
<div class="d-flex mt-1">
<textarea
dir="auto"

View File

@ -679,4 +679,19 @@ $message-day-color: color-yiq($message-app-bg) !default;
right: -1 * map-get($spacers, 2);
}
}
.emoji-auto-complete-container {
overflow: auto;
// Add a 50px buffer to account for scroll bars.
max-height: $picker-row-height + 50px;
transition: max-height .15s ease-in-out;
visibility: visible;
&.hidden {
display: block;
max-height: 0;
visibility: hidden;
transition: max-height .15s ease-in-out, visibility 0s linear .15s;
}
}
}

View File

@ -14901,6 +14901,17 @@ a.ygtvspacer:hover {
.message-app .emoji-picker-container {
right: -0.5rem; } }
.message-app .emoji-auto-complete-container {
overflow: auto;
max-height: 90px;
transition: max-height .15s ease-in-out;
visibility: visible; }
.message-app .emoji-auto-complete-container.hidden {
display: block;
max-height: 0;
visibility: hidden;
transition: max-height .15s ease-in-out, visibility 0s linear .15s; }
/* Question */
.questionbank h2 {
margin-top: 0; }

View File

@ -15163,6 +15163,17 @@ a.ygtvspacer:hover {
.message-app .emoji-picker-container {
right: -0.5rem; } }
.message-app .emoji-auto-complete-container {
overflow: auto;
max-height: 90px;
transition: max-height .15s ease-in-out;
visibility: visible; }
.message-app .emoji-auto-complete-container.hidden {
display: block;
max-height: 0;
visibility: hidden;
transition: max-height .15s ease-in-out, visibility 0s linear .15s; }
/* Question */
.questionbank h2 {
margin-top: 0; }