include "sciter:reactor.tis"; var handler = $(#handler) || view; try { view.windowIcon = self.url(handler.get_icon()); } catch(e) {} var OS = view.mediaVar("platform"); var is_osx = OS == "OSX"; var is_win = OS == "Windows"; var is_linux = OS == "Linux"; var is_file_transfer; var is_xfce = false; try { is_xfce = handler.is_xfce(); } catch(e) {} function translate(name) { try { return handler.t(name); } catch(_) { return name; } } function hashCode(str) { var hash = 160 << 16 + 114 << 8 + 91; for (var i = 0; i < str.length; i += 1) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } return hash % 16777216; } function intToRGB(i, a = 1) { return 'rgba(' + ((i >> 16) & 0xFF) + ', ' + ((i >> 8) & 0x7F) + ',' + (i & 0xFF) + ',' + a + ')'; } function string2RGB(s, a = 1) { return intToRGB(hashCode(s), a); } function getTime() { var now = new Date(); return now.valueOf(); } function platformSvg(platform, color) { platform = (platform || "").toLowerCase(); if (platform == "linux") { return ; } if (platform == "mac os") { return ; } return ; } function centerize(w, h) { var (sx, sy, sw, sh) = view.screenBox(#workarea, #rectw); if (w > sw) w = sw; if (h > sh) h = sh; var x = (sx + sw - w) / 2; var y = (sy + sh - h) / 2; view.move(x, y, w, h); } function setWindowButontsAndIcon(only_min=false) { if (only_min) { $(div.window-buttons).content(
); } else { $(div.window-buttons).content(
); } $(div.window-icon>icon).style.set { "background-image": "url('" + handler.get_icon() + "')", }; } function adjustBorder() { if (is_osx) { if (view.windowState == View.WINDOW_FULL_SCREEN) { $(header).style.set { display: "none", }; } else { $(header).style.set { display: "block", padding: "0", }; } return; } if (view.windowState == view.WINDOW_MAXIMIZED) { self.style.set { border: "window-frame-width solid transparent", }; } else if (view.windowState == view.WINDOW_FULL_SCREEN) { self.style.set { border: "none", }; } else { self.style.set { border: "black solid 1px", }; } var el = $(button#maximize); if (el) el.attributes.toggleClass("restore", view.windowState == View.WINDOW_MAXIMIZED); el = $(span#fullscreen); if (el) el.attributes.toggleClass("active", view.windowState == View.WINDOW_FULL_SCREEN); } var svg_checkmark = ; var svg_edit = ; var svg_eye = ; var svg_send = ; var svg_chat = ; function scrollToBottom(el) { var y = el.box(#height, #content) - el.box(#height, #client); el.scrollTo(0, y); } function getNowStr() { var now = new Date(); return String.printf("%02d:%02d:%02d", now.hour, now.minute, now.second); } /******************** start of chatbox ****************************************/ class ChatBox: Reactor.Component { this var msgs = []; this var callback; function this(params) { if (params) { this.msgs = params.msgs || []; this.callback = params.callback; } } function renderMsg(msg) { var cls = msg.name == "me" ? "right-side msg" : "left-side msg"; return
{msg.name == "me" ?
{msg.time + " "} me
:
{msg.name} {" " + msg.time}
}
{msg.text}
; } function render() { var me = this; var msgs = this.msgs.map(function(msg) { return me.renderMsg(msg); }); self.timer(1ms, function() { scrollToBottom(me.msgs); }); return
{msgs}
{svg_send}
; } function send() { var el = this.$(input); var value = (el.value || "").trim(); el.value = ""; if (!value) return; if (this.callback) this.callback(value); } event keydown $(input) (evt) { if (!evt.shortcutKey) { if (evt.keyCode == Event.VK_ENTER || (view.mediaVar("platform") == "OSX" && evt.keyCode == 0x4C)) { this.send(); } } } event click $(div.send span) { this.send(); view.focus = $(input); } } /******************** end of chatbox ****************************************/ /******************** start of msgbox ****************************************/ var remember_password = false; var msgbox_params; function getMsgboxParams() { return msgbox_params; } // tmp workaround https://sciter.com/forums/topic/menu-not-be-hidden-when-open-dialog-on-linux/ function msgbox(type, title, text, callback=null, height=180, width=500, retry=0, contentStyle="") { if (is_linux) { // fix menu not hidden issue self.timer(1ms, function() { msgbox_(type, title, text, callback, height, width, retry, contentStyle); }); } else { msgbox_(type, title, text, callback, height, width, retry, contentStyle); } } function msgbox_(type, title, text, callback, height, width, retry, contentStyle) { var has_msgbox = msgbox_params != null; if (!has_msgbox && !type) return; var remember = false; try { remember = handler.get_remember(); } catch(e) {} msgbox_params = { remember: remember, type: type, text: text, title: title, getParams: getMsgboxParams, callback: callback, translate: translate, retry: retry, contentStyle: contentStyle, }; if (has_msgbox) return; var dialog = { client: true, parameters: msgbox_params, width: width + (is_xfce ? 50 : 0), height: height + (is_xfce ? 50 : 0), }; var html = handler.get_msgbox(); if (html) dialog.html = html; else dialog.url = self.url("msgbox.html"); var res = view.dialog(dialog); msgbox_params = null; stdout.printf("msgbox return, type: %s, res: %s\n", type, res); if (type.indexOf("custom") >= 0) { // } else if (!res) { if (!is_port_forward) view.close(); } else if (res == "!alive") { // do nothing } else if (res.type == "input-password") { handler.login(res.password, res.remember); if (!is_port_forward) msgbox("connecting", "Connecting...", "Logging in..."); } else if (res.reconnect) { if (!is_port_forward) connecting(); handler.reconnect(); } } function connecting() { handler.msgbox("connecting", "Connecting...", "Connection in progress. Please wait."); } handler.msgbox = function(type, title, text, retry=0) { self.timer(30ms, function() { msgbox(type, title, text, null, 180, 500, retry); }); } var reconnectTimeout = 1; handler.msgbox_retry = function(type, title, text, hasRetry) { handler.msgbox(type, title, text, hasRetry ? reconnectTimeout : 0); if (hasRetry) { reconnectTimeout *= 2; } else { reconnectTimeout = 1; } } /******************** end of msgbox ****************************************/ function Progress() { var _val; var pos = -0.25; function step() { if( _val !== undefined ) { this.refresh(); return false; } pos += 0.02; if( pos > 1.25) pos = -0.25; this.refresh(); return true; } function paintNoValue(gfx) { var (w,h) = this.box(#dimension,#inner); var x = pos * w; w = w * 0.25; gfx.fillColor( this.style#color ) .pushLayer(#inner-box) .rectangle(x,0,w,h) .popLayer(); return true; } this[#value] = property(v) { get return _val; set { _val = undefined; pos = -0.25; this.paintContent = paintNoValue; this.animate(step); this.refresh(); } } this.value = ""; } var svg_eye_cross = ; class PasswordComponent: Reactor.Component { this var visible = false; this var value = ''; this var name = 'password'; function this(params) { if (params && params.value) { this.value = params.value; } if (params && params.name) { this.name = params.name; } } function render() { return
{this.visible ? svg_eye_cross : svg_eye}
; } event click $(svg) { var el = this.$(input); var value = el.value; var start = el.xcall(#selectionStart) || 0; var end = el.xcall(#selectionEnd); this.update({ visible: !this.visible }); var me = this; self.timer(30ms, function() { var el = me.$(input); view.focus = el; el.value = value; el.xcall(#setSelection, start, end); }); } } function isReasonableSize(r) { var x = r[0]; var y = r[1]; return !(x < -3200 || x > 3200 || y < -3200 || y > 3200); }