Skip to content

Commit

Permalink
emoji-picker: add clear history feat for emoticons
Browse files Browse the repository at this point in the history
Presently, emoticon usage history (recently used emoticons) is shown
to the user, but there is no feature to allow the user to clear
this history. The feature to clear emoticon history is now added.

As part of the impolementation, given emoticon is almost the same as
emoji group with few changes, most of the new UIs are again brought
to emoticon group from emoji group. In future, the implementation
can be improved by generalizing and unifying one implementation for
the both use-cases.

Bug: b:216194842
Change-Id: Ia67c6973518311bb2c618a583510f90274864212
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3627424
Reviewed-by: Darren Shen <shend@chromium.org>
Commit-Queue: Mehrab N <mehrab@chromium.org>
Reviewed-by: John Palmer <jopalmer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1001393}
  • Loading branch information
Mehrab N authored and Chromium LUCI CQ committed May 10, 2022
1 parent 4c9acea commit 4495808
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<style>
:host {
--emoji-group-clear-recents-icon-size: 16px;
margin-top: 10px;
position: relative;
}
Expand Down
25 changes: 19 additions & 6 deletions chrome/browser/resources/chromeos/emoji_picker/emoji_group.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import './emoji_button.js';
import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

import {createCustomEvent, EMOJI_CLEAR_RECENTS_CLICK} from './events.js';
import {EmojiVariants} from './types.js';
import {CategoryEnum, EmojiVariants} from './types.js';

class EmojiGroupComponent extends PolymerElement {
static get is() {
Expand All @@ -28,13 +28,11 @@ class EmojiGroupComponent extends PolymerElement {
clearable: {type: Boolean, value: false},
/** @type {boolean} */
showClearRecents: {type: Boolean, value: false},
/** @type {string} */
category: {type: String, value: CategoryEnum.EMOJI},
};
}

constructor() {
super();
}

/** @param emoji {Emoji} */
getTooltipForEmoji(emoji) {
return emoji.name;
Expand All @@ -44,17 +42,32 @@ class EmojiGroupComponent extends PolymerElement {
return this.preferred[emoji] || emoji;
}

/**
* Handles the click event for show-clear button which results
* in showing "clear recently used emojis" button.
*
* @param {Event} ev
*/
onClearClick(ev) {
ev.preventDefault();
ev.stopPropagation();
this.showClearRecents = true;
}

/**
* Handles the event for clicking on the "clear recently used" button.
* It makes "show-clear" button disappear and fires an event
* indicating that the "clear recently used" is clicked.
*
* @fires CustomEvent#`EMOJI_CLEAR_RECENTS_CLICK`
* @param {Event} ev
*/
onClearRecentsClick(ev) {
ev.preventDefault();
ev.stopPropagation();
this.showClearRecents = false;
this.dispatchEvent(createCustomEvent(EMOJI_CLEAR_RECENTS_CLICK, {}));
this.dispatchEvent(createCustomEvent(
EMOJI_CLEAR_RECENTS_CLICK, {category: this.category}));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
--emoji-spacing: 0;
--emoji-per-row: 0;
/* Values set in css only. */
--emoji-group-clear-recents-icon-size: 16px;
--emoji-group-heading-padding-bottom: 10px;
--emoji-group-heading-padding-top: 16px;
--emoji-group-heading-size: 32px;
Expand Down Expand Up @@ -378,7 +379,7 @@
emojiGroupsFullyLoaded,emoticonHistory.emoji.length)]]">
<emoticon-group data="[[emoticonHistory.emoji]]"
group="[[emoticonHistory.group]]" class="group"
data-group="emoticon-history">
data-group="emoticon-history" clearable>
</emoticon-group>
</template>
</div>
Expand Down
34 changes: 29 additions & 5 deletions chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class EmojiPicker extends PolymerElement {
this.addEventListener(
EMOJI_BUTTON_CLICK, (ev) => this.onEmojiButtonClick(ev));
this.addEventListener(
EMOJI_CLEAR_RECENTS_CLICK, ev => this.clearRecentEmoji());
EMOJI_CLEAR_RECENTS_CLICK, ev => this.clearRecentEmoji(ev));
// variant popup related handlers
this.addEventListener(
EMOJI_VARIANTS_SHOWN,
Expand Down Expand Up @@ -377,7 +377,7 @@ export class EmojiPicker extends PolymerElement {
break;

default:
throw new Error('Unknown category');
throw new Error(`Unknown category "${category}."`);
}
}
const searchLength =
Expand All @@ -391,9 +391,24 @@ export class EmojiPicker extends PolymerElement {
this.apiProxy_.insertEmoji(text, isVariant, searchLength);
}

