var selectTags = [];
var ab = { tags: [], peers: [] };
var abLoading;
var abError;
var current_menu_peer_id = '';
var current_menu_tag = '';
class AddressBook: Reactor.Component
{
this var style;
this var selectedTags = function() {
var tags = handler.get_local_option("selected-tags");
if (tags) return tags.split(",");
return [];
}();
function render() {
if (!handler.get_local_option("access_token")) {
return
{translate("Login")}
;
}
if (abLoading) {
return ;
} else if (abError) {
return
{abError}
{translate("Retry")}
;
}
var peers = this.getPeers();
var me = this;
return
,
"",
function(res=null) {
if (!res) return;
var value = (res.text || "").trim();
var values = value.split(/[\s,;\n]+/g);
if (values.length == 0) return;
for (var v in values) {
var found;
for (var i = 0; i < ab.peers.length; ++i) {
if (ab.peers[i].id == v) {
found = true;
break;
}
}
if (found) continue;
ab.peers.push({ id: v });
}
updateAb();
me.update();
},
300);
}
event click $(#add-tag) (_, __) {
var me = this;
msgbox("custom-add-tag", translate("Add Tag"),
{translate("whitelist_sep")}
, "", function(res=null) {
if (!res) return;
var value = (res.text || "").trim();
var values = value.split(/[\s,;\n]+/g);
if (values.length == 0) return;
for (var v in values) {
if (ab.tags.indexOf(v) < 0) {
ab.tags.push(v);
}
}
updateAb();
me.update();
}, 300);
}
event click $(#remove-tag) (_, me) {
var tag = current_menu_tag;
var i = ab.tags.indexOf(tag);
ab.tags.splice(i, 1);
for (var p in ab.peers) {
if (p.tags) {
i = p.tags.indexOf(tag);
if (i >= 0) p.tags.splice(i, 1);
}
}
updateAb();
this.update();
}
event click $(#unselect-tags) (_, me) {
this.selectedTags = [];
handler.set_local_option("selected-tags", "");
this.update();
}
event click $(#tags span) (_, me) {
me.attributes.toggleClass('active');
if (me.attributes.hasClass('active')) {
this.selectedTags.push(me.text);
} else {
this.selectedTags.splice(this.selectedTags.indexOf(me.text), 1);
}
handler.set_local_option("selected-tags", this.selectedTags.join(','));
this.update();
}
function getPeers() {
var tags = [];
for (var t in this.selectedTags) {
if (ab.tags.indexOf(t) >= 0) tags.push(t);
}
if (tags.length != this.selectedTags.length) {
this.selectedTags = tags;
handler.set_local_option("selected-tags", tags.join(","));
stdout.println("updated selected tags");
}
if (tags.length == 0) return ab.peers;
var peers = [];
if (tags.length > 0) {
for (var p in ab.peers) {
for (var t in (p.tags || [])) {
if (tags.indexOf(t) >= 0) {
peers.push(p);
break;
}
}
}
} else {
peers = ab.peers;
}
return peers;
}
}
class SelectTags: Reactor.Component {
function this(params) {
selectTags = this;
this.tags = params.tags;
}
function render() {
var me = this;
return
;
}
event click $(#tags span) (_, me) {
me.attributes.toggleClass('active');
var i = this.tags.indexOf(me.text);
if (i < 0) {
this.tags.push(me.text);
} else {
this.tags.splice(i, 1);
}
}
}
var svg_tile = ;
var svg_list = ;
var search_icon = ;
var clear_icon = ;
function getSessionsStyleOption(type) {
return (type || "recent") + "-sessions-style";
}
function getSessionsStyle(type) {
var v = handler.get_local_option(getSessionsStyleOption(type));
if (!v) v = type == "ab" ? "list" : "tile";
return v;
}
var searchPatterns = {};
class SearchBar: Reactor.Component {
this var type = "";
function this(params) {
this.type = (params || {}).type || "";
}
function render() {
var value = searchPatterns[this.type] || "";
var me = this;
self.timer(1ms, function() { (me.search_id || {}).value = value; });
return
{search_icon}
{value && {clear_icon}}
;
}
event click $(span.clear-input) {
this.onChange('');
}
event change $(input) (_, el) {
this.onChange(el.value.trim().toLowerCase());
}
function onChange(v) {
searchPatterns[this.type] = v;
app.multipleSessions.update();
}
}
class SessionStyle: Reactor.Component {
this var type = "";
function this(params) {
this.type = (params || {}).type || "";
}
function render() {
var sessionsStyle = getSessionsStyle(this.type);
return
{svg_tile}{svg_list}
;
}
event click $(span.inactive) {
var option = getSessionsStyleOption(this.type);
var sessionsStyle = getSessionsStyle(this.type);
handler.set_local_option(option, sessionsStyle == "tile" ? "list" : "tile");
if (is_linux) {
app.multipleSessions.stupidUpdate();
} else {
app.multipleSessions.update();
}
}
}
class SessionList: Reactor.Component {
this var sessions = [];
this var type = "";
this var style;
function this(params) {
this.sessions = params.sessions;
this.type = params.type || "";
this.style = getSessionsStyle(this.type);
}
function getSessions() {
var p = searchPatterns[this.type];
if (!p) return this.sessions;
var tmp = [];
this.sessions.map(function(s) {
var name = (s[4] || s.alias || "").toLowerCase();
var id = (s[0] || s.id || "").toLowerCase();
var user = (s[1] || "").toLowerCase();
var hostname = (s[2] || "").toLowerCase();
if (name.indexOf(p) >= 0 || id.indexOf(p) >= 0 || user.indexOf(p) >= 0 || hostname.indexOf(p) >= 0) {
tmp.push(s);
}
});
return tmp;
}
function render() {
var sessions = this.getSessions();
if (sessions.length == 0) {
return
{translate("Empty")}
;
}
var me = this;
sessions = sessions.map(function(x) { return me.getSession(x); });
return
{translate('Connect')}
{translate('Transfer File')}
{translate('TCP Tunneling')}
{svg_checkmark}{translate('Always connect via relay')}
RDP
{translate('WOL')}
{this.type != "lan" &&
{translate('Rename')}
}
{this.type != "fav" &&
{translate('Remove')}
}
{is_win &&
{translate('Create Desktop Shortcut')}
}
{translate('Unremember Password')}
{(!this.type || this.type == "fav") &&
{translate('Add to Favorites')}
}
{(!this.type || this.type == "fav") &&
{translate('Remove from Favorites')}
}
{this.type == "ab" &&
{translate('Edit Tag')}
}
{sessions}
;
}
function getSession(s) {
var id = s[0] || s.id || "";
var username = s[1] || s.username || "";
var hostname = s[2] || s.hostname || "";
var platform = s[3] || s.platform || "";
var alias = s[4] || s.alias || "";
if (this.style == "list") {
return
{platform && platformSvg(platform, "white")}
{alias ? alias : formatId(id)}
{username}@{hostname}
{svg_menu}
;
}
return
{platform && platformSvg(platform, "white")}
{username}@{hostname}
{alias ? alias : formatId(id)}
{svg_menu}
;
}
event dblclick $(div.remote-session-link) (evt, me) {
createNewConnect(me.id, "connect");
}
event click $(#menu) (_, me) {
var id = me.parent.parent.id;
var platform = me.parent.parent.attributes["platform"];
this.$(#rdp).style.set{
display: (platform == "Windows" && is_win) ? "block" : "none",
};
this.$(#forget-password).style.set{
display: handler.peer_has_password(id) ? "block" : "none",
};
if (!this.type || this.type == "fav") {
var in_fav = handler.get_fav().indexOf(id) >= 0;
this.$(#add-fav).style.set{
display: in_fav ? "none" : "block",
};
this.$(#remove-fav).style.set{
display: in_fav ? "block" : "none",
};
}
// https://sciter.com/forums/topic/replacecustomize-context-menu/
var menu = this.$(menu#remote-context);
current_menu_peer_id = id;
var el = this.$(li#force-always-relay);
if (el) {
var force = handler.get_peer_option(id, "force-always-relay");
el.attributes.toggleClass("selected", force == "Y");
}
var conn = this.$(menu #connect);
if (conn) {
var alias = me.parent.parent.$(#alias);
if (alias) {
alias = alias.text.replace(' ', '');
if (alias != id) {
conn.text = translate('Connect') + ' ' + id;
} else {
conn.text = translate('Connect');
}
}
}
me.popup(menu);
}
event click $(menu#remote-context li) (evt, me) {
var action = me.id;
var id = current_menu_peer_id;
if (action == "connect") {
createNewConnect(id, "connect");
} else if (action == "transfer") {
createNewConnect(id, "file-transfer");
} else if (action == "wol") {
handler.send_wol(id);
} else if (action == "remove") {
if (this.type == "ab") {
for (var i = 0; i < ab.peers.length; ++i) {
if (ab.peers[i].id == id) {
ab.peers.splice(i, 1);
app.update();
updateAb();
break;
}
}
} else if (this.type == "lan") {
handler.remove_discovered(id);
app.update();
} else {
handler.remove_peer(id);
app.update();
}
} else if (action == "forget-password") {
handler.forget_password(id);
} else if (action == "shortcut") {
handler.create_shortcut(id);
} else if (action == "rdp") {
if (is_edit_rdp_port) {
is_edit_rdp_port = false;
return;
}
createNewConnect(id, "rdp");
} else if (action == "add-fav") {
var favs = handler.get_fav();
if (favs.indexOf(id) < 0) {
favs = [id].concat(favs);
handler.store_fav(favs);
}
app.multipleSessions.update();
app.update();
} else if (action == "remove-fav") {
var favs = handler.get_fav();
var i = favs.indexOf(id);
favs.splice(i, 1);
handler.store_fav(favs);
app.multipleSessions.update();
} else if (action == "tunnel") {
createNewConnect(id, "port-forward");
} else if (action == "rename") {
var old_name = handler.get_peer_option(id, "alias");
var abPeer;
if (this.type == "ab") {
for (var v in ab.peers) {
if (v.id == id) {
abPeer = v;
old_name = v.alias || "";
}
}
}
msgbox("custom-rename", "Rename", "
\
\
\
", "", function(res=null) {
if (!res) return;
var name = (res.name || "").trim();
if (name != old_name) {
if (abPeer) {
abPeer.alias = name;
updateAb();
}
handler.set_peer_option(id, "alias", name);
}
app.update();
});
} else if (action == "force-always-relay") {
var force = handler.get_peer_option(id, "force-always-relay");
handler.set_peer_option(id, "force-always-relay", force == "Y" ? "" : "Y");
} else if (action == "edit-tag") {
var peer;
for (var v in ab.peers) {
if (v.id == id) {
peer = v;
}
}
if (!peer) return;
msgbox("custom-edit-tag", "Edit Tag", , "", function(res=null) {
if (!res) return;
peer.tags = selectTags.tags;
updateAb();
}, 260, 500, 0, "size: *; margin: 2em 0;");
}
}
}
function getSessionsType() {
return handler.get_local_option("show-sessions-type");
}
class Favorites: Reactor.Component {
function render() {
var sessions = handler.get_fav().map(function(f) {
return handler.get_peer(f);
});
return ;
}
}
class MultipleSessions: Reactor.Component {
function render() {
var type = getSessionsType();
return