-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emoji autocomplete π β‘ #1038
Conversation
this.emoji_dict = undefined; | ||
this.emoji_start_pos = -1; | ||
|
||
$.get('/image/emoji.tsv', (text) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can suggest a better way to load emojis, not by downloading the file like that?
I was thinking of creating JS file with one multiline constant and just including it in app.htm
, but I'm not sure if that is any better.
This happens once per page load anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If going with this solution we should use fetch
instead of $.get
..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I didn't even know about this π
padding: 4px 8px; | ||
|
||
&.selected { | ||
background: #2391d3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to use user's color theme here, but I can't find a LESS variable that would give me the color. Did I miss it?
Saw z.entity.User.accent_color()
, but definitely do not want to do this via JS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
background-color: @w-blue;
It's "hidden" a bit deeper: https://github.com/wireapp/wire-theme/blob/master/app/style/wire-theme.less#L29
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool π but is there a way which will give me currently selected color, not always blue?
I stumbled upon some mixin .accent-background-color()
, but I can't get it to work π
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right.. some magic will be needed with the themes here then! But it's a bit too late to figure out what exactly :)
.map((emoji) => { | ||
let [code, name] = emoji.split('\t'); | ||
let parsed_unicode_emoji = String.fromCodePoint.apply(null, code.split(',')); | ||
return `<div><span>${parsed_unicode_emoji}</span>${name}</div>`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the project uses knockout.js and this whole creation of emoji list could have been done nicer. However I am quite hesitant to do such refactoring now, as this will add complexity to the whole feature.
This code is tested by many Surfingkeys users, we only need to test how well it integrates with Wire. Refactoring will be more risky, all of us would have to invest more time to get it right.
Considering this, do you think we can live with such code for emojis v1?
this.emoji_list.find(`>div:nth(${new_selection})`).addClass('selected'); | ||
} | ||
|
||
get_cursor_pixel_pos(input) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is some dark magic... π
but it works well, the emoji list is always positioned correctly from what I've tested so far.
on_input_key_up(data, event) { | ||
if (!this.suppress_key_up) { | ||
let input = event.target; | ||
let text = input.value || ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
Just awesome! π |
|
||
&.selected { | ||
background: #2391d3; | ||
color: white; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#fff
position: fixed; | ||
display: block; | ||
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.2); | ||
background: white; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
background-color: #fff
@@ -167,3 +167,27 @@ | |||
.conversation-input-paste-cancel { | |||
margin-right: 32px; | |||
} | |||
|
|||
.conversation-input-emoji-list { | |||
z-index: 2147483000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @z-index-level-7
case z.util.KEYCODE.ENTER: { | ||
let input = event.target; | ||
let emoji = this.emoji_list.find('>div.selected>span').html(); | ||
let val = input.value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
} | ||
|
||
static get MIN_QUERY_LENGTH() { | ||
return 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magic numbers... not sure what would be the best approach.. maybe something like this (from SO):
const EMOJI_LIST_LENGTH = 5;
const MIN_QUERY_LENGTH = 2;
...
static get EMOJI_LIST_LENGTH() {
return EMOJI_LIST_LENGTH;
}
(even though smells like shadowing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, I actually considered this static get
to be the place where we define constants π It does feel like an overkill to define a constant, that will be used to return from a constant π
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My dream is to include this rule pretty soon: http://eslint.org/docs/rules/no-magic-numbers and while it feels like overkill I'm sure it will throw a warning.. any other ideas?
(obviously excluding 0s
and 1s
I guess from the rule)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I enabled it locally, and yes, it does throw a warning - will fix it then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we don't need to create static get
ters, I created these constants not for exposing them outside of the module, but simply to make it clear what these numbers mean. I'll just leave the const
definitions, and remove the rest.
z-index: @z-index-level-7; | ||
position: fixed; | ||
display: block; | ||
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even though the designers will have the final say here.. at least style wise we use this format:rgba(0,0,0,.2)
Not clickable - yes, but should be changeable with arrows up and down. Up / down to change, Enter to select, Esc to cancel. Hmm.. |
Heh, arrows break after clicking π nice catch. Hm, need to think how to handle this properly, as the keydown/keyup listener is registered only on the input box, and when you click elsewhere, the input is not the one who will receive keyup/keydown anymore... |
And magically fix if you press |
Also you forgot to /cc our Wire Ambassador of Emojis: @herrmannplatz π¬π© |
I think a lot of people would find it natural to click on a emoji in the list, so I added this functionality... it looks a bit hacky, but works π |
@@ -127,9 +127,10 @@ z.ViewModel.ConversationInputEmojiViewModel = class ConversationInputEmojiViewMo | |||
this.emoji_list.find('.emoji:nth(0)').addClass('selected'); | |||
|
|||
const pos = this.get_cursor_pixel_pos(input); | |||
const top = pos.top - this.emoji_list.height(); | |||
const top = pos.top - this.emoji_list.height() - 10; | |||
const left = pos.left - 20; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
magic :)
OFFSET_TOP/LEFT
(or something like that)
So I found an interesting edge case, when emoij list is open, user can click elsewhere and the emoji list should hide itself. It didn't happen before, I extended the code so that the list is removed when edit is cancelled... but this doesn't cover all cases. For example, enter |
Thanks for the quick response!
|
Got it, thanks, makes sense to be consistent. π I'm looking at the sorting now, and I'm struggling a bit with how to make this better. The simple alphabetic sorting will make query like
The current code uses the order of emojis as they appear in Maybe you have some other ideas how to handle this nicely? |
const QUERY_MIN_LENGTH = 2; | ||
|
||
const EMOJI_LIST_OFFSET_TOP = 10; | ||
const EMOJI_LIST_OFFSET_LEFT = 20; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sort them all by name.. no need to group them.
I tend to keep sorting as it is, based on the "popularity" defined by the ordering in the file. Subjectively I believe the "sunglasses" emoji is used more often than "sunny", that's why it comes first in the list. When you see a specific emoji that should be above in the list, perhaps we could just bring it up in the file. The cool engineering solution would be to keep a per-user statistics on what emojis this particular user is typing, and use this to further order the list. That way the fans of "Sunny" emoji would have it first in the list for Let me know if you agree. I keep the list of unsolved questions in the first message here, besides the emoji ordering there's a bug with "Settings" button that I'm not sure yet how to solve, and apart from that I hope we are pretty close π |
I personally like this approach to sorting. Makes sense. Good stuff.. and no.. we are not going to personalize the usage of emojis :D |
I've just had another look, and I think I might have figured out a way to fix the last issue, to hide emoji list on Settings / Collection buttons click. The trick I used is to subscribe to the I believe there are no unresolved issues anymore π |
5f726ac
to
0566487
Compare
Nice catch with variable width, @makingthematrix! Fixed all the suggestions. Since we don't have the arrow anymore, which offset do you think is the most pleasant to the eye? π |
@maximbaz Offset 8px ;) |
Boom!! Thanks again @maximbaz π» πΊ |
Hi @maximbaz, the whole @wireapp team is thankful beyond words. Your pull request is a great addition to our app. It builds the foundation for emoji input support, one of the most requested features. Based on your contribution we can add an emoji picker and further input improvements... Thanks for that! Your friends at Wire. π |
Thank you guys for the support, reviews and suggestions, I'm glad we made it in the product π |
As agreed in #541, I've migrated the code from Surfingkeys to add Emoji autocomplete. I also stripped out some code which is unnecessary for Wire.
I've made it to function properly, and although I'm planning to test more, I think now it's a good time to ask you guys to start giving some feedback on it. Give it a try π
General notes:
/app/image
folder, but strictly speaking it is not an image. Any suggestions on where to better place it? My only need is to be able to download this file from javascript, so it must be accessible as a static resource.Unresolved questions:
I'll be posting some more notes and questions inline.
/cc @bennyn, @gregor