base implementation of emoji picker [ci skip]
This commit is contained in:
parent
2b4a3bc524
commit
2eed8007bf
Binary file not shown.
After Width: | Height: | Size: 813 KiB |
|
@ -1,12 +1,23 @@
|
||||||
class @AwardsHandler
|
class @AwardsHandler
|
||||||
constructor: (@post_emoji_url, @noteable_type, @noteable_id, @aliases) ->
|
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) ->
|
addAward: (emoji) ->
|
||||||
emoji = @normilizeEmojiName(emoji)
|
emoji = @normilizeEmojiName(emoji)
|
||||||
@postEmoji emoji, =>
|
@postEmoji emoji, =>
|
||||||
@addAwardToEmojiBar(emoji)
|
@addAwardToEmojiBar(emoji)
|
||||||
|
|
||||||
addAwardToEmojiBar: (emoji, custom_path = '') ->
|
$(".emoji-menu").hide()
|
||||||
|
|
||||||
|
addAwardToEmojiBar: (emoji) ->
|
||||||
emoji = @normilizeEmojiName(emoji)
|
emoji = @normilizeEmojiName(emoji)
|
||||||
if @exist(emoji)
|
if @exist(emoji)
|
||||||
if @isActive(emoji)
|
if @isActive(emoji)
|
||||||
|
@ -17,7 +28,7 @@ class @AwardsHandler
|
||||||
counter.parent().addClass("active")
|
counter.parent().addClass("active")
|
||||||
@addMeToAuthorList(emoji)
|
@addMeToAuthorList(emoji)
|
||||||
else
|
else
|
||||||
@createEmoji(emoji, custom_path)
|
@createEmoji(emoji)
|
||||||
|
|
||||||
exist: (emoji) ->
|
exist: (emoji) ->
|
||||||
@findEmojiIcon(emoji).length > 0
|
@findEmojiIcon(emoji).length > 0
|
||||||
|
@ -54,31 +65,29 @@ class @AwardsHandler
|
||||||
resetTooltip: (award) ->
|
resetTooltip: (award) ->
|
||||||
award.tooltip("destroy")
|
award.tooltip("destroy")
|
||||||
|
|
||||||
# "destroy" call is asynchronous, this is why we need to set timeout.
|
# "destroy" call is asynchronous and there is no appropriate callnack on it, this is why we need to set timeout.
|
||||||
setTimeout (->
|
setTimeout (->
|
||||||
award.tooltip()
|
award.tooltip()
|
||||||
), 200
|
), 200
|
||||||
|
|
||||||
|
|
||||||
createEmoji: (emoji, custom_path) ->
|
createEmoji: (emoji) ->
|
||||||
|
emojiCssClass = @resolveNameToCssClass(emoji)
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
nodes.push("<div class='award active' title='me'>")
|
nodes.push("<div class='award active' title='me'>")
|
||||||
nodes.push("<div class='icon' data-emoji='" + emoji + "'>")
|
nodes.push("<div class='icon emoji-icon " + emojiCssClass + "' data-emoji='" + emoji + "'></div>")
|
||||||
nodes.push(@getImage(emoji, custom_path))
|
nodes.push("<div class='counter'>1</div>")
|
||||||
nodes.push("</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()
|
$(".award").tooltip()
|
||||||
|
|
||||||
getImage: (emoji, custom_path) ->
|
resolveNameToCssClass: (emoji) ->
|
||||||
if custom_path
|
unicodeName = $(".emoji-menu-content [data-emoji='?']".replace("?", emoji)).data("unicode-name")
|
||||||
$("<img>").attr({src: custom_path, width: 20, height: 20}).wrap("<div>").parent().html()
|
|
||||||
else
|
|
||||||
$("li[data-emoji='" + emoji + "']").html()
|
|
||||||
|
|
||||||
|
"emoji-" + unicodeName
|
||||||
|
|
||||||
postEmoji: (emoji, callback) ->
|
postEmoji: (emoji, callback) ->
|
||||||
$.post @post_emoji_url, { note: {
|
$.post @post_emoji_url, { note: {
|
||||||
|
@ -90,7 +99,7 @@ class @AwardsHandler
|
||||||
callback.call()
|
callback.call()
|
||||||
|
|
||||||
findEmojiIcon: (emoji) ->
|
findEmojiIcon: (emoji) ->
|
||||||
$(".icon[data-emoji='" + emoji + "']")
|
$(".award [data-emoji='" + emoji + "']")
|
||||||
|
|
||||||
scrollToAwards: ->
|
scrollToAwards: ->
|
||||||
$('body, html').animate({
|
$('body, html').animate({
|
||||||
|
|
|
@ -127,7 +127,7 @@ class @Notes
|
||||||
@initTaskList()
|
@initTaskList()
|
||||||
|
|
||||||
if note.award
|
if note.award
|
||||||
awards_handler.addAwardToEmojiBar(note.note, note.emoji_path)
|
awards_handler.addAwardToEmojiBar(note.note)
|
||||||
awards_handler.scrollToAwards()
|
awards_handler.scrollToAwards()
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
@include clearfix;
|
@include clearfix;
|
||||||
line-height: 34px;
|
line-height: 34px;
|
||||||
|
|
||||||
|
.emoji-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 7px 0 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.award {
|
.award {
|
||||||
@include border-radius(5px);
|
@include border-radius(5px);
|
||||||
|
|
||||||
|
@ -40,6 +46,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.awards-controls {
|
.awards-controls {
|
||||||
|
position: relative;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
float: left;
|
float: left;
|
||||||
|
|
||||||
|
@ -55,32 +62,58 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.awards-menu {
|
.emoji-menu{
|
||||||
padding: $gl-padding;
|
position: absolute;
|
||||||
min-width: 214px;
|
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);
|
||||||
|
|
||||||
> li {
|
.emoji-menu-content {
|
||||||
|
padding: $gl-padding;
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-left: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
float: left;
|
||||||
|
margin: 3px;
|
||||||
|
list-decorate: none;
|
||||||
@include border-radius(5px);
|
@include border-radius(5px);
|
||||||
|
|
||||||
img {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.awards-menu{
|
|
||||||
li {
|
|
||||||
float: left;
|
|
||||||
margin: 3px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -138,7 +138,6 @@ class Projects::NotesController < Projects::ApplicationController
|
||||||
discussion_id: note.discussion_id,
|
discussion_id: note.discussion_id,
|
||||||
html: note_to_html(note),
|
html: note_to_html(note),
|
||||||
award: note.is_award,
|
award: note.is_award,
|
||||||
emoji_path: note.is_award ? view_context.image_url(::AwardEmoji.path_to_emoji_image(note.note)) : "",
|
|
||||||
note: note.note,
|
note: note.note,
|
||||||
discussion_html: note_to_discussion_html(note),
|
discussion_html: note_to_discussion_html(note),
|
||||||
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
|
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
|
||||||
|
|
|
@ -94,11 +94,11 @@ module IssuesHelper
|
||||||
end.sort.to_sentence(last_word_connector: ', or ')
|
end.sort.to_sentence(last_word_connector: ', or ')
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_to_emoji(name)
|
def emoji_icon(name, unicode = nil)
|
||||||
emoji_path = ::AwardEmoji.path_to_emoji_image(name)
|
unicode ||= Emoji.emoji_filename(name)
|
||||||
url_to_image(emoji_path)
|
|
||||||
rescue StandardError
|
content_tag :div, "", class: "icon emoji-icon emoji-#{unicode}",
|
||||||
""
|
"data-emoji" => name, "data-unicode-name" => unicode
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_author_list(notes, current_user)
|
def emoji_author_list(notes, current_user)
|
||||||
|
@ -109,10 +109,6 @@ module IssuesHelper
|
||||||
list.join(", ")
|
list.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_list
|
|
||||||
::AwardEmoji::EMOJI_LIST
|
|
||||||
end
|
|
||||||
|
|
||||||
def note_active_class(notes, current_user)
|
def note_active_class(notes, current_user)
|
||||||
if current_user && notes.pluck(:author_id).include?(current_user.id)
|
if current_user && notes.pluck(:author_id).include?(current_user.id)
|
||||||
"active"
|
"active"
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
.awards.votes-block
|
.awards.votes-block
|
||||||
- votable.notes.awards.grouped_awards.each do |emoji, notes|
|
- votable.notes.awards.grouped_awards.each do |emoji, notes|
|
||||||
.award{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user)}
|
.award{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user)}
|
||||||
.icon{"data-emoji" => "#{emoji}"}
|
= emoji_icon(emoji)
|
||||||
= image_tag url_to_emoji(emoji), height: "20px", width: "20px"
|
|
||||||
.counter
|
.counter
|
||||||
= notes.count
|
= notes.count
|
||||||
|
|
||||||
- if current_user
|
- if current_user
|
||||||
.dropdown.awards-controls
|
.awards-controls
|
||||||
%a.add-award{"data-toggle" => "dropdown", "data-target" => "#", "href" => "#"}
|
%a.add-award{"data-toggle" => "dropdown", "data-target" => "#", "href" => "#"}
|
||||||
= icon('smile-o')
|
= icon('smile-o')
|
||||||
%ul.dropdown-menu.awards-menu
|
.emoji-menu
|
||||||
- emoji_list.each do |emoji|
|
.emoji-menu-content
|
||||||
%li{"data-emoji" => "#{emoji}"}= image_tag url_to_emoji(emoji), height: "20px", width: "20px"
|
- AwardEmoji.emoji_by_category.each do |category, emojis|
|
||||||
|
%h4= AwardEmoji::CATEGORIES[category]
|
||||||
|
%ul
|
||||||
|
- emojis.each do |emoji|
|
||||||
|
%li
|
||||||
|
= emoji_icon(emoji["name"], emoji["unicode"])
|
||||||
|
|
||||||
- if current_user
|
- if current_user
|
||||||
:coffeescript
|
:coffeescript
|
||||||
|
@ -20,10 +24,16 @@
|
||||||
noteable_type = "#{votable.class.name.underscore}"
|
noteable_type = "#{votable.class.name.underscore}"
|
||||||
noteable_id = "#{votable.id}"
|
noteable_id = "#{votable.id}"
|
||||||
aliases = #{AwardEmoji::ALIASES.to_json}
|
aliases = #{AwardEmoji::ALIASES.to_json}
|
||||||
window.awards_handler = new AwardsHandler(post_emoji_url, noteable_type, noteable_id, aliases)
|
|
||||||
|
|
||||||
$(".awards-menu li").click (e)->
|
window.awards_handler = new AwardsHandler(
|
||||||
emoji = $(this).data("emoji")
|
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_handler.addAward(emoji)
|
||||||
|
|
||||||
$(".awards").on "click", ".award", (e)->
|
$(".awards").on "click", ".award", (e)->
|
||||||
|
@ -31,3 +41,5 @@
|
||||||
awards_handler.addAward(emoji)
|
awards_handler.addAward(emoji)
|
||||||
|
|
||||||
$(".award").tooltip()
|
$(".award").tooltip()
|
||||||
|
|
||||||
|
$(".emoji-menu-content").niceScroll({cursorwidth: "7px"})
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
class AwardEmoji
|
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 = {
|
ALIASES = {
|
||||||
pout: "rage",
|
pout: "rage",
|
||||||
satisfied: "laughing",
|
satisfied: "laughing",
|
||||||
|
@ -37,11 +30,49 @@ class AwardEmoji
|
||||||
squirrel: "shipit"
|
squirrel: "shipit"
|
||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
|
|
||||||
def self.path_to_emoji_image(name)
|
CATEGORIES = {
|
||||||
"emoji/#{Emoji.emoji_filename(name)}.png"
|
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.positions_by_name(name)
|
||||||
|
emoji = emojis_json.find do |emoji|
|
||||||
|
emoji["short_names"].include?(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
[emoji["sheet_x"], emoji["sheet_y"]]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.normilize_emoji_name(name)
|
def self.normilize_emoji_name(name)
|
||||||
ALIASES[name] || name
|
ALIASES[name] || name
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -127,12 +127,6 @@ describe IssuesHelper do
|
||||||
it { is_expected.to eq("!1, !2, or !3") }
|
it { is_expected.to eq("!1, !2, or !3") }
|
||||||
end
|
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
|
describe "#emoji_list" do
|
||||||
it "returns url" do
|
it "returns url" do
|
||||||
expect(emoji_list).to be_kind_of(Array)
|
expect(emoji_list).to be_kind_of(Array)
|
||||||
|
|
Loading…
Reference in New Issue