import { handler,view,setWindowButontsAndIcon,translate,msgbox,adjustBorder,is_osx,is_xfce,svg_chat,svg_checkmark, is_linux } from "./common.js";
import {$,$$} from "@sciter";
import { adaptDisplay, audio_enabled, clipboard_enabled, keyboard_enabled } from "./remote.js";
var pi = handler.xcall("get_default_pi"); // peer information
var chat_msgs = [];
const svg_fullscreen = ();
const svg_action = ();
const svg_display = ();
const svg_secure = ();
const svg_insecure = ();
const svg_insecure_relay = ();
const svg_secure_relay = ();
var cur_window_state = view.state;
if (is_linux) {
// check_state_change;
setInterval(() => {
if (view.state != cur_window_state) {
stateChanged();
}
}, 30);
} else {
view.on("statechange",()=>{
stateChanged();
})
}
function get_id() {
return handler.xcall("get_option","alias") || handler.xcall("get_id")
}
function stateChanged() {
console.log('state changed from ' + cur_window_state + ' -> ' + view.state);
cur_window_state = view.state;
adjustBorder();
adaptDisplay();
if (cur_window_state != Window.WINDOW_MINIMIZED) {
view.focus = handler; // to make focus away from restore/maximize button, so that enter key work
}
let fs = view.state == Window.WINDOW_FULL_SCREEN;
let el = $("#fullscreen");
if (el) el.classList.toggle("active", fs);
el = $("#maximize");
if (el) {
el.state.disabled = fs; // TODO TEST
}
if (fs) {
$("header").style.setProperty("display","none");
}
}
export var header;
var old_window_state = Window.WINDOW_SHOWN;
var input_blocked;
class Header extends Element {
this() {
header = this;
}
render() {
let icon_conn;
let title_conn;
if (this.secure_connection && this.direct_connection) {
icon_conn = svg_secure;
title_conn = translate("Direct and encrypted connection");
} else if (this.secure_connection && !this.direct_connection) {
icon_conn = svg_secure_relay;
title_conn = translate("Relayed and encrypted connection");
} else if (!this.secure_connection && this.direct_connection) {
icon_conn = svg_insecure;
title_conn = translate("Direct and unencrypted connection");
} else {
icon_conn = svg_insecure_relay;
title_conn = translate("Relayed and unencrypted connection");
}
let title = get_id();
if (pi.hostname) title += "(" + pi.username + "@" + pi.hostname + ")";
if ((pi.displays || []).length == 0) {
return (
{title}
);
}
let screens = pi.displays.map(function(d, i) {
return
{i+1}
;
});
updateWindowToolbarPosition();
let style = "flow:horizontal;";
if (is_osx) style += "margin:*";
setTimeout(toggleMenuState,1);
return (
{is_osx || is_xfce ? "" :
{svg_fullscreen}}
{icon_conn}
{get_id()}
{screens}
{this.renderGlobalScreens()}
{svg_chat}
{svg_action}
{svg_display}
{this.renderDisplayPop()}
{this.renderActionPop()}
);
}
renderDisplayPop() {
return (
);
}
renderActionPop() {
return (
);
}
renderGlobalScreens() {
if (pi.displays.length < 3) return "";
let x0 = 9999999;
let y0 = 9999999;
let x = -9999999;
let y = -9999999;
pi.displays.map(function(d, i) {
if (d.x < x0) x0 = d.x;
if (d.y < y0) y0 = d.y;
let dx = d.x + d.width;
if (dx > x) x = dx;
let dy = d.y + d.height;
if (dy > y) y = dy;
});
let w = x - x0;
let h = y - y0;
let scale = 16. / h;
let screens = pi.displays.map(function(d, i) {
let min_wh = d.width > d.height ? d.height : d.width;
let fs = min_wh * 0.9 * scale;
let style = "width:" + (d.width * scale) + "px;" +
"height:" + (d.height * scale) + "px;" +
"left:" + ((d.x - x0) * scale) + "px;" +
"top:" + ((d.y - y0) * scale) + "px;" +
"font-size:" + fs + "px;";
if (is_osx) {
style += "line-height:" + fs + "px;";
}
return {i+1}
;
});
let style = "width:" + (w * scale) + "px; height:" + (h * scale) + "px;";
return
{screens}
;
}
["on click at #fullscreen"](_, el) {
if (view.state == Window.WINDOW_FULL_SCREEN) {
if (old_window_state == Window.WINDOW_MAXIMIZED) {
view.state = Window.WINDOW_SHOWN;
}
view.state = old_window_state;
} else {
old_window_state = view.state;
if (view.state == Window.WINDOW_MAXIMIZED) {
view.state = Window.WINDOW_SHOWN;
}
view.state = Window.WINDOW_FULL_SCREEN;
if (is_linux) { setTimeout(()=>view.state = Window.WINDOW_FULL_SCREEN,150); }
}
}
["on click at #chat"]() {
startChat();
}
["on click at #action"](_, me) {
let menu = $("menu#action-options");
me.popup(menu);
}
["on click at #display"](_, me) {
let menu = $("menu#display-options");
me.popup(menu);
}
["on click at #screen"](_, me) {
if (pi.current_display == me.index) return;
handler.xcall("switch_display",me.index);
}
["on click at #transfer-file"]() {
handler.xcall("transfer_file");
}
["on click at #tunnel"] () {
handler.xcall("tunnel");
}
["on click at #ctrl-alt-del"]() {
handler.xcall("ctrl_alt_del");
}
["on click at #lock-screen"]() {
handler.xcall("lock_screen");
}
["on click at #refresh"] () {
handler.xcall("refresh_video");
}
["on click at #block-input"] (_,me) {
if (!input_blocked) {
handler.xcall("toggle_option","block-input");
input_blocked = true;
me.text = "Unblock user input"; // TEST
} else {
handler.xcall("toggle_option","unblock-input");
input_blocked = false;
me.text = "Block user input";
}
}
["on click at menu#display-options>li"] (_, me) {
if (me.id == "custom") {
handle_custom_image_quality();
} else if (me.attributes.hasClass("toggle-option")) {
handler.toggle_option(me.id);
toggleMenuState();
} else if (!me.attributes.hasClass("selected")) {
let type = me.attributes["type"];
if (type == "image-quality") {
handler.xcall("save_image_quality",me.id);
} else if (type == "view-style") {
handler.xcall("save_view_style",me.id);
adaptDisplay();
}
toggleMenuState();
}
}
}
function handle_custom_image_quality() {
let tmp = handler.xcall("get_custom_image_quality");
let bitrate0 = tmp[0] || 50;
let quantizer0 = tmp.length > 1 ? tmp[1] : 100;
msgbox("custom", "Custom Image Quality", "", function(res=null) {
if (!res) return;
if (!res.bitrate) return;
handler.xcall("save_custom_image_quality",res.bitrate, res.quantizer);
toggleMenuState();
});
}
function toggleMenuState() {
let values = [];
let q = handler.xcall("get_image_quality");
if (!q) q = "balanced";
values.push(q);
let s = handler.xcall("get_view_style");
if (!s) s = "original";
values.push(s);
for (let el of $$("menu#display-options>li")) {
el.classList.toggle("selected", values.indexOf(el.id) >= 0);
}
for (let id of ["show-remote-cursor", "disable-audio", "disable-clipboard", "lock-after-session-end", "privacy-mode"]) {
let el = $('#' + id); // TEST
if (el) {
el.classList.toggle("selected", handler.xcall("get_toggle_option",id));
}
}
}
if (is_osx) {
$("header").content();
$("header").attributes["role"] = "window-caption"; // TODO
} else {
if (handler.is_file_transfer || handler.is_port_forward) {
$("caption").content();
} else {
$("div.window-toolbar").content();
}
setWindowButontsAndIcon();
}
if (!(handler.is_file_transfer || handler.is_port_forward)) {
$("header").style.setProperty("height","32px");
if (!is_osx) {
$("div.window-icon").style.setProperty("size","32px");
}
}
handler.updatePi = function(v) {
pi = v;
header.componentUpdate();
if (handler.is_port_forward) {
view.state = Window.WINDOW_MINIMIZED;
}
}
handler.switchDisplay = function(i) {
pi.current_display = i;
header.componentUpdate();
}
function updateWindowToolbarPosition() {
if (is_osx) return;
setTimeout(function() {
let el = $("div.window-toolbar");
let w1 = el.state.box("width", "border"); // TEST
let w2 = $("header").state.box("width", "border");
let x = (w2 - w1) / 2;
el.style.setProperty("left",x + "px");
el.style.setProperty("display","block")
},1);
}
view.onsizechange = function() {
// ensure size is done, so add timer
setTimeout(function() {
updateWindowToolbarPosition();
adaptDisplay();
},1);
};
handler.newMessage = function(text) {
chat_msgs.push({text: text, name: pi.username || "", time: getNowStr()});
startChat();
}
function sendMsg(text) {
chat_msgs.push({text: text, name: "me", time: getNowStr()});
handler.xcall("send_chat",text);
if (chatbox) chatbox.refresh();
}
var chatbox;
function startChat() {
if (chatbox) {
chatbox.state = Window.WINDOW_SHOWN; // TODO TEST el.state
chatbox.refresh(); // TODO el.refresh
return;
}
let icon = handler.xcall("get_icon");
let [sx, sy, sw, sh] = view.screenBox("workarea", "rectw"); // TEST
let w = 300;
let h = 400;
let x = (sx + sw - w) / 2;
let y = sy + 80;
let params = {
type: Window.FRAME_WINDOW,
x: x,
y: y,
width: w,
height: h,
client: true,
parameters: { msgs: chat_msgs, callback: sendMsg, icon: icon },
caption: get_id(),
};
let html = handler.xcall("get_chatbox");
if (html) params.html = html;
else params.url = document.url("chatbox.html");
chatbox = view.window(params); // TEST
}
handler.setConnectionType = function(secured, direct) {
// TEST
header.componentUpdate({
secure_connection: secured,
direct_connection: direct,
});
}