mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-22 18:15:47 +02:00
Add a compact skin tone selector to emoji keyboard
This commit is contained in:
parent
1f27d96ac9
commit
73d460d40a
Resources/Plugins/emoji-keyboard
@ -1,14 +1,40 @@
|
||||
enabled(){
|
||||
this.emojiHTML = "";
|
||||
enabled(){
|
||||
this.selectedSkinTone = "";
|
||||
|
||||
this.skinToneList = [
|
||||
"", "1F3FB", "1F3FC", "1F3FD", "1F3FE", "1F3FF"
|
||||
];
|
||||
|
||||
this.skinToneNonDefaultList = [
|
||||
"1F3FB", "1F3FC", "1F3FD", "1F3FE", "1F3FF"
|
||||
];
|
||||
|
||||
this.skinToneData = [
|
||||
[ "", "#FFDD67" ],
|
||||
[ "1F3FB", "#FFE1BD" ],
|
||||
[ "1F3FC", "#FED0AC" ],
|
||||
[ "1F3FD", "#D6A57C" ],
|
||||
[ "1F3FE", "#B47D56" ],
|
||||
[ "1F3FF", "#8A6859" ],
|
||||
];
|
||||
|
||||
this.emojiHTML1 = ""; // no skin tones, prepended
|
||||
this.emojiHTML2 = {}; // contains emojis with skin tones
|
||||
this.emojiHTML3 = ""; // no skin tones, appended
|
||||
|
||||
var me = this;
|
||||
|
||||
// styles
|
||||
|
||||
this.css = window.TDPF_createCustomStyle(this);
|
||||
this.css.insert(".emoji-keyboard { position: absolute; width: 15.35em; height: 11.2em; background-color: white; overflow-y: auto; padding: 0.1em; box-sizing: border-box; border-radius: 2px; font-size: 24px; z-index: 9999 }");
|
||||
this.css.insert(".emoji-keyboard .separator { height: 26px; }");
|
||||
this.css.insert(".emoji-keyboard .emoji { padding: 0.1em !important; cursor: pointer }");
|
||||
this.css.insert(".emoji-keyboard { position: absolute; width: 15.35em; background-color: white; border-radius: 2px 2px 3px 3px; font-size: 24px; z-index: 9999 }");
|
||||
this.css.insert(".emoji-keyboard-list { height: 10.14em; padding: 0.1em; box-sizing: border-box; overflow-y: auto }");
|
||||
this.css.insert(".emoji-keyboard-list .separator { height: 26px }");
|
||||
this.css.insert(".emoji-keyboard-list .emoji { padding: 0.1em !important; cursor: pointer }");
|
||||
this.css.insert(".emoji-keyboard-skintones { height: 1.3em; text-align: center; background-color: #292f33; border-radius: 0 0 2px 2px }");
|
||||
this.css.insert(".emoji-keyboard-skintones div { width: 0.8em; height: 0.8em; margin: 0.25em 0.1em; border-radius: 50%; display: inline-block; box-sizing: border-box; cursor: pointer }");
|
||||
this.css.insert(".emoji-keyboard-skintones .sel { border: 2px solid rgba(0, 0, 0, 0.35); box-shadow: 0 0 2px 0 rgba(255, 255, 255, 0.65), 0 0 1px 0 rgba(255, 255, 255, 0.4) inset }");
|
||||
this.css.insert(".emoji-keyboard-skintones :hover { border: 2px solid rgba(0, 0, 0, 0.25); box-shadow: 0 0 1px 0 rgba(255, 255, 255, 0.65), 0 0 1px 0 rgba(255, 255, 255, 0.25) inset }");
|
||||
|
||||
// layout
|
||||
|
||||
@ -34,16 +60,29 @@ enabled(){
|
||||
$(".emoji-keyboard-popup-btn").removeClass("is-selected");
|
||||
};
|
||||
|
||||
this.generateKeyboardFor = (input, left, top) => {
|
||||
var created = document.createElement("div");
|
||||
document.body.appendChild(created);
|
||||
var generateEmojiHTML = skinTone => {
|
||||
return this.emojiHTML1+this.emojiHTML2[skinTone]+this.emojiHTML3;
|
||||
};
|
||||
|
||||
var selectSkinTone = skinTone => {
|
||||
let selectedEle = this.currentKeyboard.children[1].querySelector("[data-tone='"+this.selectedSkinTone+"']");
|
||||
selectedEle && selectedEle.classList.remove("sel");
|
||||
|
||||
created.classList.add("emoji-keyboard");
|
||||
created.style.left = left+"px";
|
||||
created.style.top = top+"px";
|
||||
created.innerHTML = this.emojiHTML;
|
||||
this.selectedSkinTone = skinTone;
|
||||
this.currentKeyboard.children[0].innerHTML = generateEmojiHTML(skinTone);
|
||||
this.currentKeyboard.children[1].querySelector("[data-tone='"+this.selectedSkinTone+"']").classList.add("sel");
|
||||
};
|
||||
|
||||
this.generateKeyboard = (input, left, top) => {
|
||||
var outer = document.createElement("div");
|
||||
outer.classList.add("emoji-keyboard");
|
||||
outer.style.left = left+"px";
|
||||
outer.style.top = top+"px";
|
||||
|
||||
created.addEventListener("click", function(e){
|
||||
var keyboard = document.createElement("div");
|
||||
keyboard.classList.add("emoji-keyboard-list");
|
||||
|
||||
keyboard.addEventListener("click", function(e){
|
||||
if (e.target.tagName === "IMG"){
|
||||
input.val(input.val()+e.target.getAttribute("alt"));
|
||||
input.trigger("change");
|
||||
@ -53,7 +92,24 @@ enabled(){
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
return created;
|
||||
var skintones = document.createElement("div");
|
||||
skintones.innerHTML = me.skinToneData.map(entry => "<div data-tone='"+entry[0]+"' style='background-color:"+entry[1]+"'></div>").join("");
|
||||
skintones.classList.add("emoji-keyboard-skintones");
|
||||
|
||||
skintones.addEventListener("click", function(e){
|
||||
if (e.target.hasAttribute("data-tone")){
|
||||
selectSkinTone(e.target.getAttribute("data-tone") || "");
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
outer.appendChild(keyboard);
|
||||
outer.appendChild(skintones);
|
||||
document.body.appendChild(outer);
|
||||
|
||||
this.currentKeyboard = outer;
|
||||
selectSkinTone(this.selectedSkinTone);
|
||||
};
|
||||
|
||||
this.prevTryPasteImage = window.TDGF_tryPasteImage;
|
||||
@ -75,7 +131,7 @@ enabled(){
|
||||
}
|
||||
else{
|
||||
var pos = $(this).offset();
|
||||
me.currentKeyboard = me.generateKeyboardFor($(".js-compose-text").first(), pos.left, pos.top+$(this).outerHeight()+8);
|
||||
me.generateKeyboard($(".js-compose-text").first(), pos.left, pos.top+$(this).outerHeight()+8);
|
||||
|
||||
$(this).addClass("is-selected");
|
||||
}
|
||||
@ -123,38 +179,93 @@ ready(){
|
||||
};
|
||||
|
||||
$TDP.readFileRoot(this.$token, "emoji-ordering.txt").then(contents => {
|
||||
let generated = [];
|
||||
let generated1 = [];
|
||||
let generated2 = {};
|
||||
let generated3 = [];
|
||||
|
||||
let addDeclaration = decl => {
|
||||
generated.push(decl.split(" ").map(pt => convUnicode(parseInt(pt, 16))).join(""));
|
||||
for(let skinTone of this.skinToneList){
|
||||
generated2[skinTone] = [];
|
||||
}
|
||||
|
||||
// declaration inserters
|
||||
|
||||
let addDeclaration1 = decl => {
|
||||
generated1.push(decl.split(" ").map(pt => convUnicode(parseInt(pt, 16))).join(""));
|
||||
};
|
||||
|
||||
let skinTones = [
|
||||
"1F3FB", "1F3FC", "1F3FD", "1F3FE", "1F3FF"
|
||||
];
|
||||
let addDeclaration2 = (tone, decl) => {
|
||||
let gen = decl.split(" ").map(pt => convUnicode(parseInt(pt, 16))).join("");
|
||||
|
||||
if (tone === null){
|
||||
for(let skinTone of this.skinToneList){
|
||||
generated2[skinTone].push(gen);
|
||||
}
|
||||
}
|
||||
else{
|
||||
generated2[tone].push(gen);
|
||||
}
|
||||
};
|
||||
|
||||
let addDeclaration3 = decl => {
|
||||
generated3.push(decl.split(" ").map(pt => convUnicode(parseInt(pt, 16))).join(""));
|
||||
};
|
||||
|
||||
// line reading
|
||||
|
||||
let skinToneState = 0;
|
||||
|
||||
for(let line of contents.split("\n")){
|
||||
if (line[0] === '@'){
|
||||
generated.push("___");
|
||||
switch(skinToneState){
|
||||
case 0: generated1.push("___"); break;
|
||||
case 1: this.skinToneList.forEach(skinTone => generated2[skinTone].push("___")); break;
|
||||
case 2: generated3.push("___"); break;
|
||||
}
|
||||
|
||||
if (line[1] === '1'){
|
||||
skinToneState = 1;
|
||||
}
|
||||
else if (line[1] === '2'){
|
||||
skinToneState = 2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
let decl = line.slice(0, line.indexOf(";"));
|
||||
else if (skinToneState === 1){
|
||||
let decl = line.slice(0, line.indexOf(';'));
|
||||
let skinIndex = decl.indexOf('$');
|
||||
|
||||
if (skinIndex !== -1){
|
||||
let declPre = decl.slice(0, skinIndex);
|
||||
let declPost = decl.slice(skinIndex+1);
|
||||
|
||||
skinTones.map(skinTone => declPre+skinTone+declPost).forEach(addDeclaration);
|
||||
|
||||
for(let skinTone of this.skinToneNonDefaultList){
|
||||
generated2[skinTone].pop();
|
||||
addDeclaration2(skinTone, declPre+skinTone+declPost);
|
||||
}
|
||||
}
|
||||
else{
|
||||
addDeclaration(decl);
|
||||
addDeclaration2(null, decl);
|
||||
}
|
||||
}
|
||||
else if (skinToneState === 2){
|
||||
addDeclaration3(line.slice(0, line.indexOf(';')));
|
||||
}
|
||||
else if (skinToneState === 0){
|
||||
addDeclaration1(line.slice(0, line.indexOf(';')));
|
||||
}
|
||||
}
|
||||
|
||||
// final processing
|
||||
|
||||
let replaceSeparators = str => str.replace(/___/g, "<div class='separator'></div>");
|
||||
|
||||
let start = "<p style='font-size:13px;color:#444;margin:4px;text-align:center'>Please, note that most emoji will not show up properly in the text box above, but they will display in the tweet.</p>";
|
||||
this.emojiHTML = start+TD.util.cleanWithEmoji(generated.join("")).replace(/___/g, "<div class='separator'></div>");
|
||||
this.emojiHTML1 = start+replaceSeparators(TD.util.cleanWithEmoji(generated1.join("")));
|
||||
|
||||
for(let skinTone of this.skinToneList){
|
||||
this.emojiHTML2[skinTone] = replaceSeparators(TD.util.cleanWithEmoji(generated2[skinTone].join("")));
|
||||
}
|
||||
|
||||
this.emojiHTML3 = replaceSeparators(TD.util.cleanWithEmoji(generated3.join("")));
|
||||
}).catch(err => {
|
||||
$TD.alert("error", "Problem loading emoji keyboard: "+err.message);
|
||||
});
|
||||
|
@ -96,7 +96,7 @@
|
||||
1F648; 🙈 see-no-evil monkey
|
||||
1F649; 🙉 hear-no-evil monkey
|
||||
1F64A; 🙊 speak-no-evil monkey
|
||||
@
|
||||
@1 enable skin tones
|
||||
1F466; 👦 boy
|
||||
1F466 $; 👦🏻 boy
|
||||
1F467; 👧 girl
|
||||
@ -402,6 +402,10 @@
|
||||
1F939 $ 200D 2642 FE0F; 🤹🏻♂️ man juggling
|
||||
1F939 200D 2640 FE0F; 🤹♀️ woman juggling
|
||||
1F939 $ 200D 2640 FE0F; 🤹🏻♀️ woman juggling
|
||||
1F6CC; 🛌 person in bed !! moved
|
||||
1F6CC $; 🛌🏻 person in beh !! moved
|
||||
1F6C0; 🛀 person taking bath !! moved
|
||||
1F6C0 $; 🛀🏻 person taking bath !! moved
|
||||
1F46B; 👫 man and woman holding hands
|
||||
1F46C; 👬 two men holding hands
|
||||
1F46D; 👭 two women holding hands
|
||||
@ -439,7 +443,7 @@
|
||||
1F469 200D 1F467; 👩👧 family
|
||||
1F469 200D 1F467 200D 1F466; 👩👧👦 family
|
||||
1F469 200D 1F467 200D 1F467; 👩👧👧 family
|
||||
@ !! removed skin tone modifiers
|
||||
@
|
||||
1F4AA; 💪 flexed biceps
|
||||
1F4AA $; 💪🏻 flexed biceps
|
||||
1F933; 🤳 selfie
|
||||
@ -505,7 +509,6 @@
|
||||
1F443; 👃 nose
|
||||
1F443 $; 👃🏻 nose
|
||||
1F91D; 🤝 handshake !! moved
|
||||
@
|
||||
1F463; 👣 footprints
|
||||
1F440; 👀 eyes
|
||||
1F441; 👁 eye
|
||||
@ -570,7 +573,7 @@
|
||||
1F484; 💄 lipstick
|
||||
1F48D; 💍 ring
|
||||
1F48E; 💎 gem stone
|
||||
@
|
||||
@2 no more skin tones beyond this point
|
||||
1F435; 🐵 monkey face
|
||||
1F412; 🐒 monkey
|
||||
1F98D; 🦍 gorilla
|
||||
@ -895,14 +898,10 @@
|
||||
1F6F0; 🛰 satellite
|
||||
1F6CE; 🛎 bellhop bell
|
||||
1F6AA; 🚪 door
|
||||
1F6CC; 🛌 person in bed
|
||||
1F6CC $; 🛌🏻 person in bed
|
||||
1F6CF; 🛏 bed
|
||||
1F6CB; 🛋 couch and lamp
|
||||
1F6BD; 🚽 toilet
|
||||
1F6BF; 🚿 shower
|
||||
1F6C0; 🛀 person taking bath
|
||||
1F6C0 $; 🛀🏻 person taking bath
|
||||
1F6C1; 🛁 bathtub
|
||||
@
|
||||
231B; ⌛ hourglass
|
||||
|
Loading…
Reference in New Issue
Block a user