Merge pull request #1090 from AStove/CustomPath

Allow specifying custom websocket path in host field
use-minification
Lorenz Hübschle-Schneider 6 years ago committed by GitHub
commit 8f175d9da5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      css/glowingbear.css
  2. 7
      css/themes/base16-default.css
  3. 7
      css/themes/dark.css
  4. 8
      css/themes/light.css
  5. 41
      index.html
  6. 2
      js/bufferResume.js
  7. 6
      js/connection.js
  8. 52
      js/glowingbear.js

@ -610,7 +610,6 @@ h2 span, h2 small {
.panel[data-state=active] .panel-collapse { .panel[data-state=active] .panel-collapse {
transition: max-height 0.5s; transition: max-height 0.5s;
max-height: 60em;
height: auto; height: auto;
display: block; display: block;
} }

@ -65,6 +65,10 @@ a:visited:hover, a:visited:active, a:visited:focus {
border: 0px none; border: 0px none;
} }
.form-control[disabled] {
background: var(--base03);
}
.form-control:focus { .form-control:focus {
color: var(--base06); color: var(--base06);
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1), 0px 1px 7px 0px rgba(0, 0, 0, 0.2) inset; box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1), 0px 1px 7px 0px rgba(0, 0, 0, 0.2) inset;
@ -301,6 +305,9 @@ tr.bufferline:hover {
input[type=text], input[type=password], #sendMessage, .badge { input[type=text], input[type=password], #sendMessage, .badge {
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1), 0px 1px 7px 0px rgba(0, 0, 0, 0.2) inset; box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1), 0px 1px 7px 0px rgba(0, 0, 0, 0.2) inset;
} }
input[type=text].is-invalid{
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1), 0px 1px 7px 0px rgba(255, 0, 0, 0.6) inset;
}
input[type=text], input[type=password], #sendMessage, .btn-send, .btn-send-image, .btn-complete-nick { input[type=text], input[type=password], #sendMessage, .btn-send, .btn-send-image, .btn-complete-nick {
color: var(--base05); color: var(--base05);

@ -10,6 +10,10 @@ body {
border: 0px none; border: 0px none;
} }
.form-control[disabled] {
background: none repeat scroll 0% 0% rgba(63, 63, 63, 0.3);
}
.form-control option { .form-control option {
color: #eee; color: #eee;
background: #282828; background: #282828;
@ -86,6 +90,9 @@ input[type=text], input[type=password], #sendMessage, .badge, .btn-send, .btn-se
color: #ccc; color: #ccc;
background: none repeat scroll 0% 0% rgba(0, 0, 0, 0.3); background: none repeat scroll 0% 0% rgba(0, 0, 0, 0.3);
} }
input[type=text].is-invalid{
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1), 0px 1px 7px 0px rgba(255, 0, 0, 0.8) inset;
}
.btn-complete-nick:hover, .btn-complete-nick:focus, .btn-complete-nick:hover, .btn-complete-nick:focus,
.btn-send:hover, .btn-send:focus, .btn-send:hover, .btn-send:focus,

@ -69,6 +69,14 @@ select.form-control, select option, input[type=text], input[type=password], #sen
background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.3); background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.3);
} }
.form-control[disabled] {
background: none repeat scroll 0% 0% rgba(134, 134, 134, 0.3);
}
input[type=text].is-invalid{
box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.1), 0px 1px 7px 0px rgba(255, 0, 0, 0.8) inset;
}
#connection-infos { #connection-infos {
color: #aaa; color: #aaa;
} }

