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.
312 lines
8.5 KiB
HTML
312 lines
8.5 KiB
HTML
<html window-icon="themepicsingle:request.contact.list">
|
|
<head>
|
|
<include src="common.htm" />
|
|
<style src="uinlist.css" />
|
|
<style id="dyncss" />
|
|
<script>
|
|
const VTable = importModule("vlist.mjs").VTable;
|
|
|
|
view.uniqueid = "uinlist";
|
|
view.isDialog = true;
|
|
view.minSize = [200, 200];
|
|
view.caption = view.parameters.caption;
|
|
CommonNative.ShowTaskbarButton(self);
|
|
translateWindow("span");
|
|
|
|
var contacts,
|
|
main = $("#main"),
|
|
uinmenu = $("#uinmenu"),
|
|
action = $("#action"),
|
|
selectall = $("#selectall"),
|
|
deselectall = $("#deselectall"),
|
|
add = $("#add"),
|
|
sub = $("#sub"),
|
|
lists = $("#lists"),
|
|
|
|
cntChecked = _("Contacts selected"),
|
|
data = [];
|
|
|
|
function flattenList(items) {
|
|
var out = [];
|
|
function scanItems(items) {
|
|
for (let item of items) {
|
|
out.push(item);
|
|
if (item.expanded && item.items && item.items.length > 0) scanItems(item.items);
|
|
}
|
|
}
|
|
scanItems(items);
|
|
return out;
|
|
}
|
|
|
|
function recordViewTree(record, isCurrent, isSelected, isChecked) {
|
|
const icon = record.items ? [<div class="icon"></div>] : [<div auto pic={record.status}></div>];
|
|
var cls = record.items ? "node" : "leaf";
|
|
if (isGrouped() && record.kind == 1 && record.groupId > 0) cls += " grouped";
|
|
return <tr key={record.key} class={cls} state-current={isCurrent} state-checked={isChecked} state-expanded={record.expanded} state-collapsed={!record.expanded}>
|
|
<td>{icon}<span>{record.name}</span></td>
|
|
</tr>;
|
|
}
|
|
|
|
function updateContacts() {
|
|
contacts.componentUpdate({ recordset: flattenList(data) });
|
|
}
|
|
|
|
function updateCount() {
|
|
var total = 0,
|
|
checked = 0;
|
|
|
|
for (let record of data)
|
|
total += record.kind == 1 ? 1 : (record.items ? record.items.length : 0);
|
|
|
|
if (contacts.checkedItems)
|
|
for (let record of Object.values(contacts.checkedItems))
|
|
if (record.kind == 1) checked++;
|
|
|
|
$("#count").html = cntChecked + ": " + checked + " / " + total;
|
|
}
|
|
|
|
function updateLists() {
|
|
var data = CommonNative.GetUINLists();
|
|
var val = lists.value;
|
|
var exists = false;
|
|
lists.clear();
|
|
for (let item of data) {
|
|
if (!exists && item == val) exists = true;
|
|
lists.append(<option value={item}>{item}</option>);
|
|
}
|
|
if (exists) lists.value = val;
|
|
}
|
|
|
|
function toggleNode(node, force = "none") {
|
|
const key = node.attr["key"];
|
|
var group = contacts.recordset.find((record) => record.key == key);
|
|
if (!group) return;
|
|
if (force == "collapse") group.expanded = false;
|
|
else if (force == "expand") group.expanded = true;
|
|
else group.expanded = !group.expanded;
|
|
updateContacts();
|
|
}
|
|
|
|
function isMulti() {
|
|
return view.parameters.options.indexOf("sco_multi") >= 0;
|
|
}
|
|
|
|
function isGrouped() {
|
|
return view.parameters.options.indexOf("sco_groups") >= 0;
|
|
}
|
|
|
|
function isPredefined() {
|
|
return view.parameters.options.indexOf("sco_predefined") >= 0;
|
|
}
|
|
|
|
var groupClosed = getSpriteData("close.group");
|
|
var groupOpened = getSpriteData("open.group");
|
|
|
|
var dyncss = $("style#dyncss");
|
|
dyncss.text = makeSpriteStyle(".contacts > tbody > tr.node:collapsed > td:first-child > .icon", groupClosed);
|
|
dyncss.text += makeSpriteStyle(".contacts > tbody > tr.node:expanded > td:first-child > .icon", groupOpened);
|
|
|
|
action.$("span").text = view.parameters.btn;
|
|
|
|
data = CommonNative.GetContacts(view.parameters.options);
|
|
|
|
var params = {
|
|
recordview: recordViewTree,
|
|
recordset: flattenList(data)
|
|
};
|
|
|
|
var multi = isMulti();
|
|
if (multi) params.multicheck = true;
|
|
$("#count").setVisible(multi);
|
|
$("#selectbtns").setVisible(multi);
|
|
|
|
var predefined = isPredefined();
|
|
if (predefined) updateLists();
|
|
$("#predefined").setVisible(predefined);
|
|
lists.setVisible(predefined);
|
|
lists.on("change", (e) => {
|
|
if (e.eventPhase === 2) updateButton();
|
|
});
|
|
|
|
function updateButton() {
|
|
add.state.disabled = lists.value == "";
|
|
sub.state.disabled = lists.value == "";
|
|
}
|
|
updateButton();
|
|
|
|
main.append(<VTable class="contacts" {params}>
|
|
<columns>
|
|
<th>Name</th>
|
|
</columns>
|
|
</VTable>);
|
|
contacts = $(".contacts");
|
|
contacts.init(18);
|
|
|
|
if (view.parameters.uid !== "" && multi) {
|
|
var contact = contacts.recordset.find((record) => record.UID == view.parameters.uid);
|
|
if (contact) contacts.vtbody.toggleCheck(contact);
|
|
}
|
|
|
|
contacts.on("currentchange", (e) => {
|
|
updateCount();
|
|
}).on("keydown", (e) => {
|
|
var target = this.$(":current");
|
|
if (e.keyCode == Event.VK_SPACE) {
|
|
contacts.vtbody.checkCurrent();
|
|
} else if (e.keyCode == Event.VK_RETURN) {
|
|
if (target.classList.contains("node")) toggleNode(target);
|
|
else if (!isMulti() && e.target.classList.contains("leaf")) returnList();
|
|
return true;
|
|
} else if (e.keyCode == Event.VK_LEFT) {
|
|
toggleNode(target, "collapse");
|
|
return true;
|
|
} else if (e.keyCode == Event.VK_RIGHT) {
|
|
toggleNode(target, "expand");
|
|
return true;
|
|
}
|
|
return false;
|
|
})
|
|
|
|
contacts.vtbody.on("contextmenu", (e) => {
|
|
var show = contacts.vtbody.value && contacts.vtbody.value.kind !== 0;
|
|
if (show) e.source = uinmenu;
|
|
return show;
|
|
});
|
|
|
|
updateCount();
|
|
|
|
function getChecked() {
|
|
var UINs = [];
|
|
if (isMulti()) {
|
|
for (let record of contacts.recordset)
|
|
if (record.kind == 1 && contacts.vtbody.isChecked(record.key))
|
|
UINs.push(record.UID);
|
|
} else if (contacts.vtbody.value !== null) {
|
|
UINs.push(contacts.vtbody.value.UID);
|
|
}
|
|
return UINs;
|
|
}
|
|
|
|
function returnList() {
|
|
view.close(getChecked());
|
|
}
|
|
|
|
action.on("click", (e) => {
|
|
returnList();
|
|
});
|
|
|
|
selectall.on("click", (e) => {
|
|
contacts.vtbody.checkAll();
|
|
updateCount();
|
|
});
|
|
|
|
deselectall.on("click", (e) => {
|
|
contacts.vtbody.uncheckAll();
|
|
updateCount();
|
|
});
|
|
|
|
function applyCurrentList(action) {
|
|
if (lists.value == "") return;
|
|
var data = CommonNative.GetUINList(lists.value);
|
|
if (!data) data = [];
|
|
if (data.length == 0) return;
|
|
|
|
var records = contacts.checkedItems;
|
|
for (let item of data) {
|
|
var contact = contacts.recordset.find((record) => record.UID == item);
|
|
if (contact)
|
|
if (action == "add")
|
|
records[contact.key] = contact;
|
|
else if (action == "sub")
|
|
delete records[contact.key];
|
|
}
|
|
contacts.checkedItems = records;
|
|
contacts.componentUpdate();
|
|
|
|
updateCount();
|
|
}
|
|
|
|
add.on("click", (e) => {
|
|
applyCurrentList("add");
|
|
});
|
|
|
|
sub.on("click", (e) => {
|
|
applyCurrentList("sub");
|
|
});
|
|
|
|
$("#save").on("click", (e) => {
|
|
if (lists.value == "") {
|
|
showAlert("warning", "You need to enter a name for this uin-list");
|
|
return;
|
|
}
|
|
var checked = getChecked();
|
|
if (checked.length == 0) {
|
|
showAlert("warning", "Select at least one contact");
|
|
return;
|
|
}
|
|
if (CommonNative.SaveUINList(lists.value, checked) === true) updateLists();
|
|
});
|
|
|
|
$("#del").on("click", (e) => {
|
|
if (lists.value == "") return;
|
|
var res = CommonNative.DeleteUINList(lists.value);
|
|
if (res) {
|
|
lists.value = "";
|
|
updateLists();
|
|
}
|
|
});
|
|
|
|
function viewInfoCurrent() {
|
|
openViewInfo(contacts.vtbody.value.UID, contacts.vtbody.value.name);
|
|
}
|
|
|
|
function openChatCurrent() {
|
|
View.share.MainNative.OpenChatWith(contacts.vtbody.value.UID);
|
|
}
|
|
|
|
setMenuListener(uinmenu, function() {
|
|
if (contacts.vtbody.value && contacts.vtbody.value.UID && contacts.vtbody.value.UID != "")
|
|
switch (this.id) {
|
|
case "mviewinfo": viewInfoCurrent(); break
|
|
case "mopenchat": openChatCurrent(); break;
|
|
}
|
|
});
|
|
|
|
document.on("mousedown", "div.icon", (e, el) => {
|
|
toggleNode(el.$p("tr"));
|
|
return true;
|
|
}).on("dblclick", "tr.node", (e, el) => {
|
|
if (e.mainButton) toggleNode(el);
|
|
}).on("dblclick", "tr.leaf", (e) => {
|
|
if (e.mainButton && !isMulti()) returnList();
|
|
}).on("closerequest", function(e){
|
|
if (e.reason == Event.REASON_BY_CHROME) {
|
|
view.close([]);
|
|
return false;
|
|
}
|
|
}).on("keydown", (e) => {
|
|
if (e.keyCode == Event.VK_ESCAPE || (e.ctrlKey && e.keyCode == Event.VK_W)) view.close([]);
|
|
});
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="main"></div>
|
|
<div id="count"></div>
|
|
<select uwp editable id="lists" as="string"></select>
|
|
<div class="buttonpane" id="predefined">
|
|
<button uwp id="add" title="Add the uin-list to the selected"><span>+</span></button>
|
|
<button uwp id="sub" title="Remove the uin-list from the selected"><span>-</span></button>
|
|
<button uwp id="save" title="Save selected as uin-list"><span>💾</span></button>
|
|
<button uwp id="del" title="Delete this uin-list"><span>🗑</span></button>
|
|
</div>
|
|
<div class="buttonpane" id="selectbtns">
|
|
<button uwp id="selectall"><span>Select all</span></button>
|
|
<button uwp id="deselectall"><span>Deselect all</span></button>
|
|
</div>
|
|
<button uwp id="action"><span></span></button>
|
|
<menu id="uinmenu" class="context custom">
|
|
<li id="mviewinfo"><div auto pic="info"></div><span>View info</span></li>
|
|
<li id="mopenchat"><div auto pic="msg"></div><span>Open chat</span></li>
|
|
</menu>
|
|
</body>
|
|
</html> |