Implement basic member mentions, closes #93

This commit is contained in:
Jeremy Zhang 2018-03-19 06:09:58 +00:00
parent 55b3d1a2e3
commit 51d090e84b
3 changed files with 172 additions and 0 deletions

View File

@ -812,6 +812,61 @@ p.mentioned span.chatmessage {
} }
} }
#mention-picker {
color: black;
position: fixed;
bottom: 7%;
right: 5%;
z-index: 500;
width: 90%;
max-width: 90%;
max-height: 120px;
min-height: 40px;
background-color: #eceff1;
border-radius: 5px;
overflow-y: scroll;
display: none;
}
#mention-picker-content {
overflow: auto;
height: 100%;
padding: 5px;
display: block;
}
#mention-picker .mention-choice {
padding: 5px;
height: 30px;
display: flex;
align-items: center;
justify-content: space-evenly;
cursor: pointer;
}
#mention-picker .mention-choice.selected {
background-color: rgba(0, 0, 0, 0.07);
}
#mention-picker img {
width: 25px;
height: 25px;
}
#mention-picker .displayname {
margin-left: 10px;
}
#mention-picker .realname {
margin-left: auto;
}
@media only screen and (max-device-width: 320px) {
#mention-picker .realname {
display: none;
}
}
#usercard .avatar { #usercard .avatar {
width: 100%; width: 100%;
max-width: 120px; max-width: 120px;

View File