clearRecentEmoji() {
this.set(['emojiHistory', 'emoji'], makeRecentlyUsed([]));
this.recentEmojiStore.clearRecents();
clearRecentEmoji(event) {
switch (event.detail.category) {
case CategoryEnum.EMOJI:
this.set(['emojiHistory', 'emoji'], makeRecentlyUsed([]));
this.recentEmojiStore.clearRecents();
break;

case CategoryEnum.EMOTICON:
this.set(['emoticonHistory', 'emoji'], makeRecentlyUsed([]));
this.recentEmoticonStore.clearRecents();
break;

default:
throw new Error(
'Clear history logic is not implemented ' +
`for category "${this.category}."`);
}

afterNextRender(
this, () => {
this.updateActiveGroup(/*updateTabsScroll=*/ true);
Expand Down Expand Up @@ -675,6 +690,15 @@ export class EmojiPicker extends PolymerElement {
.querySelector('emoji-group')
.showClearRecents = false;
}

if (this.emoticonHistory.emoji.length > 0) {
const emoticonHistoryElement = this.shadowRoot.querySelector(
`div[data-group="emoticon-history"]`).querySelector('emoticon-group');
if (emoticonHistoryElement != null) {
emoticonHistoryElement.showClearRecents = false;
}

}
}

hideEmojiVariants() {
Expand Down
99 changes: 83 additions & 16 deletions chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<style>
:host {
margin-top: 10px;
position: relative;
}

#heading {
Expand All @@ -21,6 +22,13 @@
outline-width: 2px;
}

#heading-left {
height: var(--emoji-group-heading-size);
line-height: var(--emoji-group-heading-size);
user-select: none;
width: 100%;
}

#palette {
display: flex;
flex-wrap: wrap;
Expand All @@ -31,6 +39,54 @@
position: absolute;
}

#show-clear {
--cr-icon-button-fill-color: var(--cros-icon-color-primary);
height: var(--emoji-group-heading-size);
left: var(--emoji-picker-last-emoji-left);
margin: 0;
width: var(--emoji-group-heading-size);
}

#clear-recents {
background-color: var(--cros-bg-color);
border: 2px solid transparent;
border-radius: 4px;
box-shadow: var(--cr-elevation-1);
color: var(--cros-text-color-secondary);
cursor: pointer;
font-family: 'Roboto', sans-serif;
font-size: 12px;
height: var(--emoji-size);
outline: none;
padding: 0;
position: absolute;
right: 0;
top: calc(var(--emoji-group-heading-padding-top)
+ var(--emoji-group-heading-padding-bottom)
+ var(--emoji-group-heading-size));
white-space: nowrap;
width: fit-content;
z-index: 200;
}

#clear-recents:focus,
#clear-recents:active {
border: 2px solid var(--cros-toggle-color);
}

#clear-recents-hover {
border: 2px solid transparent;
margin: -2px;
/* Padding should be 6/10 not 7/11, but without adding 1 there is
* a weird border.*/
padding: 7px 11px 7px 11px;
}

#clear-recents-hover:hover {
background-color: var(--cros-button-background-color-secondary-hover);
border: 2px solid var(--cros-button-background-color-secondary-hover);
}

