Make GIFs clearable
Add a context menu for <emoji-image /> (under history group), so users can remove GIFs individually. Bug: b:282083514 Change-Id: I7d0411c091a3a812839b8430ced5093ad3a3d860 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4533818 Reviewed-by: Zac Partridge <zacpartridge@google.com> Commit-Queue: Grey Wang <greywang@google.com> Cr-Commit-Position: refs/heads/main@{#1144564}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
f4538fa9bf
commit
6bb21a64ac
chrome/browser/resources/chromeos/emoji_picker
@ -248,7 +248,8 @@
|
||||
<emoji-image index="[[getIndex(item)]]"
|
||||
item="[[item]]"
|
||||
show-tooltip="[[showTooltip]]"
|
||||
emoji-click="[[onEmojiClick]]">
|
||||
emoji-click="[[onEmojiClick]]"
|
||||
clearable="[[clearable]]">
|
||||
</emoji-image>
|
||||
</template>
|
||||
</div>
|
||||
@ -257,7 +258,8 @@
|
||||
<emoji-image index="[[getIndex(item)]]"
|
||||
item="[[item]]"
|
||||
show-tooltip="[[showTooltip]]"
|
||||
emoji-click="[[onEmojiClick]]">
|
||||
emoji-click="[[onEmojiClick]]"
|
||||
clearable="[[clearable]]">
|
||||
</emoji-image>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -1,4 +1,8 @@
|
||||
<style>
|
||||
.emoji-image-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emoji-image {
|
||||
background-color: var(--cros-button-stroke-color-secondary-disabled);
|
||||
border: none;
|
||||
@ -39,15 +43,53 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-image-clear {
|
||||
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: 7px 11px 7px 11px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
white-space: nowrap;
|
||||
width: fit-content;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.emoji-image-clear:focus,
|
||||
.emoji-image-clear:active {
|
||||
border: 2px solid var(--cros-toggle-color);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<img data-index$="[[index]]"
|
||||
class$="[[getImageClassName(loading)]]"
|
||||
is="cr-auto-img"
|
||||
auto-src="[[getUrl()]]"
|
||||
alt$="[[item.base.name]]"
|
||||
load="lazy"
|
||||
on-mouseenter="handleMouseEnter"
|
||||
on-focus="handleFocus"
|
||||
on-click="handleClick"
|
||||
on-load="handleLoad">
|
||||
<div class="emoji-image-container"
|
||||
on-contextmenu="handleContextMenu"
|
||||
on-mouseleave="handleMouseLeave"
|
||||
style$="[[getStyles(item)]]">
|
||||
<img data-index$="[[index]]"
|
||||
class$="[[getImageClassName(loading)]]"
|
||||
is="cr-auto-img"
|
||||
auto-src="[[getUrl(item)]]"
|
||||
alt$="[[item.base.name]]"
|
||||
load="lazy"
|
||||
on-mouseenter="handleMouseEnter"
|
||||
on-focus="handleFocus"
|
||||
on-click="handleClick"
|
||||
on-load="handleLoad">
|
||||
|
||||
<template is="dom-if" if="[[showClearButton]]">
|
||||
<button class="emoji-image-clear" on-click="handleClear">
|
||||
Remove from recently used GIFs
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
@ -6,7 +6,8 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bu
|
||||
|
||||
import {VISUAL_CONTENT_WIDTH} from './constants.js';
|
||||
import {getTemplate} from './emoji_image.html.js';
|
||||
import {EmojiVariants} from './types.js';
|
||||
import { createCustomEvent, EMOJI_CLEAR_RECENTS_CLICK } from './events.js';
|
||||
import {CategoryEnum, EmojiVariants} from './types.js';
|
||||
|
||||
export class EmojiImageComponent extends PolymerElement {
|
||||
static get is() {
|
||||
@ -23,6 +24,9 @@ export class EmojiImageComponent extends PolymerElement {
|
||||
item: Object,
|
||||
showTooltip: Object,
|
||||
emojiClick: Object,
|
||||
|
||||
clearable: {type: Boolean, value: false},
|
||||
showClearButton: {type: Boolean, value: false},
|
||||
};
|
||||
}
|
||||
|
||||
@ -33,6 +37,9 @@ export class EmojiImageComponent extends PolymerElement {
|
||||
showTooltip: (e: MouseEvent|FocusEvent) => void;
|
||||
emojiClick: (e: MouseEvent) => void;
|
||||
|
||||
clearable: boolean;
|
||||
showClearButton: boolean;
|
||||
|
||||
private handleMouseEnter(event: MouseEvent): void {
|
||||
this.showTooltip(event);
|
||||
}
|
||||
@ -49,6 +56,32 @@ export class EmojiImageComponent extends PolymerElement {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
private handleContextMenu(evt: Event): void {
|
||||
if (this.clearable) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
this.showClearButton = true;
|
||||
}
|
||||
}
|
||||
|
||||
private handleMouseLeave(): void {
|
||||
if (this.showClearButton) {
|
||||
this.showClearButton = false;
|
||||
}
|
||||
}
|
||||
|
||||
private handleClear(evt: Event): void {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
this.showClearButton = false;
|
||||
this.dispatchEvent(createCustomEvent(
|
||||
EMOJI_CLEAR_RECENTS_CLICK, {
|
||||
category: CategoryEnum.GIF,
|
||||
item: this.item,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
private getImageClassName(loading: boolean) {
|
||||
return loading ? 'emoji-image loading' : 'emoji-image';
|
||||
}
|
||||
@ -56,12 +89,12 @@ export class EmojiImageComponent extends PolymerElement {
|
||||
/**
|
||||
* Returns visual content preview url.
|
||||
*/
|
||||
private getUrl() {
|
||||
return this.item.base.visualContent?.url.preview.url;
|
||||
private getUrl(item: EmojiVariants) {
|
||||
return item.base.visualContent?.url.preview.url;
|
||||
}
|
||||
|
||||
private setHeight() {
|
||||
const {visualContent} = this.item.base;
|
||||
private getStyles(item: EmojiVariants) {
|
||||
const {visualContent} = item.base;
|
||||
|
||||
if (visualContent === undefined) {
|
||||
return;
|
||||
@ -69,14 +102,8 @@ export class EmojiImageComponent extends PolymerElement {
|
||||
|
||||
const {height, width} = visualContent.previewSize;
|
||||
const visualContentHeight = height / width * VISUAL_CONTENT_WIDTH;
|
||||
this.updateStyles({
|
||||
'--visual-content-height': `${visualContentHeight}px`,
|
||||
});
|
||||
}
|
||||
|
||||
override ready() {
|
||||
super.ready();
|
||||
this.setHeight();
|
||||
return `--visual-content-height: ${visualContentHeight}px`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,7 +600,8 @@ export class EmojiPicker extends PolymerElement {
|
||||
|
||||
private clearRecentEmoji(event: events.EmojiClearRecentClickEvent) {
|
||||
const category = event.detail.category;
|
||||
this.clearHistoryData(category);
|
||||
const item = event.detail.item;
|
||||
this.clearHistoryData(category, item);
|
||||
afterNextRender(this, () => {
|
||||
this.updateActiveGroup();
|
||||
this.updateHistoryTabDisabledProperty();
|
||||
@ -1099,14 +1100,19 @@ export class EmojiPicker extends PolymerElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears history items for a category.
|
||||
* Clears history item(s) for a category.
|
||||
*/
|
||||
private clearHistoryData(category: CategoryEnum) {
|
||||
private clearHistoryData(category: CategoryEnum, item?: EmojiVariants) {
|
||||
if (this.incognito) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.categoriesHistory[category]?.clearRecents();
|
||||
if (item === undefined) {
|
||||
this.categoriesHistory[category]?.clearRecents();
|
||||
} else {
|
||||
this.categoriesHistory[category]?.clearItem(category, item);
|
||||
}
|
||||
|
||||
this.categoryHistoryUpdated(category, true, false);
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,20 @@ export class RecentlyUsedStore {
|
||||
save(this.storeName, this.data);
|
||||
}
|
||||
|
||||
clearItem(category: CategoryEnum, item: EmojiVariants) {
|
||||
if (category === CategoryEnum.GIF) {
|
||||
this.data.history = this.data.history.filter(
|
||||
x =>
|
||||
(x.base.visualContent &&
|
||||
x.base.visualContent.id !== item.base.visualContent?.id));
|
||||
} else {
|
||||
this.data.history = this.data.history.filter(
|
||||
x =>
|
||||
(x.base.string && x.base.string !== item.base.string));
|
||||
}
|
||||
save(this.storeName, this.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the given item to the front of the MRU list, inserting it if
|
||||
* it did not previously exist.
|
||||
|
Reference in New Issue
Block a user