Skip to content

Commit

Permalink
Support emojis in flair text (pokemontrades#659)
Browse files Browse the repository at this point in the history
Co-authored-by: Raia <[email protected]>
Co-authored-by: SnowPhoenix <[email protected]>
  • Loading branch information
3 people authored Jan 3, 2021
1 parent 1dec269 commit 75dd3d6
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 110 deletions.
46 changes: 34 additions & 12 deletions api/controllers/FlairController.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,30 @@ module.exports = {
}
var user = await User.findOne(app.user);
var shortened = app.sub === 'pokemontrades' ? 'ptrades' : 'svex';
var relevant_flair = Flairs.makeNewCSSClass(_.get(user, 'flair.' + shortened + '.flair_css_class') || '', app.flair, app.sub);
user.flair[shortened].flair_css_class = relevant_flair;
await Reddit.setUserFlair(req.user.redToken, user.name, relevant_flair, user.flair[shortened].flair_text, app.sub);
var css_flair = Flairs.makeNewCSSClass(_.get(user, 'flair.' + shortened + '.flair_css_class') || '', app.flair, app.sub);
user.flair[shortened].flair_css_class = css_flair;
let current_text = user.flair[shortened].flair_text.replace(/:[a-zA-Z0-9_-]*:/g,'');
let flair_text = Flairs.makeNewFlairText(css_flair, current_text, shortened);

// Check length of flair_text and give a warning message
var warning = '';
if (flair_text.length > 64) {
warning = ' However, the length of your flair was too long, so your flair text was trimmed automatically. Please go to [FHQ](https://hq.porygon.co) to set your flair again.';
flair_text = Flairs.makeNewFlairText(css_flair, current_text.slice(0,55), shortened);
}

// Set the user's flair
await Reddit.setUserFlair(req.user.redToken, user.name, css_flair, flair_text, app.sub);
var promises = [];
promises.push(user.save());
promises.push(Event.create({type: "flairTextChange", user: req.user.name,content: "Changed " + user.name + "'s flair to " + relevant_flair}));
var pmContent = 'Your application for ' + Flairs.formattedName(app.flair) + ' flair on /r/' + app.sub + ' has been approved.';
promises.push(Event.create({type: "flairTextChange", user: req.user.name,content: "Changed " + user.name + "'s flair to " + css_flair}));

// Send a PM to let them know application was accepted.
var pmContent = 'Your application for ' + Flairs.formattedName(app.flair) + ' flair on /r/' + app.sub + ' has been approved.' + warning;
promises.push(Reddit.sendPrivateMessage(refreshToken, 'FlairHQ Notification', pmContent, user.name));
promises.push(Application.destroy({id: req.allParams().id}));
await* promises;
sails.log.info("/u/" + req.user.name + ": Changed " + user.name + "'s flair to " + relevant_flair);
sails.log.info("/u/" + req.user.name + ": Changed " + user.name + "'s flair to " + css_flair);
return res.ok(await Flairs.getApps());
} catch (err) {
return res.serverError(err);
Expand Down Expand Up @@ -118,6 +131,14 @@ module.exports = {
var pFlair = _.get(req, "user.flair.ptrades.flair_css_class") || "default";
var svFlair = _.get(req, "user.flair.svex.flair_css_class") || "";
svFlair = svFlair.replace(/2/, "");

// Build flair text for ptrades and svex from css class
var ptrades_current_text = flairs.ptrades;
var ptrades_flair_text = Flairs.makeNewFlairText(pFlair, ptrades_current_text, 'ptrades');

var svex_current_text = flairs.svex;
var svex_flair_text = Flairs.makeNewFlairText(svFlair, svex_current_text, 'svex');

var promises = [];
var eventFlair = null; // Change to req.allParams().eventFlair during events

Expand All @@ -130,7 +151,7 @@ module.exports = {
req.user.team = _.includes(Flairs.kantoFlair, eventFlair) ? "kanto" : "alola";
pFlair = Flairs.makeNewCSSClass(pFlair, `kva-${eventFlair}-1`, "PokemonTrades");
module.exports.addMembershipPoints(req, res, "add").then(() => {
promises.push(Reddit.setUserFlair(refreshToken, req.user.name, pFlair, flairs.ptrades, "PokemonTrades").catch((err) => {
promises.push(Reddit.setUserFlair(refreshToken, req.user.name, pFlair, ptrades_flair_text, "PokemonTrades").catch((err) => {
sails.log.warn(`Reverting team ${req.user.team} join for ${req.user.name} due to the following error:`);
sails.log.warn(err);
module.exports.addMembershipPoints(req, res, "remove");
Expand All @@ -141,13 +162,13 @@ module.exports = {
return res.status(400).json({error: "Unexpected extra flair."});
}
} else {
promises.push(Reddit.setUserFlair(refreshToken, req.user.name, pFlair, flairs.ptrades, "PokemonTrades"));
promises.push(Reddit.setUserFlair(refreshToken, req.user.name, pFlair, ptrades_flair_text, "PokemonTrades"));
}
promises.push(Reddit.setUserFlair(refreshToken, req.user.name, svFlair, flairs.svex, "SVExchange"));
promises.push(Reddit.setUserFlair(refreshToken, req.user.name, svFlair, svex_flair_text, "SVExchange"));
promises.push(User.update({name: req.user.name}, {loggedFriendCodes: friend_codes}));

if (!blockReport && (users_with_matching_fcs.length !== 0 || matching_ip_usernames.length !== 0 || flagged.length)) {
var message = 'The user /u/' + req.user.name + ' set the following flairs:\n\n' + flairs.ptrades + '\n\n' + flairs.svex + '\n\n';
var message = 'The user /u/' + req.user.name + ' set the following flairs:\n\n' + ptrades_flair_text + '\n\n' + svex_flair_text + '\n\n';
if (users_with_matching_fcs.length !== 0) {
message += 'This flair contains a friend code that matches ' + '/u/' + matching_fc_usernames.join(', /u/') + '\'s friend code: ' + matching_friend_codes + '\n\n';
var altNote = "Alt of " + matching_fc_usernames;
Expand Down Expand Up @@ -189,15 +210,16 @@ module.exports = {
User.native(function(err, collection) {
collection.update({"_id": req.user.name}, {
$set:{
"flair.ptrades.flair_text": flairs.ptrades,
"flair.ptrades.flair_text": ptrades_flair_text,
"flair.ptrades.flair_css_class": pFlair,
"flair.svex.flair_text": flairs.svex,
"flair.svex.flair_text": svex_flair_text,
"flair.svex.flair_css_class": svFlair
}
});
});
return res.ok();
});

} catch (err) {
return res.serverError(err);
}
Expand Down
22 changes: 18 additions & 4 deletions api/services/Ban.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,24 @@ exports.banFromSub = async function (redToken, username, banMessage, banNote, su
exports.giveBannedUserFlair = async function (redToken, username, current_css_class, current_flair_text, subreddit) {
try {
var flair_text = current_flair_text || '';
var css_class = Flairs.makeNewCSSClass(current_css_class, 'banned', subreddit);
await Reddit.setUserFlair(redToken, username, css_class, flair_text, subreddit);
sails.log('Changed ' + username + '\'s flair to ' + css_class + ' on /r/' + subreddit);
return 'Changed ' + username + '\'s flair to ' + css_class + ' on /r/' + subreddit;

// Remove emoji if it exists
var flair_arr = flair_text.split(' ');
if (flair_arr[0] !== null) {
if (flair_arr[0].indexOf(':') !== -1) {
flair_arr.shift();
}
}

// Add BANNED USER to flair text
flair_text = 'BANNED USER ' + flair_arr.join(' ');
if (flair_text.length >= 64) {
flair_text = flair_text.slice(0, 64);
}

await Reddit.setUserFlair(redToken, username, 'banned', flair_text, subreddit);
sails.log('Changed ' + username + '\'s flair to banned on /r/' + subreddit);
return 'Changed ' + username + '\'s flair to banned on /r/' + subreddit;
} catch (err) {
throw {error: 'Failed to give banned user flair'};
}
Expand Down
91 changes: 73 additions & 18 deletions api/services/Flairs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,53 @@ var alolaFlair = ['rowlet', 'litten', 'popplio'];
var eventFlair = kantoFlair.concat(alolaFlair);
var eventFlairRegExp = new RegExp('\\bkva-(' + eventFlair.join("|") + ')-[1-3]\\b');

// Mappings from css_flair to emoji names
const emojiMap = {
"ptrades": {
"default" : ":0:",
"gen2" : ":2:",
"pokeball" : ":10:",
"premierball" : ":20:",
"greatball" : ":30:",
"ultraball" : ":40:",
"luxuryball" : ":50:",
"masterball" : ":60:",
"dreamball" : ":70:",
"cherishball" : ":80:",
"ovalcharm" : ":90:",
"shinycharm" : ":100:",
"pokeball1" : ":10i:",
"premierball1" : ":20i:",
"greatball1" : ":30i:",
"ultraball1" : ":40i:",
"luxuryball1" : ":50i:",
"masterball1" : ":60i:",
"dreamball1" : ":70i:",
"cherishball1" : ":80i:",
"ovalcharm1" : ":90i:",
"shinycharm1" : ":100i:",
"gsball1" : ":GSi:",
"upgrade" : ":u:",
"eventribbon" : ":helper:"
},
"svex": {
"lucky" : ":1:",
"egg" : ":5:",
"eevee" : ":10:",
"togepi" : ":20:",
"torchic" : ":30:",
"pichu" : ":50:",
"manaphy" : ":75:",
"eggcup" : ":100:",
"cuteribbon" : ":1r:",
"coolribbon" : ":2r:",
"beautyribbon" : ":3r:",
"smartribbon" : ":4r:",
"toughribbon" : ":5r:",
"upgrade" : ":u:"
}
};

exports.eventFlair = eventFlair;
exports.kantoFlair = kantoFlair;
exports.eventFlairRegExp = eventFlairRegExp;
Expand Down Expand Up @@ -115,17 +162,6 @@ exports.getUserFlairs = function (user, allflairs) {
return exports.userHasFlair(user, flair);
});
};
exports.getFlairTextForSVEx = function (user) {
if (!user || !user.flair || !user.flair.svex || !user.flair.svex.flair_css_class) {
return;
}
var flairs = user.flair.svex.flair_css_class.split(' '),
flairText = "";
for (var i = 0; i < flairs.length; i++) {
flairText += "flair-" + flairs[i] + " ";
}
return flairText;
};
exports.canUserApply = function (refs, applicationFlair, currentFlairs) {
if (!applicationFlair) {
return false;
Expand Down Expand Up @@ -232,13 +268,17 @@ exports.flairCheck = function (ptrades, svex) {
if (!ptrades || !svex) {
throw "Need both flairs.";
}
if (ptrades.length > 64 || svex.length > 64) {
throw "Flairs too long";

const regex_emoji = /:[a-zA-Z0-9_-]*:/;
if (ptrades.match(regex_emoji) || svex.match(regex_emoji)) {
throw "Flair has emoji.";
}

if (ptrades.length > 55 || svex.length > 56) {
throw "Flairs too long.";
}

const friendCodeGroup = /((?:SW-)?(?:\d{4}-){2}\d{4}(?:, (?:SW-)?(?:\d{4}-){2}\d{4})*)/;
const gameGroup = '^(' + exports.legalIgn + '(?: \\((?:' + exports.gameOptions + ')(?:, (?:' + exports.gameOptions + '))*\\))(?:,(?: ' +
exports.legalIgn + ')?(?: \\((?:' + exports.gameOptions + ')(?:, (?:' + exports.gameOptions + '))*\\))?)*)$';
var tradesParts = ptrades.split(' || ');
var svexParts = svex.split(' || ');
if (tradesParts.length !== 2 || svexParts.length !== 3) {
Expand All @@ -247,8 +287,8 @@ exports.flairCheck = function (ptrades, svex) {
if (!tradesParts[0].match(friendCodeGroup) || !svexParts[0].match(friendCodeGroup)) {
throw "Error with FCs";
}
if (!tradesParts[1].match(RegExp(gameGroup)) || !svexParts[1].match(RegExp(gameGroup))) {
throw "We need at least 1 game.";
if (!tradesParts[1].match(RegExp(exports.legalIgn)) || !svexParts[1].match(RegExp(exports.legalIgn))) {
throw "We need at least one IGN.";
}
if (!/\d{4}(, \d{4})*|XXXX/.test(svexParts[2])) {
throw "Error with TSVs";
Expand All @@ -258,7 +298,7 @@ exports.flairCheck = function (ptrades, svex) {
svex: svex,
games: exports.combineGames(exports.parseGames(tradesParts[1]), exports.parseGames(svexParts[1])),
tsvs: svexParts[2].split(', '),
fcs: _.union(tradesParts[0].split(', '), svexParts[0].split(', '))
fcs: _.union(tradesParts[0].replace(/:[a-zA-Z0-9_-]*:/, "").split(', '), svexParts[0].split(', '))
};
return response;
};
Expand Down Expand Up @@ -293,6 +333,21 @@ exports.makeNewCSSClass = function (previous_flair, new_addition, subreddit) {
return previous_flair.replace(/([^ ]*)(.*)/, '$1 ' + new_addition + '$2');
};

// Create new flair text with emojis
exports.makeNewFlairText = function (css_class, current_text, subreddit) {

// Loop through CSS class and grab the appropriate emoji
const cssClasses = css_class.split(' ');
let emoji = '';
for (let cssClass of cssClasses) {
// If the word is a key in the flair map, then grab the appropriate emoji
if (cssClass in emojiMap[subreddit]) {
emoji += emojiMap[subreddit][cssClass];
}
}
return emoji + current_text;
};

// Get the Damerau–Levenshtein distance (edit distance) between two strings.
exports.edit_distance = function (string1, string2) {
var distance_matrix = {};
Expand Down
4 changes: 3 additions & 1 deletion assets/common/regexCommon.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var ptradesFlair = "((?:SW-)?([0-9]{4}-){2}[0-9]{4})(, ((?:SW-)?([0-9]{4}-){2}[0-9]{4}))* \\|\\| ([^ ,|(]*( \\((X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH)(, (X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH))*\\))?)(, ([^ ,|(]*( \\((X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH)(, (X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH))*\\))?))*";
var ptradesFlair = "(:[a-zA-Z0-9_-]*:)*((?:SW-)?([0-9]{4}-){2}[0-9]{4})(, ((?:SW-)?([0-9]{4}-){2}[0-9]{4}))* \\|\\| ([^ ,|(]*( \\((X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH)(, (X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH))*\\))?)(, ([^ ,|(]*( \\((X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH)(, (X|Y|ΩR|αS|S|M|US|UM|LGP|LGE|SW|SH))*\\))?))*";
var regex = {
emoji: "(:[a-zA-Z0-9_-]*:)",
tsv: "[0-3]\\d{3}|40(?:[0-8]\\d|9[0-5])",
tsvBars: "(\\|\\| [0-9]{4})|(, [0-9]{4})",
fc: "((?:SW-)?([0-9]{4}-){2}[0-9]{4})",
Expand All @@ -19,6 +20,7 @@ var global = function (reg) {
};

module.exports = {
emoji: global(regex.emoji),
tsv: global(regex.tsvBars),
fc: global(regex.fc),
game: global(regex.game),
Expand Down
13 changes: 11 additions & 2 deletions assets/sharedClientFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,17 @@ module.exports = {
$scope.numberOfApprovedEggChecks = function () {
return referenceService.numberOfApprovedEggChecks(_.get($scope, pathToRefs));
};
$scope.getFlairTextForSVEx = function () {
return flairService.getFlairTextForSVEx($scope.refUser);
$scope.renderCSSClass = function(classes) {
if (typeof classes !== 'string') {
return '';
}
return classes.replace(/(\S+)/g, "flair-$1");
};
$scope.renderFlair = function(flair) {
if (typeof flair !== 'string') {
return '';
}
return flair.replace(/:([^:]+):/g,'');
};
$scope.applied = function (flair) {
return flairService.applied(_.get($scope, pathToApps), flair);
Expand Down
10 changes: 3 additions & 7 deletions assets/styles/importer.less
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,13 @@ tr[data-toggle='collapse']{
margin-top: 10px;
}

.flairTop{
margin-top: 10px;
margin-bottom: 0px;
}

.flairBottom{
margin-top:2px;
.flairListing{
margin: 2px 0 0 0;
}

.flairs{
display: inline-block;
padding: 8px 0 10px 0;
}

td h3 {
Expand Down
Loading

0 comments on commit 75dd3d6

Please sign in to comment.