Skip to content
Snippets Groups Projects
Commit 37120872 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Merge branch 'improve_emoji_picker' into 'master'

Improve emoji picker

This request uses an emoji image sprite to show big set of emojis. The sprite has been made based one gemojione gem images. The categories are retrieved from https://github.com/jonathanwiesel/gemojione/blob/master/config/index.json as well.

Some categories are pretty poor, it can be extended in the future.

It's a first step on the way to improve picker.

The first implementation was using https://github.com/iamcal/emoji-data project, but there was huge incompatibility with gemojione emojis set and I had to drop that solution.

![Screenshot_2015-12-22_23.26.27](/uploads/7d323eb0586204ac92915b41233b97ec/Screenshot_2015-12-22_23.26.27.png)


See merge request !2172
parents e68ae9c6 44d8714f
No related branches found
No related tags found
No related merge requests found
app/assets/images/emoji.png

813 KiB

class @AwardsHandler
constructor: (@post_emoji_url, @noteable_type, @noteable_id, @aliases) ->
$(".add-award").click (event)->
event.stopPropagation()
event.preventDefault()
$(".emoji-menu").show()
$("html").click ->
if !$(event.target).closest(".emoji-menu").length
if $(".emoji-menu").is(":visible")
$(".emoji-menu").hide()
 
addAward: (emoji) ->
emoji = @normilizeEmojiName(emoji)
@postEmoji emoji, =>
@addAwardToEmojiBar(emoji)
$(".emoji-menu").hide()
addAwardToEmojiBar: (emoji, custom_path = '') ->
addAwardToEmojiBar: (emoji) ->
emoji = @normilizeEmojiName(emoji)
if @exist(emoji)
if @isActive(emoji)
Loading
Loading
@@ -17,7 +28,7 @@ class @AwardsHandler
counter.parent().addClass("active")
@addMeToAuthorList(emoji)
else
@createEmoji(emoji, custom_path)
@createEmoji(emoji)
 
exist: (emoji) ->
@findEmojiIcon(emoji).length > 0
Loading
Loading
@@ -54,31 +65,29 @@ class @AwardsHandler
resetTooltip: (award) ->
award.tooltip("destroy")
 
# "destroy" call is asynchronous, this is why we need to set timeout.
# "destroy" call is asynchronous and there is no appropriate callback on it, this is why we need to set timeout.
setTimeout (->
award.tooltip()
), 200
 
createEmoji: (emoji, custom_path) ->
createEmoji: (emoji) ->
emojiCssClass = @resolveNameToCssClass(emoji)
nodes = []
nodes.push("<div class='award active' title='me'>")
nodes.push("<div class='icon' data-emoji='" + emoji + "'>")
nodes.push(@getImage(emoji, custom_path))
nodes.push("<div class='icon emoji-icon " + emojiCssClass + "' data-emoji='" + emoji + "'></div>")
nodes.push("<div class='counter'>1</div>")
nodes.push("</div>")
nodes.push("<div class='counter'>1")
nodes.push("</div></div>")
 
$(".awards-controls").before(nodes.join("\n"))
emoji_node = $(nodes.join("\n")).insertBefore(".awards-controls").find(".emoji-icon").data("emoji", emoji)
 
$(".award").tooltip()
 
getImage: (emoji, custom_path) ->
if custom_path
$("<img>").attr({src: custom_path, width: 20, height: 20}).wrap("<div>").parent().html()
else
$("li[data-emoji='" + emoji + "']").html()
resolveNameToCssClass: (emoji) ->
unicodeName = $(".emoji-menu-content [data-emoji='?']".replace("?", emoji)).data("unicode-name")
 
"emoji-" + unicodeName
 