@ -1447,6 +1447,72 @@
} }
}); });
$("#chatcontent").bind("click", function () {
$("#mention-picker").hide();
});
$('#messagebox').bind('input keydown click', function(event) {
if (event.type == "keydown" && (event.which == 38 || event.which == 40 || event.which == 13) && $("#mention-picker").is(":visible")) {
return;
}
var cursorAt = $(this).caret();
var input = $(this).val().substr(0, cursorAt);
var lastWord = input.match(/@\w+$/);
if (lastWord == null) {
$("#mention-picker").hide();
return;
}
lastWord = lastWord[0];
if (lastWord.charAt(0) != "@") {
$("#mention-picker").hide();
return;
}
lastWord = lastWord.substr(1);
var template = $('#mustache_usermentionchoices').html();
Mustache.parse(template);
var users = [];
for (var i = 0; i < discord_users_list.length; i++) {
var usr = discord_users_list[i];
if (usr.username.toLowerCase().indexOf(lastWord.toLowerCase()) > -1 || (usr.nick && usr.nick.toLowerCase().indexOf(lastWord.toLowerCase()) > -1)) {
var displayname = usr.username;
if (usr.nick) {
displayname = usr.nick;
}
users.push({
id: usr.id,
avatar: usr.avatar_url,
username: usr.username,
discriminator: usr.discriminator,
displayname: displayname
});
}
}
if (users.length == 0) {
$("#mention-picker").hide();
return;
}
$("#mention-picker").show();
$("#mention-picker-content").html("");
for (var i = 0; i < users.length; i++) {
var usr = users[i];
var rendered = $(Mustache.render(template, usr));
rendered.hover(function () {
$("#mention-picker .mention-choice.selected").removeClass("selected");
$(this).addClass("selected");
});
rendered.click(function () {
var usrid = $(this).attr("discorduserid");
var val = $("#messagebox").val().replace("@" + lastWord, "[@" + usrid + "] ");
$("#messagebox").val(val);
$("#mention-picker").hide();
$("#messagebox").focus();
});
$("#mention-picker-content").append(rendered);
}
$("#mention-picker .mention-choice.selected").removeClass("selected");
$("#mention-picker .mention-choice").first().addClass("selected");
});
$("#messagebox").keyup(function (event) { $("#messagebox").keyup(function (event) {
if (event.keyCode == 16) { if (event.keyCode == 16) {
shift_pressed = false; shift_pressed = false;
@ -1454,6 +1520,40 @@
}); });
$("#messagebox").keydown(function(event){ $("#messagebox").keydown(function(event){
if ($("#mention-picker").is(":visible")) {
if ((event.which == 38 || event.which == 40)) {
event.preventDefault();
var choices = $("#mention-picker .mention-choice");
var selected = $("#mention-picker .mention-choice.selected");
var index = choices.index(selected);
selected.removeClass("selected");
if (event.which == 40) {
if (index == choices.length - 1) {
$(choices.get(0)).addClass("selected");
} else {
$(choices.get(index + 1)).addClass("selected");
}
} else {
if (index == 0) {
$(choices.get(choices.length - 1)).addClass("selected");
} else {
$(choices.get(index - 1)).addClass("selected");
}
}
$("#mention-picker .mention-choice.selected")[0].scrollIntoView();
return;
}
if (event.which == 13) {
event.preventDefault();
$("#mention-picker .mention-choice.selected").click();
return;
}
if (event.which == 27) {
$("#mention-picker").hide();
}
}
if ($(this).val().length == 1) { if ($(this).val().length == 1) {
$(this).val($.trim($(this).val())); $(this).val($.trim($(this).val()));
} }

View File

@ -286,6 +286,12 @@
</div> </div>
</div> </div>
<div id="mention-picker">
<div id="mention-picker-content">
</div>
</div>
<footer id="footer" class="footer"> <footer id="footer" class="footer">
<div id="footercontainer" class="footercontainer"> <div id="footercontainer" class="footercontainer">
<div class="currentuserchip" id="nameplate"> <div class="currentuserchip" id="nameplate">
@ -319,6 +325,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/twemoji/2.5.0/2/twemoji.min.js" integrity="sha256-t5bxASdQ5tDbKQZy330h/YufCiZg82xG8PqIYzFpwhU=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twemoji/2.5.0/2/twemoji.min.js" integrity="sha256-t5bxASdQ5tDbKQZy330h/YufCiZg82xG8PqIYzFpwhU=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/soundmanager2/2.97a.20150601/script/soundmanager2-nodebug-jsmin.js" integrity="sha256-5KBL+8gS3BkWOs22YOrezN3Djl4pwodgZaPQY9hgu4Y=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/soundmanager2/2.97a.20150601/script/soundmanager2-nodebug-jsmin.js" integrity="sha256-5KBL+8gS3BkWOs22YOrezN3Djl4pwodgZaPQY9hgu4Y=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.3/es6-shim.min.js" integrity="sha256-THlgZSjqt7idNSdnUvGypTuXB5C4hV9kSuPYrbiq19o=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.3/es6-shim.min.js" integrity="sha256-THlgZSjqt7idNSdnUvGypTuXB5C4hV9kSuPYrbiq19o=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/caret/1.0.0/jquery.caret.min.js" integrity="sha256-NfP6KWI/oETcPbLcLXVAamn8K2wJrYH8ZIRrOf1XNUE=" crossorigin="anonymous"></script>
<script src="{{ url_for("static", filename="js/vendor/highlight.pack.js") }}"></script> <script src="{{ url_for("static", filename="js/vendor/highlight.pack.js") }}"></script>
<script src="{{ url_for("static", filename="js/vendor/jquery.balloon.min.js") }}"></script> <script src="{{ url_for("static", filename="js/vendor/jquery.balloon.min.js") }}"></script>
@ -440,6 +447,16 @@
<script id="mustache_rolebubble" type="text/template"> <script id="mustache_rolebubble" type="text/template">
<span class="bubble" {{#color}}style="color: {{color}};"{{/color}}><span class="color" {{#color}}style="background-color: {{color}};"{{/color}}></span> <span class="text">{{name}}</span></span> <span class="bubble" {{#color}}style="color: {{color}};"{{/color}}><span class="color" {{#color}}style="background-color: {{color}};"{{/color}}></span> <span class="text">{{name}}</span></span>
</script> </script>
<script id="mustache_usermentionchoices" type="text/template">
<div class="mention-choice" discorduserid="{{ id }}">
<img src="{{ avatar }}" class="circle">
<span class="displayname">{{ displayname }}</span>
<span class="realname">
<span class="username">{{ username }}</span><span class="hash">#</span><span class="discriminator">{{ discriminator }}</span>
</span>
</div>
</script>
{% endraw %} {% endraw %}
<script> <script>