.emoticon-button {
background: var(--emoji-background);
border: none;
Expand Down Expand Up @@ -79,23 +135,34 @@
</style>

<template is="dom-if" if="[[group]]">
<div id="heading" role="heading">
[[group]]
<div id="heading" role="heading" aria-level="2" tabindex="-1">
<div id="heading-left">[[group]]</div>
<template is="dom-if" if="[[clearable]]">
<cr-icon-button id="show-clear" iron-icon="emoji_picker:more_horizontal"
on-click="onClearClick">
</cr-icon-button>
</template>
</div>
</template>
<template is = "dom-if" if="[[showClearRecents]]">
<button id="clear-recents" on-click="onClearRecentsClick">
<div id="clear-recents-hover">
Clear recently used emoticons
</div>
</button>
</template>
<!-- TODO(b/216194842): Implement emoticon group clear logic. -->
<div id="palette">
<div id="fake-focus-target" tabindex="-1"></div>
<template is="dom-repeat" items="[[data]]" as="emoticon">
<button class="emoticon-button" id="[[generateEmoticonId(index)]]"
emoticon-name$="[[emoticon.base.name]]"
on-click="onEmoticonClick"
emoticon-string$="[[emoticon.base.string]]">
[[emoticon.base.string]]
</button>
<paper-tooltip class="tooltip" for="[[generateEmoticonId(index)]]"
fit-to-visible-bounds part="tooltip" offset="8">
[[emoticon.base.name]]
</paper-tooltip>
</template>
<div id="fake-focus-target" tabindex="-1"></div>
<template is="dom-repeat" items="[[data]]" as="emoticon">
<button class="emoticon-button" id="[[generateEmoticonId(index)]]"
emoticon-name$="[[emoticon.base.name]]"
on-click="onEmoticonClick"
emoticon-string$="[[emoticon.base.string]]">
[[emoticon.base.string]]
</button>
<paper-tooltip class="tooltip" for="[[generateEmoticonId(index)]]"
fit-to-visible-bounds part="tooltip" offset="8">
[[emoticon.base.name]]
</paper-tooltip>
</template>
</div>
38 changes: 36 additions & 2 deletions chrome/browser/resources/chromeos/emoji_picker/emoticon_group.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js';

import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {createCustomEvent, EMOJI_BUTTON_CLICK} from './events.js';
import {createCustomEvent, EMOJI_BUTTON_CLICK, EMOJI_CLEAR_RECENTS_CLICK} from './events.js';
import {CategoryEnum, EmojiVariants} from './types.js';

class EmoticonGroupComponent extends PolymerElement {
Expand All @@ -21,6 +21,12 @@ class EmoticonGroupComponent extends PolymerElement {
return {
/** @type {!Array<EmojiVariants>}*/
data: {type: Array, readonly: true},
/** @type {boolean} */
clearable: {type: Boolean, value: false},
/** @type {boolean} */
showClearRecents: {type: Boolean, value: false},
/** @type {string} */
category: {type: String, value: CategoryEnum.EMOTICON},
};
}

Expand All @@ -33,7 +39,7 @@ class EmoticonGroupComponent extends PolymerElement {
baseEmoji: emoticonString,
allVariants: [],
name: emoticonName,
category: CategoryEnum.EMOTICON
category: this.category,
}));
}

Expand All @@ -45,6 +51,34 @@ class EmoticonGroupComponent extends PolymerElement {
generateEmoticonId(index) {
return `emoticon-${index}`;
}

/**
* Handles the click event for show-clear button which results
* in showing "clear recently used" emoticons button.
*
* @param {Event} ev
*/
onClearClick(ev) {
ev.preventDefault();
ev.stopPropagation();
this.showClearRecents = true;
}

/**
* Handles the event for clicking on the "clear recently used" button.
* It makes "show-clear" button disappear and fires an event
* indicating that the "clear recently used" is clicked.
*
* @fires CustomEvent#`EMOJI_CLEAR_RECENTS_CLICK`
* @param {Event} ev
*/
onClearRecentsClick(ev) {
ev.preventDefault();
ev.stopPropagation();
this.showClearRecents = false;
this.dispatchEvent(createCustomEvent(
EMOJI_CLEAR_RECENTS_CLICK, {category: this.category}));
}
}

customElements.define(EmoticonGroupComponent.is, EmoticonGroupComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ suite('emoji-picker-extension', () => {
for (let idx = 0; idx < allEmoticonGroups.length; ++idx) {
const group = allEmoticonGroups[idx];
const actualFirstGroupName =
group.shadowRoot.querySelector('#heading').innerHTML.trim();
group.shadowRoot.querySelector('#heading-left').innerHTML.trim();
const expectedFirstGroupName = emojiPicker.emoticonData[idx].group;
assertEquals(expectedFirstGroupName, actualFirstGroupName);

Expand Down

0 comments on commit 4495808

Please sign in to comment.