You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/Distro/Template/common.htm

1172 lines
30 KiB
HTML

<style>
@import url(common.css);
</style>
<script type="text/tiscript">
const CommonNative = View.CommonNative;
const NODE_DIV = 1;
const NODE_GROUP = 2;
const NODE_CONTACT = 3;
const GA_NONE = 0;
const GA_ADD = 1;
const GA_RENAME = 2;
const GA_REMOVE = 3;
VM.unhandledExceptionHandler = function(err) {
view.msgbox(#error, err.toString(), "Sciter error", #ok);
return true;
}
class KillOverscroll: Behavior {
function wheelEvent(e) {
return (this.scroll(#top) <= 0 && e.wheelDelta > 0) || (this.scroll(#bottom) <= 0 && e.wheelDelta < 0);
}
function attached() {
this.subscribe(this.wheelEvent, Event.MOUSE, Event.MOUSE_WHEEL);
}
function detached() {
this.unsubscribe(this.wheelEvent);
}
}
class KillOverscrollNoFocus: KillOverscroll {
function attached() {
super.attached();
this.state.focusable = false;
}
}
class GlobalCaretPos: Behavior {
var savedCaretPos = 0;
var savedEdge = false;
function getCaretPos() {
if (!this.selection.caret) return 0;
var caretEdge = false;
var caretPos = this.selection.caret[1];
var priornode = this.selection.caret[0].parent.prior;
while (priornode) {
caretPos += priornode.text.length + 2;
priornode = priornode.prior;
}
caretEdge = this.selection.caret[2];
return caretPos + (caretEdge ? 1 : 0);
}
function getCaretEdge() {
if (!this.selection.caret) return false;
return this.selection.caret[2];
}
function setCaretPos(caretPos, caretEdge) {
if (caretPos < 0 || this.value == "" || this.value.length == 0) return;
this.selection.advance(#first);
var pos = 0;
var node = this.first;
while (node.next && pos + node.text.length + 2 <= caretPos) {
pos += node.text.length + 2;
node = node.next;
}
this.selection.select([bookmark: node.firstNode, caretPos - pos + (caretEdge ? -1 : 0), caretEdge]);
}
function saveCaretPos() {
this.savedCaretPos = this.getCaretPos();
this.savedEdge = this.getCaretEdge();
}
function restoreCaretPos() {
this.setCaretPos(this.savedCaretPos, this.savedEdge);
}
function attached() {
// if (this.selection) // init empty selection
// if (this.selection.caret === null) this.selection.select(this, #content);
}
}
class ThemedImage: Behavior {
function setupIcon() {
if (!View.MainNative) {
this.setVisible(false);
return;
}
this.applySprite(getSpriteData(this.@#pic));
this.update();
}
function setIcon(pic) {
this.@#pic = pic;
this.setupIcon();
}
function attached() {
if (this.@#auto == "") this.setupIcon();
}
}
class CustomTabs: Behavior {
var strip, panels;
function init() {
this.strip.on("click", "div[panel]", function(e) {
this super.switchTab(this);
});
// Select first
var tabs = this.strip.$$(> *);
if (tabs.length > 1)
tabs.first.@#selected = "";
else
this.strip.style#display = "none";
if (this.panels.first) this.panels.first.@#selected = "";
}
function switchTab(theTab) {
var tabs = this.strip.$$(> *);
for (var tab in tabs)
if (tab !== theTab) tab.@.remove("selected");
theTab.@#selected = "";
if (theTab.onOpen) theTab.onOpen();
var panels = this.panels.$$(> *);
for (var panel in panels) panel.@.remove("selected");
this.panels.$([panel="{theTab.@#panel}"]).@#selected = "";
}
function addTab(stripContent, panelContent, onOpen = null) {
this.strip.append(stripContent);
this.panels.append(panelContent);
if (onOpen) this.strip.last.onOpen = onOpen;
}
function attached() {
this.strip = this.$(.strip);
this.panels = this.$(.panels);
if (this.@#auto == "") this.init();
}
property selectedTabIndex(index) {
get return this.panels.$([selected]).index;
}
}
function TranslateMenu() {
try {
if (CommonNative.GetTranslation)
this.text = CommonNative.GetTranslation(this.text);
} catch(e) {}
}
function setupWindow(resize = true, min = true, max = true) {
view.windowResizable = resize;
view.windowMinimizable = min;
view.windowMaximizable = max;
}
function animateWindow() {
if (View.commonSettings.animateWindows) self.post(:{
var (x, y) = view.box(#position, #border, #screen);
self.animate(:progress {
view.move(x, (y - progress * 7).toInteger());
}, 100ms);
});
}
function translateWindow(selector) {
var elements = self.selectAll(selector);
var texts = [];
for (var element in elements) texts.push(element.text);
if (texts.length > 0) {
var ttexts = CommonNative.GetTranslations(texts);
for (var (index, element) in elements) element.text = ttexts[index];
}
elements = $$([title]);
texts = [];
for (var element in elements) texts.push(element.attributes["title"]);
if (texts.length > 0) {
var ttexts = CommonNative.GetTranslations(texts);
for (var (index, element) in elements) element.attributes["title"] = ttexts[index];
}
}
function activate(reorder = false) {
view.activate(reorder ? #toFront : #noChange);
}
function getBounds() {
var (x, y, width, height) = view.box(#rectw, #border, #screen);
return [x, y, width, height];
}
function setBounds(left, top, width, height) {
view.move(left, top, width, height, false);
}
function setPosition(left, top) {
view.move(left, top, false);
}
function fixMenu(menu, e, exec = null) {
if (e.target == menu)
if (e.type == Event.POPUP_READY) {
menu.focusback = view.focus && view.focus.tag != "menu" ? view.focus : null;
menu.state.focus = true;
} else if (e.type == Event.POPUP_DISMISSING) {
if (exec != null) exec();
var item = menu.$(:current);
if (item) item.state.current = false;
if (menu.focusback && CommonNative.IsWindowActive(menu.focusback))
view.focus = menu.focusback;
}
}
function setMenuListener(menu, callback) {
menu.subscribe(function(e) {
fixMenu(this, e);
if (e.type == Event.MENU_ITEM_CLICK) e.target.timer(1ms, callback); // focus fix
}, Event.BEHAVIOR_EVENT);
}
function setSystemColor(r, g, b) {
View.activeClr = color(r, g, b);
for (var window in View.all)
if (window.root.ns.applySystemColor) window.root.ns.applySystemColor();
}
function applyActiveColor(activeClr) {
if (!activeClr) return;
self.style.variable("activeColor", activeClr);
self.style.variable("activeColorHover", activeClr.tint(0.85, -1));
self.style.variable("activeColorCurrent", activeClr.tint(0.7, -0.75));
self.style.variable("activeColorHoverCurrent", activeClr.tint(0.6, -0.7));
self.style.variable("activeColorLight", activeClr.tint(0.2));
self.style.variable("activeColorDark", activeClr.tint(-0.2));
}
function applySystemColor() {
if (View.activeClr) applyActiveColor(View.activeClr)
}
applySystemColor();
function getSpriteData(pic) {
return CommonNative.GetSpriteData(pic);
}
function renderGroupLists(opt, addOut) {
var groupitems = View.MainNative.GetGroups(addOut);
opt.clear();
for (var groupitem in groupitems)
if (groupitem.caption == "-")
opt.append(<hr/>);
else
opt.append(<li groupid={groupitem.id}><div pic={groupitem.img}></div><span>{groupitem.caption}</span></li>);
var pics = opt.$$(div[pic]);
for (var pic in pics) {
pic.setupIcon();
pic.update();
}
}
function findWindow(uniq) {
for (var window in View.all)
if (window.uniqueid == uniq) return window;
return null;
}
function findWindows(uniq) {
var windows = [];
for (var window in View.all)
if (window.uniqueid == uniq) windows.push(window);
return windows;
}
function matchWindows(text) {
var windows = [];
for (var window in View.all)
if (window.uniqueid instanceof String && window.uniqueid.indexOf(text) == 0) windows.push(window);
return windows;
}
function getActiveWindow() {
for (var window in View.all)
if (CommonNative.IsWindowActive(window.root)) return window;
return null;
}
function openSingleWindow(props) {
var window = findWindow(props.uniqueid);
if (window) {
if (window.windowState == View.WINDOW_MINIMIZED)
window.windowState = View.WINDOW_SHOWN;
window.activate(#toFront);
return window.isDialog ? "" : window;
}
var scr = view.screen;
if (props.screen) {
var scrwin = findWindow(props.screen);
if (scrwin) scr = scrwin.screen;
} else {
var actwin = getActiveWindow();
if (actwin) scr = actwin.screen;
}
var winparams = {
type: props.tool ? View.TOOL_WINDOW : View.FRAME_WINDOW,
state: props.hidden ? View.WINDOW_HIDDEN : View.WINDOW_SHOWN,
url: self.url(props.url),
screen: scr,
caption: props.translate === false ? props.caption : CommonNative.GetTranslation(props.caption)
};
if (props.cascade) {
var windows = matchWindows(props.uniqueid.split(":")[0]);
var curx = 0, cury = 0;
for (var window in windows) {
var (x, y) = window.box(#position, #border, #screen);
curx = Integer.max(curx, x);
cury = Integer.max(cury, y);
}
var (sx, sy, sw, sh) = view.screenBox(scr, #frame, #rectw);
if (curx == 0 || cury == 0 || curx > sx + sw / 3 || cury > sy + sh / 3) {
curx = sx + sw / 4;
cury = sy + sh / 6;
} else {
curx += 40;
cury += 40;
}
props.x = curx;
props.y = cury;
}
if (props.alignment) winparams = winparams.extend({ alignment: props.alignment });
if (props.params) winparams = winparams.extend({ parameters: props.params });
if (props.x) winparams = winparams.extend({ x: props.x });
if (props.y) winparams = winparams.extend({ y: props.y });
if (props.width) winparams = winparams.extend({ width: props.width });
if (props.height) winparams = winparams.extend({ height: props.height });
if (props.disable) self.state.disabled = true;
if (props.dialog) {
return view.dialog(winparams);
} else {
var window = props.detach === true ? View.window(winparams) : view.window(winparams);
window.uniqueid = props.uniqueid;
if (props.disable) window.on("close", :: self.state.disabled = false);
return window;
}
}
function createContactList() {
var window = openSingleWindow({
url: "main.htm",
caption: "",
hidden: true,
//detach: true, // makes window unowned and shows taskbar button
translate: false,
uniqueid: #main,
alignment: 5,
width: 250,
height: 400
});
return window.root;
}
function createChat() {
var window = openSingleWindow({
url: "chat.htm",
caption: "",
hidden: true,
detach: true,
translate: false,
uniqueid: #chat,
alignment: 5,
width: 600,
height: 400
});
return window.root;
}
function createLog() {
var window = openSingleWindow({
url: "log.htm",
caption: "",
hidden: true,
detach: true,
uniqueid: #log,
alignment: 5,
width: 800,
height: 600
});
return window.root;
}
function openLog() {
var window = findWindow(#log);
if (window) window.root.ns.showLog(view.screen);
}
function openSessionsManager() {
var (px, py, dw, dh) = view.screenBox(#frame, #rectw);
openSingleWindow({
url: "sessionsmgr.htm",
caption: "Sessions manager",
uniqueid: #sessionsmgr,
detach: true,
alignment: 5,
width: dw / 3,
height: dh / 2.5
});
}
function updateSessionsManager(current) {
var window = findWindow(#sessionsmgr);
if (window)
if (current)
window.root.ns.removeCurrent();
else
window.root.ns.updateSessionsList();
}
function createTips() {
var window = openSingleWindow({
url: "tips.htm",
caption: "",
//detach: true,
translate: false,
uniqueid: #tips,
x: -9999,
y: -9999,
width: 1,
height: 1
});
return window.root;
}
function openPasswordDialog(type, title, pwd = "", maxlen = 0, translate = true) {
return openSingleWindow({
dialog: type != #acc,
translate: translate,
url: "enterpassword.htm",
caption: title,
uniqueid: type != #acc ? #loginpassword : #accpassword,
alignment: 5,
params: {
type: type,
password: pwd,
maxlength: maxlen
}
});
}
function openLoginDialog() {
var res = openPasswordDialog(#login,
CommonNative.GetTranslation("Login password") + " (" + View.MainNative.GetCurrentUserAcc() + ")",
View.MainNative.GetPwd(),
View.MainNative.GetMaxPasswordLength(),
false
);
if (res) {
View.MainNative.SavePassword(res);
return true;
} else return false;
}
function openAccDialog() {
return openPasswordDialog(#acc,
CommonNative.GetTranslation("Account password") + " (" + View.MainNative.GetCurrentUserAcc() + ")",
"", 0, false
);
}
function enterPassword(title, maxLen) {
return openPasswordDialog(#pwd, title, "", maxLen, false);
}
function enterLockPassword(title, hint, maxLen) {
self.post(:: openSingleWindow({
detach: true,
translate: false,
url: "enterpassword.htm",
caption: title,
uniqueid: #lock,
screen: #main,
alignment: 5,
params: {
type: #lockpwd,
maxlength: 0,
hint: hint
}
}));
}
function enterUIN(caption, icon) {
return openSingleWindow({
dialog: true,
url: "enterstring.htm",
caption: caption,
uniqueid: #enteruin,
alignment: 5,
params: {
uniqueid: #enteruin,
icon: icon
}
});
}
function inputQuery(caption, text, icon) {
return openSingleWindow({
dialog: true,
url: "enterstring.htm",
caption: caption,
uniqueid: #enterstr,
alignment: 5,
params: {
uniqueid: #enterstr,
icon: icon,
text: text
}
});
}
function viewInfoAbout() {
var uin = enterUIN("View info about...", "info");
if (uin && uin != "") self.post(:: View.MainNative.ViewInfoAbout(uin));
}
function openChatWith() {
var uin = enterUIN("Open chat with...", "msg");
if (uin && uin != "") self.post(:: View.MainNative.OpenChatWith(uin));
}
function createNewAccount() {
var uin = enterUIN("New user", "uin");
if (uin && uin != "") CommonNative.CreateAccount(uin)
}
function switchUser(conflict = false) {
if (conflict) self.post(:: showAlert(#warning, "There is another instance with this user already running"));
return openSingleWindow({
dialog: true,
url: "users.htm",
caption: "Users",
uniqueid: #users,
screen: #main,
alignment: 5,
width: 450,
height: 310
});
}
function showAlert(type, message, translate = true) {
var alert = openSingleWindow({
url: "alert.htm",
caption: "",
detach: true,
uniqueid: #alert,
screen: #main,
alignment: 5
});
alert.root.ns.addMessage({
type: type,
message: translate ? CommonNative.GetTranslation(message) : message
});
}
function createDialog(icon, title, msg, left = false, buttons = null, defbtn = null, cancelbtn = null, timeout = 0) {
return openSingleWindow({
dialog: true,
url: "dialog.htm",
caption: title,
translate: false,
uniqueid: #msgdlg,
alignment: 5,
params: {
icon: icon,
message: msg,
left: left,
buttons: buttons,
default: defbtn,
cancel: cancelbtn,
timeout: timeout
}
});
}
function openViewInfo(uid, title = "", updateOnly = false) {
var window = findWindow("info:" + uid);
if (window) {
if (window.windowState == View.WINDOW_MINIMIZED)
window.windowState = View.WINDOW_SHOWN;
window.activate(#toFront);
window.root.ns.updateData();
} else if (!updateOnly) {
openSingleWindow({
url: "viewinfo.htm",
caption: title,
detach: true,
cascade: true,
translate: false,
uniqueid: "info:" + uid,
alignment: 7,
width: 450,
height: 550,
params: {
contact: uid
}
});
}
}
function updateViewInfoAnP(uid) {
var window = findWindow("info:" + uid);
if (window) window.root.ns.updateAvatarAndPhoto();
}
function updateDB() {
var window = findWindow(#db);
if (window) window.root.ns.updateList();
}
function openContactsDB() {
openSingleWindow({
url: "contactsdb.htm",
caption: CommonNative.GetTranslation("Contacts database"),
detach: true,
uniqueid: #db,
alignment: 5,
width: 850,
height: 500
});
}
function openAbout() {
openSingleWindow({
url: "about.htm",
caption: "About",
detach: true,
uniqueid: #about,
alignment: 5,
width: 310,
height: 265
});
}
function openHistorySearch(uid = null, displayed = null) {
var (px, py, dw, dh) = view.screenBox(#frame, #rectw);
var window = openSingleWindow({
url: "search.htm",
caption: "History search",
detach: true,
uniqueid: #search,
alignment: 5,
width: dw / 3,
height: dh / 1.5
});
if (window) window.root.ns.refreshState({
UID: uid,
Display: displayed,
RowID: -1
});
}
function openOutbox() {
var (px, py, dw, dh) = view.screenBox(#frame, #rectw);
openSingleWindow({
url: "outbox.htm",
caption: "Outbox",
detach: true,
uniqueid: #outbox,
alignment: 5,
width: dw / 2.5,
height: dh / 2.2
});
}
function updateOutbox() {
var window = findWindow(#outbox);
if (window) {
window.root.ns.updateList(true);
window.root.ns.updateText();
}
}
function openUpdater() {
openSingleWindow({
url: "updater.htm",
caption: CommonNative.GetTranslation("Check for updates"),
detach: true,
uniqueid: #updater,
alignment: 5
});
}
function openLangs(langs) {
return openSingleWindow({
url: "langs.htm",
caption: CommonNative.GetTranslation("Select a language"),
uniqueid: #langs,
dialog: true;
alignment: 5,
width: 450,
height: 310,
params: {
langs: langs
}
});
}
function openUINList(caption, btn, options, uid = "") {
options = options ?? [];
return openSingleWindow({
url: "uinlist.htm",
caption: "Select contacts",
uniqueid: #uinlist,
dialog: true,
alignment: 5,
width: 250,
height: options.indexOf(#sco_predefined) >= 0 ? 500 : 400,
params: {
caption: CommonNative.GetTranslation(caption),
btn: CommonNative.GetTranslation(btn),
options: options,
uid: uid
}
});
}
function updateUINList(record) {
var window = findWindow(#uinlist);
if (window) window.root.ns.updateContact(uin, status);
}
function openTextWindow(id, title, body, wrap = true, images = [], formicon = null) {
var (px, py, dw, dh) = view.screenBox(#frame, #rectw);
openSingleWindow({
url: "window.htm",
caption: title,
detach: true,
cascade: true,
translate: false,
uniqueid: "message:" + id,
alignment: 7,
width: dw/2.5,
height: dh/2.5,
params: {
body: body,
wrap: wrap,
images: images,
formicon: formicon,
}
});
}
function openTextEdit(text) {
var (px, py, dw, dh) = view.screenBox(#frame, #rectw);
return openSingleWindow({
url: "textedit.htm",
caption: "Edit message",
dialog: true,
uniqueid: "message:" + id,
alignment: 5,
width: dw/4,
height: dh/4,
params: {
text: text
}
});
}
function openPrefs(page = '', full = true) {
var (px, py, dw, dh) = view.screenBox(#frame, #rectw);
var window = openSingleWindow({
url: "preferences.htm",
caption: "Preferences",
hidden: true,
detach: true,
uniqueid: #prefs,
alignment: 5,
width: dw / 2.2,
height: dh / 2.2
});
window.root.ns.setViewMode(page, full);
}
function closeChildWindows() {
for (var window in View.all)
if (window.uniqueid != #main && window.uniqueid != #chat && window.uniqueid != #users) window.close();
}
// function autosizeWindow() {
// self.post(:{
// var (x, y, w, h) = view.box(#rectw, #client, #screen);
// view.windowMove(x, y, w, $(body).box(#height, #margin), true);
// });
// }
// function coordScreenToView(x, y) {
// var (vx, vy) = view.box(#position, #client, #screen);
// x -= vx;
// y -= vy;
// return (x, y);
// }
function coordViewToScreen(x, y) {
var (vx, vy) = view.box(#position, #client, #screen);
x += vx;
y += vy;
return (x, y);
}
function getScreenFromCoord(x, y) {
for (var scr in view.screens) {
var (x1, y1, x2, y2) = view.screenBox(scr, #frame, #rect);
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) return scr;
}
return view.screen;
}
function getPopupPosition(x, y, size, hgap = 0, vgap = 0) {
var (sx, sy, sw, sh) = view.screenBox(#frame, #rectw);
var (x2, y2) = coordViewToScreen(x, y);
var overw = x2 + size > sx + sw;
var overh = y2 + size > sy + sh;
if (overw && overh)
return (3, x - hgap, y - vgap);
else if (overw)
return (9, x - hgap, y + vgap * 2);
else if (overh)
return (1, x + hgap, y - vgap);
else
return (7, x + hgap, y + vgap * 2);
}
var hint = self.$append(<popup id="hint"></popup>),
hintAncor = null,
hintData = null,
hintX = -1,
hintY = -1;
function prepareHint() {
function checkField(field) {
return field != "" ? <b>{field}</b> : {CommonNative.GetTranslation("Unknown")}>;
}
if (hintData instanceof String) hintData = CommonNative.GetContactData(hintData);
if (hintData.kind == NODE_GROUP && cldata) {
var total = cldata.getTotalGroupCount(hintData.group);
var onoffline = [];
if (CommonNative.IsOnline()) {
var online = cldata.getGroupCount(hintData.group, 0);
var offline = cldata.getGroupCount(hintData.group, 1) + cldata.getGroupCount(hintData.group, 4);
var unknown = cldata.getGroupCount(hintData.group, 2) + cldata.getGroupCount(hintData.group, 3);
onoffline.push(<div key="hintonline">{CommonNative.GetTranslation("Online")}: <b>{online}</b></div>);
onoffline.push(<div key="hintoffline">{CommonNative.GetTranslation("Offline")}: <b>{offline}</b></div>);
onoffline.push(<div key="hintunknown">{CommonNative.GetTranslation("Unknown")}: <b>{unknown}</b></div>);
}
hint.merge(<popup id="hint">
<div key="hinttotal">{CommonNative.GetTranslation("Total")}: <b>{total}</b></div>
{onoffline}
</popup>);
return;
}
if (hintData.kind != NODE_CONTACT) return;
var texts = {
hintstatusmsg: "Message",
hintidle: "Idle time",
hintimportant: "Important",
hintofficial: "Official contact",
hintbot: "Bot contact",
hintbirth: "Birthday",
hintgroup: "Group",
hintnoclient: "Client was closed",
hintclientdesc: "Client",
hintclientonline: "Online since",
hintclientoffline: "Last time seen online",
hintignored: "Being ignored",
hintauth: "Authorization required",
hintstatus: "Status",
hintxstatus: "XStatus",
hintnick: "Nick",
hintfirst: "First name",
hintlast: "Last name"
};
var ttexts = CommonNative.GetTranslations(texts);
var desc = [];
if (hintData.status.desc != "")
desc = <div key="hintstatusmsg">{ttexts["hintstatusmsg"]}: <span class="limited"><b>{hintData.status.desc}</b></span></div>;
var idle = [];
var idleTime = CommonNative.GetContactIdle(hintData.uid);
if (idleTime > 0)
idle = <div key="hintidle">{ttexts["hintidle"]}: <b>{String.printf("%d:%02d", (idleTime % 3600) / 60, idleTime % 60)}</b></div>;
var important = [];
var importantText = CommonNative.GetContactImportant(hintData.uid, false);
if (importantText != "")
important = <div key="hintimportant">{ttexts["hintimportant"]}: <span class="limited"><b>{importantText}</b></span></div>;
var importantLocal = [];
importantText = CommonNative.GetContactImportant(hintData.uid, true);
if (importantText != "")
importantLocal = <div key="hintimportantlocal">{ttexts["hintimportant"]}: <span class="limited"><b>{importantText}</b></span></div>;
var official = [];
if (hintData.status.official)
official = <div key="hintofficial"><b>{ttexts["hintofficial"]}</b></div>;
var bot = [];
if (hintData.status.bot)
bot = <div key="hintbot"><b>{ttexts["hintbot"]}</b></div>;
var birth = [];
if (hintData.birthLocal != '')
birth = <div key="hintbirth">{ttexts["hintbirth"]}: <b>{hintData.birthLocal}</b></div>;
// else if (hintData.birth != '')
// birth =
{ttexts["hintbirth"]}: {hintData.birth}
;
var group = [];
var groupName = CommonNative.GetGroupName(hintData.group);
if (groupName != "")
group = <div key="hintgroup">{ttexts["hintgroup"]}: <b>{groupName}</b></div>;
var noClient = [];
if (hintData.noClient)
noClient = <div key="hintnoclient">{ttexts["hintnoclient"]}: <b>{hintData.clientClosed}</b></div>;
var client = [];
if (hintData.status.code != 1 && hintData.status.code != 2) { // is online
if (hintData.clientDesc != "")
client.push(<div key="hintclientdesc">{ttexts["hintclientdesc"]}: <b>{hintData.clientDesc}</b></div>);
if (hintData.onlineSince != "")
client.push(<div key="hintclientonline">{ttexts["hintclientonline"]}: <b>{hintData.onlineSince}</b></div>);
} else {
if (hintData.lastTimeSeenOnline != "")
client.push(<div key="hintclientoffline">{ttexts["hintclientoffline"]}: <b>{hintData.lastTimeSeenOnline}</b></div>);
}
var ignored = [];
var isIgnored = CommonNative.GetContactIgnored(hintData.uid);
if (isIgnored)
ignored = <div key="hintignored"><b>{ttexts["hintignored"]}</b></div>;
var needAuth = [];
if (hintData.needAuth)
needAuth = <div key="hintauth"><b>{ttexts["hintauth"]}</b></div>;
var avatar = [];
if (View.commonSettings.supportAvatars && View.commonSettings.avatarShowInHint && hintData.hasAvatar)
avatar = <div key="hintavatar" class="hintheader2"><img src={String.$(miniavatar:{hintData.uid})} /></div>;
var xstatus = [];
var xstatustext = [];
if (hintData.xstatus.status != "") {
xstatus = <span key="xstatus" class="xstatus">{hintData.xstatus.status}</span>;
xstatustext = <div key="hintxstatus">{ttexts["hintxstatus"]}: <b>{hintData.xstatus.text}</b></div>
}
hint.merge(<popup id="hint">
<div class="hintheader">
<div class="hintheader1">
<div><div id="hinticon"></div>{xstatus}<span>UIN </span><span key="hintuin"><b>{hintData.uid2show}</b></span></div>
<div key="hintstatus">{ttexts["hintstatus"]}: <b>{hintData.status.name}</b></div>
{xstatustext}
</div>
{avatar}
</div>
{desc}
{idle}
<hr/>
{important}
{importantLocal}
{official}
{bot}
<div key="hintnick">{ttexts["hintnick"]}: {checkField(hintData.nick)}</div>
<div key="hintfirst">{ttexts["hintfirst"]}: {checkField(hintData.first)}</div>
<div key="hintlast">{ttexts["hintlast"]}: {checkField(hintData.last)}</div>
{birth}
{group}
{noClient}
{client}
{ignored}
{needAuth}
</popup>);
hint.$(#hinticon).applySprite(hintData.status.statusimg);
hint.$(#hinticon).update();
}
function showHintFunc() {
if (!hintAncor || !hintAncor.tag || self.state.ownspopup) return;
if (self.view.uniqueid != #main) { // check for menu in main
var main = findWindow(#main);
if (main && main.root.state.ownspopup) return;
}
var gap = 0;
if (hintX == -1 && hintY == -1) {
(hintX, hintY) = view.cursorLocation();
gap = self.toPixels(10dip)
}
prepareHint();
var pos = 7;
if (hintData.kind == NODE_CONTACT) {
(pos, hintX, hintY) = getPopupPosition(hintX, hintY, self.toPixels(200dip), gap, gap);
} else {
hintX += gap;
hintY += gap;
}
hintAncor.popup(hint, pos, hintX, hintY);
}
function showHint(ancor, data, x = -1, y = -1) {
self.timer(0, hideHint);
var wasPresent = hint.state.popup;
hideHint();
hintAncor = ancor;
hintData = data;
hintX = x;
hintY = y;
var delay = wasPresent ? 100 : 1000;
self.timer(delay, showHintFunc);
}
function hideHint() {
self.timer(0, showHintFunc);
hintX = -1;
hintY = -1;
hint.closePopup();
hint.update();
}
function showSelectPopup(el) {
var cur = el.$(option:current);
if (!cur) cur = el.$(option);
if (!cur) return;
el.popup(
el.$(popup),
el.box(#left, #border, #root),
el.box(#top, #border, #root) - el.$(popup).style#padding-top
- (cur.style#line-height + cur.style#padding-top + cur.style#padding-bottom) * cur.index - 1
);
el.$(popup).state.focus = true;
}
function initUWPSelect(editable = false) {
var body = $(body);
body.on("~keydown", "select:not([type]):not([default])", :e {
if (e.target.tag == "select" &&
(e.keyCode == Event.VK_RETURN || e.keyCode == Event.VK_SPACE)) {
showSelectPopup(this);
return true;
}
});
body.on("~mousedown", "select:not([type]):not([default])", :e {
if (editable && e.target.tag == "caption") return false;
if (e.target.tag !== "option") return true;
});
body.on("~mouseup", "select:not([type]):not([default])", :e {
if (editable && e.target.tag == "caption") return false;
if (e.target.tag !== "option") {
showSelectPopup(this);
return true;
} else {
this.$(popup).closePopup();
}
});
body.subscribe(:e {
if (e.target.$p(select:not([type]):not([default]))) return true;
}, Event.BEHAVIOR_EVENT, Event.BUTTON_PRESS | Event.SINKING);
}
function cubicOut(t, b = 0.0, c = 1.0, d = 1.0) {
return c*((t=t/d-1)*t*t + 1) + b;
}
function String.toLocalPath() {
return URL.toPath(this).replace("/", "\\");
}
function Element.setVisible(vis, update = true) {
this.style#display = vis ? undefined : "none";
if (update) this.update();
}
function Element.reloadImage(url, cache = true) {
var target = this.tag ? this.view.root : findWindow(#chat).root;
if (target && url)
target.loadImage(url, :image {
target.bindImage(url, image);
}, cache);
}
function Element.applySprite(pic, cat = #theme) {
if (cat == #plugin) this.reloadImage("pluginpic:" + pic["name"], false);
if (pic) this.style.set({
background-image: [url: (cat == #plugin ? "pluginpic:" : "themepic:") + pic["name"]],
background-position: [px(pic["x"]), px(pic["y"])],
width: px(pic["width"]),
height: px(pic["height"])
});
}
function Element.clearSprite() {
this.style.set({
background-image: "none",
width: "auto",
height: "auto"
});
}
function makeSpriteStyle(pic) {
return {
background-image: [url: "themepic:" + pic["name"]],
background-position: [px(pic["x"]), px(pic["y"])],
width: px(pic["width"]),
height: px(pic["height"])
}
}
function Function.throttle(milliseconds, options = {}) {
milliseconds = milliseconds.toInteger();
var context, args, result;
var running = false;
var previous = options.leading === false ? 0 : Date.ticks() - milliseconds - 1;
var func = this;
function later() {
previous = options.leading === false ? 0 : Date.ticks();
running = false;
result = func.apply(context, args);
};
return function(arguments..) {
var now = Date.ticks();
if (!previous && options.leading === false) previous = now;
var remaining = milliseconds - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
self.timer(0,later,true);
running = false;
previous = now;
result = func.apply(context, args);
} else if (!running && options.trailing !== false) {
running = true;
self.timer(remaining, later,true);
}
return result;
};
}
</script>