diff --git a/client/css/style.css b/client/css/style.css index 215d1b24..110dfd28 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -222,6 +222,7 @@ kbd { #viewport .rt::before { content: "\f0c0"; /* http://fontawesome.io/icon/users/ */ } #chat button.menu::before { content: "\f142"; /* http://fontawesome.io/icon/ellipsis-v/ */ } +.context-menu-join::before { content: "\f067"; /* http://fontawesome.io/icon/plus/ */ } .context-menu-user::before { content: "\f007"; /* http://fontawesome.io/icon/user/ */ } .context-menu-close::before { content: "\f00d"; /* http://fontawesome.io/icon/times/ */ } .context-menu-list::before { content: "\f03a"; /* http://fontawesome.io/icon/list/ */ } @@ -457,7 +458,6 @@ kbd { will-change: transform; } -#sidebar button, #sidebar .chan, #sidebar .sign-out, #sidebar .empty { @@ -551,6 +551,7 @@ kbd { } #sidebar .badge, +#sidebar .add-channel, #sidebar .close { float: right; margin-left: 5px; @@ -594,6 +595,32 @@ kbd { color: #fff; } +#sidebar .lobby .add-channel { + border-radius: 3px; + width: 18px; + height: 18px; + transition: opacity 0.2s, background-color 0.2s; +} + +#sidebar .lobby .add-channel::before { + font-size: 20px; + font-weight: normal; + display: inline-block; + line-height: 16px; + text-align: center; + content: "+"; + color: #fff; +} + +#sidebar .lobby .add-channel { + opacity: 0.4; +} + +#sidebar .lobby .add-channel:hover { + background-color: rgba(0, 0, 0, 0.1); + opacity: 1; +} + #sidebar .chan.active .close { opacity: 0.4; display: unset; @@ -685,7 +712,7 @@ kbd { font-size: 14px; } -#windows .input { +.input { background-color: white; border: 1px solid #cdd3da; border-radius: 2px; @@ -894,6 +921,35 @@ kbd { touch-action: pan-y; } + +/** + * Toggled via JavaScript + */ +#sidebar .join-form { + display: none; +} + +#sidebar .join-form .input { + display: block; + margin-left: auto; + margin-right: auto; + margin-top: 5px; + margin-bottom: 5px; + width: 80%; +} + +#sidebar .join-form .btn { + display: block; + width: 80%; + padding: 1px; + margin: auto; + height: 29px; +} + +#sidebar .add-channel-tooltip { + float: right; +} + #chat .show-more { display: none; padding: 10px; diff --git a/client/js/lounge.js b/client/js/lounge.js index c260bd76..f395508d 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -132,6 +132,12 @@ $(function() { text: "List all channels", data: target.data("id"), }); + output += templates.contextmenu_item({ + class: "join", + action: "join", + text: "Join a channel\u2026", + data: target.data("id"), + }); } if (target.hasClass("channel")) { output += templates.contextmenu_item({ @@ -477,7 +483,39 @@ $(function() { closeChan($(this).closest(".chan")); }); + sidebar.on("click", ".add-channel", (e) => { + const id = $(e.target).data("id"); + const joinForm = $(`#join-channel-${id}`); + joinForm.toggle(); + joinForm.find(".input[name='channel']").focus(); + return false; + }); + + sidebar.on("submit", ".join-form", function() { + const form = $(this); + const channel = form.find("input[name='channel']"); + const channelString = channel.val(); + const key = form.find("input[name='key']"); + const keyString = key.val(); + const chan = utils.findCurrentNetworkChan(channelString); + if (chan.length) { + chan.click(); + } else { + socket.emit("input", { + text: `/join ${channelString} ${keyString}`, + target: form.prev().data("id"), + }); + } + channel.val(""); + key.val(""); + form.hide(); + return false; + }); + const contextMenuActions = { + join: function(itemData) { + $(`#join-channel-${itemData}`).show(); + }, close: function(itemData) { closeChan($(`.networks .chan[data-target="${itemData}"]`)); }, diff --git a/client/views/chan.tpl b/client/views/chan.tpl index 857c599f..f7bc0575 100644 --- a/client/views/chan.tpl +++ b/client/views/chan.tpl @@ -1,7 +1,15 @@ {{#each channels}}