Merge pull request #9 from xPaw/contextmenu

Add context menus
This commit is contained in:
Max-P 2016-03-06 00:27:24 -05:00
commit 94bcb21faa
15 changed files with 164 additions and 14 deletions

View File

@ -421,6 +421,14 @@ button,
right: 3px; right: 3px;
} }
#sidebar,
#footer {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#footer { #footer {
background: rgba(0, 0, 0, .06); background: rgba(0, 0, 0, .06);
border-radius: 2px; border-radius: 2px;
@ -1188,6 +1196,62 @@ button,
width: 58px; width: 58px;
} }
#context-menu-container {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
background: transparent;
}
#context-menu {
position: absolute;
list-style: none;
margin: 0;
padding: 0;
min-width: 160px;
font-size: 14px;
background-color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, .1);
border: 1px solid rgba(61, 70, 77, .1);
}
.context-menu-item:first-child {
border-bottom: 1px solid rgba(61, 70, 77, .1);
}
.context-menu-item {
cursor: pointer;
display: block;
padding: 6px 8px;
color: #333;
}
.context-menu-item:hover {
background-color: #f6f6f6;
}
.context-menu-item:before {
font-family: FontAwesome;
width: 20px;
display: inline-block;
}
.context-menu-user:before {
content: "\f007";
}
.context-menu-chan:before {
content: "\f0f6";
}
.context-menu-close:before {
content: "\f057";
}
/** /**
* Tooltips * Tooltips
* See http://primercss.io/tooltips/ * See http://primercss.io/tooltips/

View File

@ -324,6 +324,10 @@
</div> </div>
</div> </div>
<div id="context-menu-container">
<ul id="context-menu"></ul>
</div>
<script src="js/libs.min.js"></script> <script src="js/libs.min.js"></script>
<script src="js/lounge.templates.js"></script> <script src="js/lounge.templates.js"></script>
<script src="js/lounge.js"></script> <script src="js/lounge.js"></script>

View File

@ -477,6 +477,8 @@ $(function() {
}); });
var viewport = $("#viewport"); var viewport = $("#viewport");
var contextMenuContainer = $("#context-menu-container");
var contextMenu = $("#context-menu");
viewport.on("click", ".lt, .rt", function(e) { viewport.on("click", ".lt, .rt", function(e) {
var self = $(this); var self = $(this);
@ -489,6 +491,63 @@ $(function() {
} }
}); });
function positionContextMenu(e) {
var top, left;
var menuWidth = contextMenu.outerWidth();
var menuHeight = contextMenu.outerHeight();
if ((window.innerWidth - e.pageX) < menuWidth) {
left = window.innerWidth - menuWidth;
} else {
left = e.pageX;
}
if ((window.innerHeight - e.pageY) < menuHeight) {
top = window.innerHeight - menuHeight;
} else {
top = e.pageY;
}
return {left: left, top: top};
}
viewport.on("contextmenu", ".user, .network .chan", function(e) {
var target = $(e.currentTarget);
var output = "";
if (target.hasClass("user")) {
output = render("contextmenu_item", {
class: "user",
text: target.text(),
data: target.data("name")
});
}
else if (target.hasClass("chan")) {
output = render("contextmenu_item", {
class: "chan",
text: target.data("title"),
data: target.data("target")
});
output += render("contextmenu_item", {
class: "close",
text: target.hasClass("lobby") ? "Disconnect" : target.hasClass("query") ? "Close" : "Leave",
data: target.data("target")
});
}
contextMenuContainer.show();
contextMenu
.html(output)
.css(positionContextMenu(e));
return false;
});
contextMenuContainer.on("click contextmenu", function() {
contextMenuContainer.hide();
return false;
});
var input = $("#input") var input = $("#input")
.history() .history()
.tab(complete, {hint: false}); .tab(complete, {hint: false});
@ -637,6 +696,20 @@ $(function() {
return false; return false;
}); });
contextMenu.on("click", ".context-menu-item", function() {
switch ($(this).data("action")) {
case "close":
$(".networks .chan[data-target=" + $(this).data("data") + "] .close").click();
break;
case "chan":
$(".networks .chan[data-target=" + $(this).data("data") + "]").click();
break;
case "user":
$(".channel.active .users .user[data-name=" + $(this).data("data") + "]").click();
break;
}
});
chat.on("input", ".search", function() { chat.on("input", ".search", function() {
var value = $(this).val().toLowerCase(); var value = $(this).val().toLowerCase();
var names = $(this).closest(".users").find(".names"); var names = $(this).closest(".users").find(".names");
@ -852,6 +925,12 @@ $(function() {
} }
}); });
Mousetrap.bind([
"escape"
], function() {
contextMenuContainer.hide();
});
setInterval(function() { setInterval(function() {
chat.find(".chan:not(.active)").each(function() { chat.find(".chan:not(.active)").each(function() {
var chan = $(this); var chan = $(this);

View File

@ -1,2 +1,2 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
{{{parse text}}} {{{parse text}}}

View File

@ -1,9 +1,9 @@
<a href="#" class="user">{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{from}}</a>
invited invited
{{#if invitedYou}} {{#if invitedYou}}
you you
{{else}} {{else}}
<a href="#" class="user">{{target}}</a> <a href="#" class="user" data-name="{{target}}">{{target}}</a>
{{/if}} {{/if}}
to to
{{{parse text}}} {{{parse text}}}

View File

@ -1,3 +1,3 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
<i class="hostmask">({{hostmask}})</i> <i class="hostmask">({{hostmask}})</i>
has joined the channel has joined the channel

View File

@ -1,6 +1,6 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
has kicked has kicked
<a href="#" class="user">{{target}}</a> <a href="#" class="user" data-name="{{target}}">{{target}}</a>
{{#if text}} {{#if text}}
<i class="part-reason">({{{parse text}}})</i> <i class="part-reason">({{{parse text}}})</i>
{{/if}} {{/if}}

View File

@ -1,3 +1,3 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
sets mode sets mode
{{{parse text}}} {{{parse text}}}

View File

@ -1,3 +1,3 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
is now known as is now known as
<a href="#" class="user">{{mode}}{{text}}</a> <a href="#" class="user" data-name="{{text}}">{{mode}}{{text}}</a>

View File

@ -1,4 +1,4 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
<i class="hostmask">({{hostmask}})</i> <i class="hostmask">({{hostmask}})</i>
has left the channel has left the channel
{{#if text}} {{#if text}}

View File

@ -1,4 +1,4 @@
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
<i class="hostmask">({{hostmask}})</i> <i class="hostmask">({{hostmask}})</i>
has quit has quit
{{#if text}} {{#if text}}

View File

@ -1,7 +1,7 @@
{{#if isSetByChan}} {{#if isSetByChan}}
The topic is: The topic is:
{{else}} {{else}}
<a href="#" class="user">{{mode}}{{from}}</a> <a href="#" class="user" data-name="{{from}}">{{mode}}{{from}}</a>
has changed the topic to: has changed the topic to:
{{/if}} {{/if}}

View File

@ -0,0 +1,3 @@
<li class="context-menu-item context-menu-{{class}}" data-action="{{class}}"{{#if data}} data-data="{{data}}"{{/if}}>
{{text}}
</li>

View File

@ -4,7 +4,7 @@
</span> </span>
<span class="from"> <span class="from">
{{#if from}} {{#if from}}
<a href="#" class="user" style="color: #{{stringcolor from}}">{{mode}}{{from}}</a> <a href="#" class="user" style="color: #{{stringcolor from}}" data-name="{{from}}">{{mode}}{{from}}</a>
{{/if}} {{/if}}
</span> </span>
<span class="text"> <span class="text">

View File

@ -13,7 +13,7 @@
{{/unless}} {{/unless}}
<div class="user-mode {{modes mode}}"> <div class="user-mode {{modes mode}}">
{{/diff}} {{/diff}}
<button class="user" style="color: #{{stringcolor name}}">{{mode}}{{name}}</button> <button class="user" style="color: #{{stringcolor name}}" data-name="{{name}}">{{mode}}{{name}}</button>
{{/each}} {{/each}}
</div> </div>
</div> </div>