@ -104,10 +104,10 @@
<div class="input-group"> <div class="input-group">
<div class="row no-gutter"> <div class="row no-gutter">
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control favorite-font" id="host" ng-model="settings.host" placeholder="Address" autocapitalize="off"> <input type="text" class="form-control favorite-font" id="host" ng-model="settings.hostField" ng-change="parseHost()" ng-class="{'is-invalid': hostInvalid}" placeholder="Address" autocapitalize="off">
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
<input type="text" class="form-control favorite-font" id="port" ng-model="settings.port" placeholder="Port"> <input type="text" class="form-control favorite-font" id="port" ng-model="settings.port" ng-disabled="portDisabled" placeholder="Port">
</div> </div>
</div> </div>
</div> </div>
@ -136,7 +136,7 @@
</label> </label>
</div> </div>
</div> </div>
<button class="btn btn-lg btn-primary" ng-click="connect()" ng-cloak>{{ connectbutton }} <i ng-class="connectbuttonicon" class="glyphicon"></i></button> <button class="btn btn-lg btn-primary" ng-disabled="hostInvalid" ng-click="connect()" ng-cloak>{{ connectbutton }} <i ng-class="connectbuttonicon" class="glyphicon"></i></button>
</form> </form>
</div> </div>
</div> </div>
@ -207,6 +207,41 @@ chown -R <strong>username</strong>:<strong>username</strong> ~<strong>username</
<p> <p>
Helpful trigger to automatically repin a buffer (in this instance, <var>irc.freenode.#weechat</var>): <pre><code>/trigger add autopin signal "buffer_opened" "${buffer[${tg_signal_data}].full_name} =~ <var>irc.freenode.#weechat</var>" "" "/command -buffer ${buffer[${tg_signal_data}].full_name} * /buffer set localvar_set_pinned true"</code></pre> Helpful trigger to automatically repin a buffer (in this instance, <var>irc.freenode.#weechat</var>): <pre><code>/trigger add autopin signal "buffer_opened" "${buffer[${tg_signal_data}].full_name} =~ <var>irc.freenode.#weechat</var>" "" "/command -buffer ${buffer[${tg_signal_data}].full_name} * /buffer set localvar_set_pinned true"</code></pre>
</p> </p>
<h3>Setting a custom path</h3>
<p>
To connect to the weechat relay service we connect using a URL. A typical URL consists of 4 parts. <code>{scheme}://{host}:{port}/{path}</code>. The path can be changed by enterying the relay's full URL (except the scheme).
</p>
<ul>
<li><b>scheme</b>: The scheme must never be input. The scheme is "ws" if TLS isn't used and it is "wss" if TLS is used.</li>
<li><b>host</b>: Can be an IPv4, IPv6 or a FQDN. IPv6 addresses must be wrapped in square brackets.</li>
<li><b>port</b>: can be specified in the host field or the seperate port field. However if the path is specified in the host field the port must also be specified.</li>
<li><b>path</b>: by defautl this is "weechat". In case <a href="https://github.com/glowing-bear/glowing-bear/wiki/Proxying-WeeChat-relay-with-a-web-server">a proxy</a> is used the path can be changed by entering it in the host field.</li>
</ul>
<p>
Examples of correct input for the host field are:
</p>
<ul>
<li>192.168.0.1</li>
<li>192.168.0.1:8000</li>
<li>192.168.0.1:8000/weechat2</li>
<li>[2001:db8:85a3::8a2e:370:7334]</li>
<li>[2001:db8:85a3::8a2e:370:7334]:8000</li>
<li>[2001:db8:85a3::8a2e:370:7334]:8000/weechat2</li>
<li>yourhost.yourdomain.com</li>
<li>yourhost.yourdomain.com:8000</li>
<li>yourhost.yourdomain.com:8000/weechat2</li>
</ul>
<p>
Incorrect input for the host field:
</p>
<ul>
<li><span class="text-danger">ws://192.168.0.1</span> (do not specify the scheme)</li>
<li><span class="text-danger">192.168.0.1/weechat2</span> (must specify port when specifying path)</li>
<li><span class="text-danger">[2001:db8:85a3::8a2e:370:7334]/weechat2</span> (must specify port when specifying path)</li>
<li><span class="text-danger">yourhost.yourdomain.com/weechat2</span> (must specify port when specifying path)</li>
<li><span class="text-danger">2001:db8:85a3::8a2e:370:7334</span> (must wrap IPv6 address in square brackets)</li>
<li><span class="text-danger">2001:db8:85a3::8a2e:370:7334:8000</span> (must wrap IPv6 address in square brackets)</li>
</ul>
</div> </div>
</div> </div>
</div> </div>

@ -11,7 +11,7 @@ var bufferResume = angular.module('bufferResume', []);
bufferResume.service('bufferResume', ['settings', function(settings) { bufferResume.service('bufferResume', ['settings', function(settings) {
var resumer = {}; var resumer = {};
var key = settings.host + ":" + settings.port; var key = settings.host + ":" + settings.port + "/" + settings.path;
// Hold the status that we were able to find the previously accessed buffer // Hold the status that we were able to find the previously accessed buffer
// and reload it. If we cannot, we'll need to know so we can load the default // and reload it. If we cannot, we'll need to know so we can load the default

@ -20,15 +20,15 @@ weechat.factory('connection',
var locked = false; var locked = false;
// Takes care of the connection and websocket hooks // Takes care of the connection and websocket hooks
var connect = function (host, port, passwd, ssl, noCompression, successCallback, failCallback) { var connect = function (host, port, path, passwd, ssl, noCompression, successCallback, failCallback) {
$rootScope.passwordError = false; $rootScope.passwordError = false;
connectionData = [host, port, passwd, ssl, noCompression]; connectionData = [host, port, path, passwd, ssl, noCompression];
var proto = ssl ? 'wss' : 'ws'; var proto = ssl ? 'wss' : 'ws';
// If host is an IPv6 literal wrap it in brackets // If host is an IPv6 literal wrap it in brackets
if (host.indexOf(":") !== -1 && host[0] !== "[" && host[host.length-1] !== "]") { if (host.indexOf(":") !== -1 && host[0] !== "[" && host[host.length-1] !== "]") {
host = "[" + host + "]"; host = "[" + host + "]";
} }
var url = proto + "://" + host + ":" + port + "/weechat"; var url = proto + "://" + host + ":" + port + "/" + path;
$log.debug('Connecting to URL: ', url); $log.debug('Connecting to URL: ', url);
var onopen = function () { var onopen = function () {

@ -41,8 +41,9 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
// or else they won't be saved to the localStorage. // or else they won't be saved to the localStorage.
settings.setDefaults({ settings.setDefaults({
'theme': 'dark', 'theme': 'dark',
'host': 'localhost', 'hostField': 'localhost',
'port': 9001, 'port': 9001,
'path': 'weechat',
'ssl': (window.location.protocol === "https:"), 'ssl': (window.location.protocol === "https:"),
'savepassword': false, 'savepassword': false,
'autoconnect': false, 'autoconnect': false,
@ -65,6 +66,12 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
}); });
$scope.settings = settings; $scope.settings = settings;
//For upgrade reasons because we changed the name of host to hostField
//check if the value might still be in the host key instead of the hostField key
if (!settings.hostField && settings.host) {
settings.hostField = settings.host;
}
$rootScope.countWatchers = function () { $rootScope.countWatchers = function () {
$log.debug($rootScope.$$watchersCount); $log.debug($rootScope.$$watchersCount);
}; };
@ -623,6 +630,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
} }
$rootScope.bufferBottom = eob.offsetTop <= bl.scrollTop + bl.clientHeight; $rootScope.bufferBottom = eob.offsetTop <= bl.scrollTop + bl.clientHeight;
}; };
$rootScope.scrollWithBuffer = function(scrollToReadmarker, moreLines) { $rootScope.scrollWithBuffer = function(scrollToReadmarker, moreLines) {
// First, get scrolling status *before* modification // First, get scrolling status *before* modification
// This is required to determine where we were in the buffer pre-change // This is required to determine where we were in the buffer pre-change
@ -656,6 +664,35 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
window.requestAnimationFrame(scroll); window.requestAnimationFrame(scroll);
}; };
$scope.parseHost = function() {
//The host field is multi purpose for advanced users
//There can be a combination of host, port and path
//If host is specified here the dedicated port field is disabled
$rootScope.hostInvalid = false;
var parts;
var regexHost = /^([^:\/]*|\[.*\])$/;
var regexHostPort = /^([^:]*|\[.*\]):(\d+)$/;
var regexHostPortPath = /^([^:]*|\[.*\]):(\d*)\/(.+)$/;
if ((parts = regexHost.exec(settings.hostField)) !== null) { //host only
settings.host = parts[1];
settings.path = "weechat";
$rootScope.portDisabled = false;
} else if ((parts = regexHostPort.exec(settings.hostField)) !== null) { //host:port
settings.host = parts[1];
settings.port = parts[2];
settings.path = "weechat";
$rootScope.portDisabled = true;
} else if ((parts = regexHostPortPath.exec(settings.hostField)) !== null) { //host:port/path
settings.host = parts[1];
settings.port = parts[2];
settings.path = parts[3];
$rootScope.portDisabled = true;
} else {
$rootScope.hostInvalid = true;
}
};
$scope.connect = function() { $scope.connect = function() {
notifications.requestNotificationPermission(); notifications.requestNotificationPermission();
@ -665,14 +702,16 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$rootScope.bufferBottom = true; $rootScope.bufferBottom = true;
$scope.connectbutton = 'Connecting'; $scope.connectbutton = 'Connecting';
$scope.connectbuttonicon = 'glyphicon-refresh glyphicon-spin'; $scope.connectbuttonicon = 'glyphicon-refresh glyphicon-spin';
connection.connect(settings.host, settings.port, $scope.password, settings.ssl); connection.connect(settings.host, settings.port, settings.path, $scope.password, settings.ssl);
}; };
$scope.disconnect = function() { $scope.disconnect = function() {
$scope.connectbutton = 'Connect'; $scope.connectbutton = 'Connect';
$scope.connectbuttonicon = 'glyphicon-chevron-right'; $scope.connectbuttonicon = 'glyphicon-chevron-right';
bufferResume.reset(); bufferResume.reset();
connection.disconnect(); connection.disconnect();
}; };
$scope.reconnect = function() { $scope.reconnect = function() {
var bufferId = models.getActiveBuffer().id; var bufferId = models.getActiveBuffer().id;
connection.attemptReconnect(bufferId, 3000); connection.attemptReconnect(bufferId, 3000);
@ -681,6 +720,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$scope.showModal = function(elementId) { $scope.showModal = function(elementId) {
document.getElementById(elementId).setAttribute('data-state', 'visible'); document.getElementById(elementId).setAttribute('data-state', 'visible');
}; };
$scope.closeModal = function($event) { $scope.closeModal = function($event) {
function closest(elem, selector) { function closest(elem, selector) {
var matchesSelector = elem.matches || elem.webkitMatchesSelector || elem.mozMatchesSelector || elem.msMatchesSelector; var matchesSelector = elem.matches || elem.webkitMatchesSelector || elem.mozMatchesSelector || elem.msMatchesSelector;
@ -927,12 +967,13 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
}; };
$scope.init = function() { $scope.init = function() {
$scope.parseHost();
if (window.location.hash) { if (window.location.hash) {
var rawStr = atob(window.location.hash.substring(1)); var rawStr = atob(window.location.hash.substring(1));
window.location.hash = ""; window.location.hash = "";
var spl = rawStr.split(":"); var spl = rawStr.split(":");
var host = spl[0]; settings.host = spl[0];
var port = parseInt(spl[1]); settings.port = parseInt(spl[1]);
var password = spl[2]; var password = spl[2];
var ssl = spl.length > 3; var ssl = spl.length > 3;
notifications.requestNotificationPermission(); notifications.requestNotificationPermission();
@ -942,7 +983,8 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$rootScope.bufferBottom = true; $rootScope.bufferBottom = true;
$scope.connectbutton = 'Connecting'; $scope.connectbutton = 'Connecting';
$scope.connectbuttonicon = 'glyphicon-chevron-right'; $scope.connectbuttonicon = 'glyphicon-chevron-right';
connection.connect(host, port, password, ssl); $scope.parseHost();
connection.connect(settings.host, settings.port, settings.path, password, ssl);
} }
}; };

Loading…
Cancel
Save