postEmoji: (emoji, callback) ->
$.post @post_emoji_url, { note: {
Loading
Loading
@@ -90,7 +99,7 @@ class @AwardsHandler
callback.call()
 
findEmojiIcon: (emoji) ->
$(".icon[data-emoji='" + emoji + "']")
$(".award [data-emoji='" + emoji + "']")
 
scrollToAwards: ->
$('body, html').animate({
Loading
Loading
Loading
Loading
@@ -127,7 +127,7 @@ class @Notes
@initTaskList()
 
if note.award
awards_handler.addAwardToEmojiBar(note.note, note.emoji_path)
awards_handler.addAwardToEmojiBar(note.note)
awards_handler.scrollToAwards()
 
###
Loading
Loading
Loading
Loading
@@ -2,6 +2,12 @@
@include clearfix;
line-height: 34px;
 
.emoji-icon {
width: 20px;
height: 20px;
margin: 7px 0 0 5px;
}
.award {
@include border-radius(5px);
 
Loading
Loading
@@ -40,6 +46,7 @@
}
 
.awards-controls {
position: relative;
margin-left: 10px;
float: left;
 
Loading
Loading
@@ -55,32 +62,60 @@
}
}
 
.awards-menu {
padding: $gl-padding;
min-width: 214px;
> li {
cursor: pointer;
width: 30px;
height: 30px;
text-align: center;
@include border-radius(5px);
.emoji-menu{
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175);
box-shadow: 0 6px 12px rgba(0,0,0,.175);
.emoji-menu-content {
padding: $gl-padding;
width: 300px;
height: 300px;
overflow-y: scroll;
h5 {
clear: left;
}
 
img {
margin-bottom: 2px;
ul {
list-style-type: none;
margin-left: -20px;
margin-bottom: 20px;
overflow: auto;
}
 
&:hover {
background-color: #ccc;
li {
cursor: pointer;
width: 30px;
height: 30px;
text-align: center;
float: left;
margin: 3px;
list-decorate: none;
@include border-radius(5px);
&:hover {
background-color: #ccc;
}
}
}
}
}
.awards-menu{
li {
float: left;
margin: 3px;
}
}
}
This diff is collapsed.
Loading
Loading
@@ -139,7 +139,6 @@ class Projects::NotesController < Projects::ApplicationController
discussion_id: note.discussion_id,
html: note_to_html(note),
award: note.is_award,
emoji_path: note.is_award ? view_context.image_url(::AwardEmoji.path_to_emoji_image(note.note)) : "",
note: note.note,
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
Loading
Loading
Loading
Loading
@@ -94,11 +94,13 @@ module IssuesHelper
end.sort.to_sentence(last_word_connector: ', or ')
end
 
def url_to_emoji(name)
emoji_path = ::AwardEmoji.path_to_emoji_image(name)
url_to_image(emoji_path)
rescue StandardError
""
def emoji_icon(name, unicode = nil)
unicode ||= Emoji.emoji_filename(name)
content_tag :div, "",
class: "icon emoji-icon emoji-#{unicode}",
"data-emoji" => name,
"data-unicode-name" => unicode
end
 
def emoji_author_list(notes, current_user)
Loading
Loading
@@ -109,10 +111,6 @@ module IssuesHelper
list.join(", ")
end
 
def emoji_list
::AwardEmoji::EMOJI_LIST
end
def note_active_class(notes, current_user)
if current_user && notes.pluck(:author_id).include?(current_user.id)
"active"
Loading
Loading
.awards.votes-block
- votable.notes.awards.grouped_awards.each do |emoji, notes|
.award{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user)}
.icon{"data-emoji" => "#{emoji}"}
= image_tag url_to_emoji(emoji), height: "20px", width: "20px"
= emoji_icon(emoji)
.counter
= notes.count
 
- if current_user
.dropdown.awards-controls
.awards-controls
%a.add-award{"data-toggle" => "dropdown", "data-target" => "#", "href" => "#"}
= icon('smile-o')
%ul.dropdown-menu.awards-menu
- emoji_list.each do |emoji|
%li{"data-emoji" => "#{emoji}"}= image_tag url_to_emoji(emoji), height: "20px", width: "20px"
.emoji-menu
.emoji-menu-content
- AwardEmoji.emoji_by_category.each do |category, emojis|
%h5= AwardEmoji::CATEGORIES[category]
%ul
- emojis.each do |emoji|
%li
= emoji_icon(emoji["name"], emoji["unicode"])
 
- if current_user
:coffeescript
Loading
Loading
@@ -20,10 +24,16 @@
noteable_type = "#{votable.class.name.underscore}"
noteable_id = "#{votable.id}"
aliases = #{AwardEmoji::ALIASES.to_json}
window.awards_handler = new AwardsHandler(post_emoji_url, noteable_type, noteable_id, aliases)
 
$(".awards-menu li").click (e)->
emoji = $(this).data("emoji")
window.awards_handler = new AwardsHandler(
post_emoji_url,
noteable_type,
noteable_id,
aliases
)
$(".emoji-menu-content li").click (e)->
emoji = $(this).find(".emoji-icon").data("emoji")
awards_handler.addAward(emoji)
 
$(".awards").on "click", ".award", (e)->
Loading
Loading
@@ -31,3 +41,5 @@
awards_handler.addAward(emoji)
 
$(".award").tooltip()
$(".emoji-menu-content").niceScroll({cursorwidth: "7px", autohidemode: false})
Loading
Loading
@@ -13,6 +13,11 @@ Feature: Award Emoji
Then I have award added
And I can remove it by clicking to icon
 
@javascript
Scenario: I can see the list of emoji categories
Given I click to emoji-picker
Then I can see the activity and food categories
@javascript
Scenario: I add award emoji using regular comment
Given I leave comment with a single emoji
Loading
Loading
Loading
Loading
@@ -15,8 +15,8 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps
end
 
step 'I click to emoji in the picker' do
page.within '.awards-menu' do
page.first('img').click
page.within '.emoji-menu' do
page.first('.emoji-icon').click
end
end
 
Loading
Loading
@@ -27,6 +27,13 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps
end
end
 
step 'I can see the activity and food categories' do
page.within '.emoji-menu' do
expect(page).to_not have_selector 'Activity'
expect(page).to_not have_selector 'Food'
end
end
step 'I have award added' do
page.within '.awards' do
expect(page).to have_selector '.award'
Loading
Loading
class AwardEmoji
EMOJI_LIST = [
"+1", "-1", "100", "blush", "heart", "smile", "rage",
"beers", "disappointed", "ok_hand",
"helicopter", "shit", "airplane", "alarm_clock",
"ambulance", "anguished", "two_hearts", "wink"
]
ALIASES = {
pout: "rage",
satisfied: "laughing",
Loading
Loading
@@ -37,11 +30,41 @@ class AwardEmoji
squirrel: "shipit"
}.with_indifferent_access
 
def self.path_to_emoji_image(name)
"emoji/#{Emoji.emoji_filename(name)}.png"
end
CATEGORIES = {
other: "Other",
objects: "Objects",
places: "Places",
travel_places: "Travel",
emoticons: "Emoticons",
objects_symbols: "Symbols",
nature: "Nature",
celebration: "Celebration",
people: "People",
activity: "Activity",
flags: "Flags",
food_drink: "Food"
}.with_indifferent_access
 
def self.normilize_emoji_name(name)
ALIASES[name] || name
end
def self.emoji_by_category
unless @emoji_by_category
@emoji_by_category = {}
emojis_added = []
Emoji.emojis.each do |emoji_name, data|
next if emojis_added.include?(data["name"])
emojis_added << data["name"]
@emoji_by_category[data["category"]] ||= []
@emoji_by_category[data["category"]] << data
end
@emoji_by_category = @emoji_by_category.sort.to_h
end
@emoji_by_category
end
end
Loading
Loading
@@ -127,18 +127,6 @@ describe IssuesHelper do
it { is_expected.to eq("!1, !2, or !3") }
end
 
describe "#url_to_emoji" do
it "returns url" do
expect(url_to_emoji("smile")).to include("emoji/1F604.png")
end
end
describe "#emoji_list" do
it "returns url" do
expect(emoji_list).to be_kind_of(Array)
end
end
describe "#note_active_class" do
before do
@note = create :note
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment