This commit is contained in:
Mirco Wittrien 2019-11-06 23:57:43 +01:00
parent 5c318cb3fb
commit d6212372db
3 changed files with 226 additions and 299 deletions

View File

@ -837,7 +837,7 @@ var BDFDB = {
return array;
};
BDFDB.ArrayUtils.getAllIndexes = function (array, value) {
if (!BDFDB.ArrayUtils.is(array)) return [];
if (!BDFDB.ArrayUtils.is(array) && typeof array != "string") return [];
var indexes = [], index = -1;
while ((index = array.indexOf(value, index + 1)) !== -1) indexes.push(index);
return indexes;
@ -2801,7 +2801,7 @@ var BDFDB = {
let template = document.createElement("template");
try {template.innerHTML = html.replace(/(?<!pre)>[\t\r\n]+<(?!pre)/g, "><");}
catch (err) {template.innerHTML = html.replace(/>[\t\r\n]+<(?!pre)/g, "><");}
if (template.content.childElementCount == 1) return template.content.firstElementChild;
if (template.content.childNodes.length == 1) return template.content.firstElementChild;
else {
var wrapper = document.createElement("span");
var nodes = Array.from(template.content.childNodes);

File diff suppressed because one or more lines are too long

View File

@ -3,120 +3,31 @@
class RepoControls {
getName () {return "RepoControls";}
getVersion () {return "1.3.1";}
getVersion () {return "1.3.2";}
getAuthor () {return "DevilBro";}
getDescription () {return "Lets you sort and filter your list of downloaded Themes and Plugins.";}
getDescription () {return "Lets you sort and filter your list of downloaded Themes and Plugins. <span style='color: red';'>test</span>";}
constructor () {
this.changelog = {
"fixed":[["Light Theme Update","Fixed bugs for the Light Theme Update, which broke 99% of my plugins"]]
"improved":[["New Library Structure & React","Restructured my Library and switched to React rendering instead of DOM manipulation"]]
};
this.patchModules = {
"V2C_List":"componentDidMount",
"V2C_PluginCard": ["componentDidMount","componentDidUpdate"],
"V2C_ThemeCard": ["componentDidMount","componentDidUpdate"]
V2C_List: "render",
V2C_PluginCard: "render",
V2C_ThemeCard: "render",
V2C_ContentColumn: "render"
};
}
initConstructor () {
this.sortings = {
sort: {
name: "Name",
author: "Author",
version: "Version",
description: "Description",
enabled: "Enabled",
adddate: "Added",
moddate: "Modified"
},
order: {
asc: "Ascending",
desc: "Descending"
}
};
this.repoControlsMarkup =
`<div class="repo-controls ${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.marginbottom8}" style="flex: 1 1 auto;">
<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCN.nowrap}" style="flex: 0 1 auto;">
<button action="add" type="button" class="${BDFDB.disCNS.flexchild + BDFDB.disCNS.button + BDFDB.disCNS.buttonlookfilled + BDFDB.disCNS.buttoncolorgreen + BDFDB.disCNS.buttonsizeicon + BDFDB.disCN.buttongrow} btn-enableall" style="flex: 0 0 auto;">
<div class="${BDFDB.disCN.buttoncontents}">Enable All</div>
</button>
<button action="add" type="button" class="${BDFDB.disCNS.flexchild + BDFDB.disCNS.button + BDFDB.disCNS.buttonlookfilled + BDFDB.disCNS.buttoncolorred + BDFDB.disCNS.buttonsizeicon + BDFDB.disCN.buttongrow} btn-disableall" style="flex: 0 0 auto;">
<div class="${BDFDB.disCN.buttoncontents}">Disable All</div>
</button>
</div>
<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.quickselect}" style="flex: 0 1 auto;">
<div class="${BDFDB.disCNS.flex2 + BDFDB.disCN.quickselectlabel} style="flex: 0 0 auto;"">Sort by:</div>
<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.quickselectclick} sort-filter" style="flex: 0 0 auto;">
<div option="${Object.keys(this.sortings.sort)[0]}" class="${BDFDB.disCN.quickselectvalue}">${this.sortings.sort[Object.keys(this.sortings.sort)[0]]}</div>
<div class="${BDFDB.disCN.quickselectarrow}"></div>
</div>
</div>
<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.quickselect}" style="flex: 0 1 auto;">
<div class="${BDFDB.disCNS.flex2 + BDFDB.disCN.quickselectlabel} style="flex: 0 0 auto;"">Order:</div>
<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.quickselectclick} order-filter" style="flex: 0 0 auto;">
<div option="${Object.keys(this.sortings.order)[0]}" class="${BDFDB.disCN.quickselectvalue}">${this.sortings.order[Object.keys(this.sortings.order)[0]]}</div>
<div class="${BDFDB.disCN.quickselectarrow}"></div>
</div>
</div>
</div>`;
this.sortPopoutMarkup =
`<div class="${BDFDB.disCNS.popout + BDFDB.disCNS.popoutbottomright + BDFDB.disCN.popoutnoshadow} repocontrols-sort-popout" style="position: fixed; z-index: 1100; visibility: visible; transform: translateX(-100%) translateY(0%) translateZ(0px);">
<div>
<div class="${BDFDB.disCN.contextmenu} BDFDB-quickSelectPopout">
<div class="${BDFDB.disCN.contextmenuitemgroup}">
${Object.keys(this.sortings.sort).map((key, i) => `<div option="${key}" class="${BDFDB.disCNS.contextmenuitem + BDFDB.disCN.contextmenuitemclickable}">${this.sortings.sort[key]}</div>`).join("")}
</div>
</div>
</div>
</div>`;
this.orderPopoutMarkup =
`<div class="${BDFDB.disCNS.popout + BDFDB.disCNS.popoutbottomright + BDFDB.disCN.popoutnoshadow} repocontrols-order-popout" style="position: fixed; z-index: 1100; visibility: visible; transform: translateX(-100%) translateY(0%) translateZ(0px);">
<div>
<div class="${BDFDB.disCN.contextmenu} BDFDB-quickSelectPopout">
<div class="${BDFDB.disCN.contextmenuitemgroup}">
${Object.keys(this.sortings.order).map((key, i) => `<div option="${key}" class="${BDFDB.disCNS.contextmenuitem + BDFDB.disCN.contextmenuitemclickable}">${this.sortings.order[key]}</div>`).join("")}
</div>
</div>
</div>
</div>`;
this.editButtonMarkup =
`<svg class="editIcon" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-150 -55 620 620">
<g fill="currentColor" fill-rule="evenodd">
<path d="M496.093,189.613c-18.643-15.674-47.168-13.807-63.354,5.493l-9.727,11.508l68.945,57.849l9.288-11.466 C517.22,233.997,515.199,205.621,496.093,189.613z"/>
<path d="M301.375,350.534l-5.131,6.072c-4.453,5.332-7.661,11.704-9.272,18.457l-13.945,58.359 c-1.318,5.522,0.601,11.323,4.951,14.971c4.234,3.558,10.206,4.591,15.601,2.285l55.063-23.877 c6.372-2.769,12.085-7.031,16.538-12.319l5.149-6.092L301.375,350.534z"/>
<polygon points="403.656,229.517 320.733,327.631 389.683,385.487 472.601,287.366"/>
<path d="M376.02,66.504l-56.982-54.141c-5.387-5.107-12.014-8.115-18.999-10.069V90h89.052 C387.23,81.09,382.69,72.836,376.02,66.504z"/>
<path d="M257.792,368.091c2.681-11.221,8.027-21.841,15.439-30.718l116.807-138.214V120h-105c-8.291,0-15-6.709-15-15V0h-225 c-24.814,0-45,20.186-45,45v422c0,24.814,20.186,45,45,45h300c24.814,0,45-20.186,45-45v-35.459l-1.948,2.305 c-7.368,8.775-16.875,15.85-27.466,20.465l-55.107,23.892c-15.532,6.707-33.511,4.331-46.816-6.812 c-13.14-11.03-18.838-28.242-14.854-44.941L257.792,368.091z M75.038,90h150c8.291,0,15,6.709,15,15s-6.709,15-15,15h-150 c-8.291,0-15-6.709-15-15S66.747,90,75.038,90z M75.038,181h240c8.291,0,15,6.709,15,15s-6.709,15-15,15h-240 c-8.291,0-15-6.709-15-15S66.747,181,75.038,181z M195.038,391h-120c-8.291,0-15-6.709-15-15c0-8.291,6.709-15,15-15h120 c8.291,0,15,6.709,15,15C210.038,384.291,203.329,391,195.038,391z M75.038,301c-8.291,0-15-6.709-15-15c0-8.291,6.709-15,15-15 h180c8.291,0,15,6.709,15,15c0,8.291-6.709,15-15,15H75.038z"/>
</g>
</svg>`;
this.deleteButtonMarkup =
`<svg class="trashIcon" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<g fill="currentColor" transform="translate(2,1.5)">
<path d="M 18.012, 0.648 H 12.98 C 12.944, 0.284, 12.637, 0, 12.264, 0 H 8.136 c -0.373, 0 -0.68, 0.284 -0.716, 0.648 H 2.389 c -0.398, 0 -0.72, 0.322 -0.72, 0.72 v 1.368 c 0, 0.398, 0.322, 0.72, 0.72, 0.72 h 15.623 c 0.398, 0, 0.72 -0.322, 0.72 -0.72 V 1.368 C 18.731, 0.97, 18.409, 0.648, 18.012, 0.648 z"/>
<path d="M 3.178, 4.839 v 14.841 c 0, 0.397, 0.322, 0.72, 0.72, 0.72 h 12.604 c 0.398, 0, 0.72 -0.322, 0.72 -0.72 V 4.839 H 3.178 z M 8.449, 15.978 c 0, 0.438 -0.355, 0.794 -0.794, 0.794 c -0.438, 0 -0.794 -0.355 -0.794 -0.794 V 8.109 c 0 -0.438, 0.355 -0.794, 0.794 -0.794 c 0.438, 0, 0.794, 0.355, 0.794, 0.794 V 15.978 z M 13.538, 15.978 c 0, 0.438 -0.355, 0.794 -0.794, 0.794 s -0.794 -0.355 -0.794 -0.794 V 8.109 c 0 -0.438, 0.355 -0.794, 0.794 -0.794 c 0.438, 0, 0.794, 0.355, 0.794, 0.794 V 15.978 z"/>
</g>
</svg>`;
this.css = `
#bd-settingspane-container .editIcon,
#bd-settingspane-container .trashIcon {
margin: 0 5px 0 -2px;
cursor: pointer;
vertical-align: top;
color: #72767d;
.RC-button {
margin-right: 5px;
}
${BDFDB.dotCN.themedark} #bd-settingspane-container .editIcon,
${BDFDB.dotCN.themedark} #bd-settingspane-container .trashIcon {
color: #dcddde;
}`;
`;
this.defaults = {
settings: {
@ -125,8 +36,27 @@ class RepoControls {
confirmDelete: {value:true, description:"Asks for your confirmation before deleting a File."}
},
sortings: {
sort: {value:"name"},
order: {value:"asc"}
sort: {
value: "name",
label: "Sortkey:",
values: {
name: "Name",
author: "Author",
version: "Version",
description: "Description",
enabled: "Enabled",
adddate: "Added",
moddate: "Modified"
}
},
order: {
value: "asc",
label: "Order:",
values: {
asc: "Ascending",
desc: "Descending"
}
}
}
};
}
@ -134,17 +64,18 @@ class RepoControls {
getSettingsPanel () {
if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return;
let settings = BDFDB.DataUtils.get(this, "settings");
let settingshtml = `<div class="${this.name}-settings BDFDB-settings"><div class="${BDFDB.disCNS.titledefault + BDFDB.disCNS.titlesize18 + BDFDB.disCNS.height24 + BDFDB.disCNS.weightnormal + BDFDB.disCN.marginbottom8}">${this.name}</div><div class="BDFDB-settings-inner">`;
for (let key in settings) {
settingshtml += `<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.marginbottom8}" style="flex: 1 1 auto;"><h3 class="${BDFDB.disCNS.titledefault + BDFDB.disCNS.marginreset + BDFDB.disCNS.weightmedium + BDFDB.disCNS.titlesize16 + BDFDB.disCNS.height24 + BDFDB.disCN.flexchild}" style="flex: 1 1 auto;">${this.defaults.settings[key].description}</h3><div class="${BDFDB.disCNS.flexchild + BDFDB.disCNS.switchenabled + BDFDB.disCNS.switch + BDFDB.disCNS.switchvalue + BDFDB.disCNS.switchsizedefault + BDFDB.disCNS.switchsize + BDFDB.disCN.switchthemedefault}" style="flex: 0 0 auto;"><input type="checkbox" value="settings ${key}" class="${BDFDB.disCNS.switchinnerenabled + BDFDB.disCN.switchinner} settings-switch"${settings[key] ? " checked" : ""}></div></div>`;
}
settingshtml += `</div></div>`;
let settingspanel = BDFDB.DOMUtils.create(settingshtml);
BDFDB.initElements(settingspanel, this);
return settingspanel;
let settingsitems = [];
for (let key in settings) settingsitems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
className: BDFDB.disCN.marginbottom8,
type: "Switch",
plugin: this,
keys: ["settings", key],
label: this.defaults.settings[key].description,
value: settings[key]
}));
return BDFDB.PluginUtils.createSettingsPanel(this, settingsitems);
}
//legacy
@ -175,8 +106,6 @@ class RepoControls {
if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
if (this.started) return;
BDFDB.PluginUtils.init(this);
this.dirs = {theme: BDFDB.BDUtils.getThemesFolder(), plugin: BDFDB.BDUtils.getPluginsFolder()};
BDFDB.ModuleUtils.forceAllUpdates(this);
}
@ -188,19 +117,8 @@ class RepoControls {
if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
this.stopping = true;
BDFDB.DOMUtils.remove(".repo-controls","#bd-settingspane-container .trashIcon");
BDFDB.DOMUtils.removeClassFromDOM("repocontrols-added");
for (let list of document.querySelectorAll(BDFDB.dotCNS._repolist)) {
list.style.removeProperty("display");
list.style.removeProperty("flex-direction");
for (let li of list.querySelectorAll("li")) {
li.style.removeProperty("display");
li.style.removeProperty("order");
var checkbox = li.querySelector(BDFDB.dotCN._repocheckbox);
if (checkbox) checkbox.removeEventListener("change", checkbox.changeRepoControlsListener);
}
}
BDFDB.ModuleUtils.forceAllUpdates(this);
//BDFDB.DOMUtils.removeClassFromDOM("repocontrols-added");
BDFDB.PluginUtils.clear(this);
}
@ -209,191 +127,200 @@ class RepoControls {
// begin of own functions
processV2CList (instance, container, returnvalue) {
if (instance._reactInternalFiber.key) this.addControls(instance._reactInternalFiber.key.split("-")[0], container);
processV2CContentColumn (e) {
let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {name: "V2C_List"});
if (index > -1) {
let list = children[index];
this.injectControls(e.instance, list, children, index, children[index].key.split("-")[0]);
this.sortEntries(null, list);
}
}
processV2CPluginCard (instance, wrapper, returnvalue, methodnames) {
if (wrapper.querySelector(BDFDB.dotCN._reponame)) {
processV2CPluginCard (e) {
this.processV2CThemeCard(e);
}
processV2CThemeCard (e) {
if (!e.instance.props.RCdata) return;
let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {props: [["className", "bda-controls"]]});
if (index > -1) {
let settings = BDFDB.DataUtils.get(this, "settings");
if (instance.props && settings.addDeleteButton) this.addDeleteButton("plugin", wrapper);
if (instance.props && settings.addEditButton) this.addEditButton("plugin", wrapper);
if (methodnames.includes("componentDidUpdate")) this.changeTextToHTML(wrapper, "");
if (settings.addDeleteButton) children[index].props.children.unshift(this.createDeleteButton(e));
if (settings.addEditButton) children[index].props.children.unshift(this.createEditButton(e));
this.highlightSearchKey(e);
}
}
processV2CThemeCard (instance, wrapper, returnvalue, methodnames) {
if (wrapper.querySelector(BDFDB.dotCN._reponame)) {
let settings = BDFDB.DataUtils.get(this, "settings");
if (instance.props && settings.addDeleteButton) this.addDeleteButton("theme", wrapper);
if (instance.props && settings.addEditButton) this.addEditButton("theme", wrapper);
if (methodnames.includes("componentDidUpdate")) this.changeTextToHTML(wrapper, "");
}
}
addEditButton (type, wrapper) {
if (!type || !wrapper || wrapper.querySelector(".editIcon")) return;
let name = wrapper.getAttribute("data-name");
let controls = wrapper.querySelector(BDFDB.dotCN._repocontrols);
if (!name || !controls) return;
let path = global[`bd${type}s`] && global[`bd${type}s`][name] ? BDFDB.LibraryRequires.path.join(this.dirs[type], global[`bd${type}s`][name].filename) : null;
if (!path) return;
let button = BDFDB.DOMUtils.create(this.editButtonMarkup);
button.addEventListener("click", () => {
if (!BDFDB.LibraryRequires.electron.shell.openItem(path)) BDFDB.NotificationUtils.toast(`Unable to open ${type} "${name}".`, {type:"danger"});;
});
button.addEventListener("mouseenter", e => {
BDFDB.TooltipUtils.create(e.currentTarget, `Edit ${type[0].toUpperCase() + type.slice(1)}`, {type:"top",selector:"repocontrols-editicon-tooltip"});
});
controls.insertBefore(button, controls.firstElementChild);
}
addDeleteButton (type, wrapper) {
if (!type || !wrapper || wrapper.querySelector(".trashIcon")) return;
let name = wrapper.getAttribute("data-name");
let controls = wrapper.querySelector(BDFDB.dotCN._repocontrols);
if (!name || !controls) return;
let path = global[`bd${type}s`] && global[`bd${type}s`][name] ? BDFDB.LibraryRequires.path.join(this.dirs[type], global[`bd${type}s`][name].filename) : null;
if (!path) return;
let button = BDFDB.DOMUtils.create(this.deleteButtonMarkup);
button.addEventListener("click", () => {
let deleteFile = () => {
BDFDB.LibraryRequires.fs.unlink(path, (error) => {
if (error) BDFDB.NotificationUtils.toast(`Unable to delete ${type} "${name}".`, {type:"danger"});
else BDFDB.NotificationUtils.toast(`Successfully deleted ${type} "${name}".`, {type:"success"});
});
};
if (!BDFDB.DataUtils.get(this, "settings", "confirmDelete")) deleteFile();
else BDFDB.ModalUtils.confirm(this, `Are you sure you want to delete the ${type} "${name}"?`, () => {
deleteFile();
});
});
button.addEventListener("mouseenter", e => {
BDFDB.TooltipUtils.create(e.currentTarget, `Delete ${type[0].toUpperCase() + type.slice(1)}`, {type:"top",selector:"repocontrols-trashicon-tooltip"});
});
controls.insertBefore(button, controls.firstElementChild);
}
addControls (type, container) {
if (!type || !container) return;
BDFDB.DOMUtils.remove(".repo-controls");
container.style.setProperty("display", "flex", "important");
container.style.setProperty("flex-direction", "column", "important");
injectControls (instance, parent, children, index, type) {
let sortings = BDFDB.DataUtils.get(this, "sortings");
let repocontrols = BDFDB.DOMUtils.create(this.repoControlsMarkup);
repocontrols.insertBefore(BDFDB.createSearchBar("small"), repocontrols.firstElementChild);
BDFDB.initElements(repocontrols, this);
container.parentElement.insertBefore(repocontrols, container);
let sortfilter = repocontrols.querySelector(".sort-filter " + BDFDB.dotCN.quickselectvalue);
sortfilter.setAttribute("option", sortings.sort);
sortfilter.innerText = this.sortings.sort[sortings.sort];
let orderfilter = repocontrols.querySelector(".order-filter " + BDFDB.dotCN.quickselectvalue);
orderfilter.setAttribute("option", sortings.order);
orderfilter.innerText = this.sortings.order[sortings.order];
BDFDB.ListenerUtils.addToChildren(repocontrols, "keyup", BDFDB.dotCN.searchbarinput, () => {
BDFDB.TimeUtils.clear(repocontrols.searchTimeout);
repocontrols.searchTimeout = BDFDB.TimeUtils.timeout(() => {this.sortEntries(container, repocontrols);},1000);
});
BDFDB.ListenerUtils.addToChildren(repocontrols, "click", BDFDB.dotCN.searchbarclear + BDFDB.dotCN.searchbarvisible, () => {
this.sortEntries(container, repocontrols);
});
BDFDB.ListenerUtils.addToChildren(repocontrols, "click", ".btn-enableall", e => {
this.toggleAll(type, container, true);
});
BDFDB.ListenerUtils.addToChildren(repocontrols, "click", ".btn-disableall", e => {
this.toggleAll(type, container, false);
});
BDFDB.ListenerUtils.addToChildren(repocontrols, "click", ".sort-filter", e => {
BDFDB.createSortPopout(e.currentTarget, this.sortPopoutMarkup, () => {
BDFDB.DataUtils.save(sortfilter.getAttribute("option"), this, "sortings", "sort");
this.sortEntries(container, repocontrols);
});
});
BDFDB.ListenerUtils.addToChildren(repocontrols, "click", ".order-filter", e => {
BDFDB.createSortPopout(e.currentTarget, this.orderPopoutMarkup, () => {
BDFDB.DataUtils.save(orderfilter.getAttribute("option"), this, "sortings", "order");
this.sortEntries(container, repocontrols);
});
});
BDFDB.DOMUtils.addClass(container, "repocontrols-added");
container.entries = {};
for (let li of container.children) {
if (li.querySelector(BDFDB.dotCN._reponame)) {
let name = li.querySelector(BDFDB.dotCN._reponame).textContent;
let version = li.querySelector(BDFDB.dotCN._repoversion).textContent;
let author = li.querySelector(BDFDB.dotCN._repoauthor).textContent;
let description = li.querySelector(BDFDB.dotCN._repodescription).textContent;
let enabled = li.querySelector(BDFDB.dotCN._repocheckbox).checked;
let path = global[`bd${type}s`] && global[`bd${type}s`][name] ? BDFDB.LibraryRequires.path.join(this.dirs[type], global[`bd${type}s`][name].filename) : null;
let stats = path ? BDFDB.LibraryRequires.fs.statSync(path) : null;
container.entries[name] = {
search: (name + " " + author + " " + description).toUpperCase(),
origName: name,
name: (name).toUpperCase(),
version: (version).toUpperCase(),
author: (author).toUpperCase(),
description: (description).toUpperCase(),
type: type,
path: path,
adddate: stats ? stats.atime.getTime() : null,
moddate: stats ? stats.mtime.getTime() : null,
enabled: enabled ? 0 : 1
};
}
}
this.sortEntries(container, repocontrols);
this.searchTimeout;
children.splice(index, 0, BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
className: BDFDB.disCN.marginbottom8,
justify: BDFDB.LibraryComponents.Flex.Justify.BETWEEN,
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
children: [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SearchBar, {
onChange: value => {
BDFDB.TimeUtils.clear(this.searchTimeout);
this.searchTimeout = BDFDB.TimeUtils.timeout(_ => {
this.sortEntries(instance, parent, value);
}, 1000);
},
onClear: _ => {
this.sortEntries(instance, parent, "");
}
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
color: BDFDB.LibraryComponents.Button.Colors.GREEN,
size: BDFDB.LibraryComponents.Button.Sizes.MIN,
onClick: _ => {
this.toggleAll(type, instance, true);
},
children: "Enable All"
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
color: BDFDB.LibraryComponents.Button.Colors.RED,
size: BDFDB.LibraryComponents.Button.Sizes.MIN,
onClick: _ => {
this.toggleAll(type, instance, false);
},
children: "Disable All"
}),
].concat(Object.keys(sortings).map(key =>
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
popoutClassName: BDFDB.disCN.contextmenu,
label: this.defaults.sortings[key].label,
value: {
label: this.defaults.sortings[key].values[sortings[key]],
value: sortings[key]
},
options: Object.keys(this.defaults.sortings[key].values).map(valuekey => {return {
label: this.defaults.sortings[key].values[valuekey],
value: valuekey
}}),
onChange: value => {
BDFDB.DataUtils.save(value.value, this, "sortings", key);
this.sortEntries(instance, parent);
}
})
))
}));
}
sortEntries (container, repocontrols) {
if (typeof container.entries != "object") return;
let searchstring = repocontrols.querySelector(BDFDB.dotCN.searchbarinput).value.replace(/[<|>]/g, "").toUpperCase();
sortEntries (instance, parent, searchkey = parent.props.searchkey) {
if (instance) instance = BDFDB.ReactUtils.findOwner(instance, {name: "V2C_List"});
let sortings = BDFDB.DataUtils.get(this, "sortings");
let entries = BDFDB.ObjectUtils.filter(container.entries, entry => {return entry.search.indexOf(searchstring) > -1 ? entry : null;});
entries = BDFDB.ObjectUtils.sort(entries, sortings.sort);
if (sortings.order == "desc") entries = BDFDB.ObjectUtils.reverse(entries);
let entrypositions = Object.keys(entries);
for (let li of container.children) {
let name = li.getAttribute("data-name");
let pos = entrypositions.indexOf(name);
if (pos > -1) {
this.changeTextToHTML(li, searchstring);
li.style.setProperty("order", pos, "important");
var checkbox = li.querySelector(BDFDB.dotCN._repocheckbox);
if (checkbox) {
checkbox.removeEventListener("change", checkbox.changeRepoControlsListener);
checkbox.changeRepoControlsListener = () => {entries[name].enabled = checkbox.checked ? 0 : 1};
checkbox.addEventListener("change", checkbox.changeRepoControlsListener);
parent.props.searchkey = (searchkey || "").toUpperCase();
if (!parent.props.entries) parent.props.entries = parent.props.children;
let entries = [].concat(parent.props.entries);
for (let i in entries) {
let entry = entries[i];
if (!entry.props.RCdata) {
entry.props.RCdata = {};
if (entry.props.plugin) {
["name", "author", "version", "description"].forEach(key => {
let funcname = "get" + key.charAt(0).toUpperCase() + key.slice(1);
let value = typeof entry.props.plugin[funcname] == "function" ? entry.props.plugin[funcname]() : "";
if (value) entry.props.RCdata[key] = value.toUpperCase().trim();
else entry.props.RCdata[key] = "";
});
entry.props.RCdata.type = "plugin";
entry.props.RCdata.enabled = BDFDB.BDUtils.isPluginEnabled(entry.key) ? 1 : 2;
entry.props.RCdata.path = window.bdplugins && window.bdplugins[entry.key] && BDFDB.LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), window.bdplugins[entry.key].filename);
}
else if (entry.props.theme) {
["name", "author", "version", "description"].forEach(key => {
if (entry.props.theme[key]) entry.props.RCdata[key] = entry.props.theme[key].toUpperCase().trim();
else entry.props.RCdata[key] = "";
});
entry.props.RCdata.type = "theme";
entry.props.RCdata.enabled = BDFDB.BDUtils.isThemeEnabled(entry.key) ? 1 : 2;
entry.props.RCdata.path = window.bdthemes && window.bdthemes[entry.key] && BDFDB.LibraryRequires.path.join(BDFDB.BDUtils.getThemesFolder(), window.bdthemes[entry.key].filename);
}
let stats = entry.props.RCdata.path && BDFDB.LibraryRequires.fs.statSync(entry.props.RCdata.path);
entry.props.RCdata.adddate = stats && stats.atime.getTime();
entry.props.RCdata.moddate = stats && stats.mtime.getTime();
entry.props.RCdata.search = [entry.props.RCdata.name, entry.props.RCdata.author, entry.props.RCdata.description].filter(n => n).join(" ");
}
else li.style.removeProperty("order");
BDFDB.DOMUtils.toggle(li, pos > -1);
entry.props.RCdata.searchkey = parent.props.searchkey;
if (parent.props.searchkey && entry.props.RCdata.search.indexOf(parent.props.searchkey) == -1) entries[i] = null;
}
let order = sortings.order == "asc" ? -1 : 1;
parent.props.children = entries.filter(n => n).sort(function (x, y) {
return x.props.RCdata[sortings.sort] < y.props.RCdata[sortings.sort] ? order : x.props.RCdata[sortings.sort] > y.props.RCdata[sortings.sort] ? order * -1 : 0;
});
if (instance) {
BDFDB.ReactUtils.forceUpdate(instance);
BDFDB.TimeUtils.timeout(_ => {BDFDB.ReactUtils.forceUpdate(BDFDB.ReactUtils.findOwner(instance, {name: ["V2C_PluginCard", "V2C_ThemeCard"]}));});
}
}
changeTextToHTML (wrapper, searchstring) {
if (!wrapper || !wrapper.tagName) return;
for (let ele of wrapper.querySelectorAll(BDFDB.dotCNC._reponame + BDFDB.dotCNC._repoauthor + BDFDB.dotCN._repodescription)) {
var string = ele.firstElementChild ? ele.innerHTML : ele.innerText;
if (BDFDB.DOMUtils.containsClass(ele, BDFDB.disCN._repodescription)) {
ele.style.display = "block";
if (searchstring && searchstring.length > 2) ele.innerHTML = BDFDB.highlightText(string, searchstring);
else ele.innerHTML = string;
highlightSearchKey (e) {
if (!e.instance.props.RCdata.searchkey) return;
[BDFDB.disCN._reponame, BDFDB.disCN._repoauthor, BDFDB.disCN._repodescription].forEach(className => {
let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {props: [["className", className]]});
if (index > -1) {
let originalText = BDFDB.StringUtils.htmlEscape(children[index].props.children);
let highlightedText = BDFDB.StringUtils.highlight(originalText, e.instance.props.RCdata.searchkey);
if (highlightedText != originalText) children[index].props.children = BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(highlightedText));
}
else if (searchstring && searchstring.length > 2 || ele.querySelector(BDFDB.dotCN.highlight)) ele.innerHTML = BDFDB.highlightText(string, searchstring);
}
});
}
createDeleteButton (e) {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
text: BDFDB.LanguageUtils.LanguageStrings.DELETE,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
className: "RC-deleteButton RC-button",
look: BDFDB.LibraryComponents.Button.Looks.BLANK,
size: BDFDB.LibraryComponents.Button.Sizes.NONE,
onClick: _ => {
let deleteFile = () => {
BDFDB.LibraryRequires.fs.unlink(e.instance.props.RCdata.path, (error) => {
if (error) BDFDB.NotificationUtils.toast(`Unable to delete ${e.instance.props.RCdata.type} "${e.returnvalue.props["data-name"]}".`, {type:"danger"});
else BDFDB.NotificationUtils.toast(`Successfully deleted ${e.instance.props.RCdata.type} "${e.returnvalue.props["data-name"]}".`, {type:"success"});
});
};
if (!BDFDB.DataUtils.get(this, "settings", "confirmDelete")) deleteFile();
else BDFDB.ModalUtils.confirm(this, `Are you sure you want to delete the ${e.instance.props.RCdata.type} "${e.returnvalue.props["data-name"]}"?`, deleteFile);
},
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
iconSVG: `<svg width="24" height="24"><g fill="currentColor" transform="translate(2,1.5)"><path d="M 18.012, 0.648 H 12.98 C 12.944, 0.284, 12.637, 0, 12.264, 0 H 8.136 c -0.373, 0 -0.68, 0.284 -0.716, 0.648 H 2.389 c -0.398, 0 -0.72, 0.322 -0.72, 0.72 v 1.368 c 0, 0.398, 0.322, 0.72, 0.72, 0.72 h 15.623 c 0.398, 0, 0.72 -0.322, 0.72 -0.72 V 1.368 C 18.731, 0.97, 18.409, 0.648, 18.012, 0.648 z"/><path d="M 3.178, 4.839 v 14.841 c 0, 0.397, 0.322, 0.72, 0.72, 0.72 h 12.604 c 0.398, 0, 0.72 -0.322, 0.72 -0.72 V 4.839 H 3.178 z M 8.449, 15.978 c 0, 0.438 -0.355, 0.794 -0.794, 0.794 c -0.438, 0 -0.794 -0.355 -0.794 -0.794 V 8.109 c 0 -0.438, 0.355 -0.794, 0.794 -0.794 c 0.438, 0, 0.794, 0.355, 0.794, 0.794 V 15.978 z M 13.538, 15.978 c 0, 0.438 -0.355, 0.794 -0.794, 0.794 s -0.794 -0.355 -0.794 -0.794 V 8.109 c 0 -0.438, 0.355 -0.794, 0.794 -0.794 c 0.438, 0, 0.794, 0.355, 0.794, 0.794 V 15.978 z"/></g></svg>`
})
})
});
}
createEditButton (e) {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
text: BDFDB.LanguageUtils.LanguageStrings.EDIT,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
className: "RC-editButton RC-button",
look: BDFDB.LibraryComponents.Button.Looks.BLANK,
size: BDFDB.LibraryComponents.Button.Sizes.NONE,
onClick: _ => {
if (!BDFDB.LibraryRequires.electron.shell.openItem(e.instance.props.RCdata.path)) {
BDFDB.NotificationUtils.toast(`Unable to open the ${e.instance.props.RCdata.type} "${e.returnvalue.props["data-name"]}".`, {type:"danger"});
}
},
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
iconSVG: `<svg width="24" height="24" viewBox="-80 -55 620 620"><g fill="currentColor" fill-rule="evenodd"><path d="M 496.093, 189.613c -18.643 -15.674 -47.168 -13.807 -63.354, 5.493l -9.727, 11.508l 68.945, 57.849l 9.288 -11.466 C 517.22, 233.997, 515.199, 205.621, 496.093, 189.613z"/><path d="M 301.375, 350.534l -5.131, 6.072c -4.453, 5.332 -7.661, 11.704 -9.272, 18.457l -13.945, 58.359 c -1.318, 5.522, 0.601, 11.323, 4.951, 14.971c 4.234, 3.558, 10.206, 4.591, 15.601, 2.285l 55.063 -23.877 c 6.372 -2.769, 12.085 -7.031, 16.538 -12.319l 5.149 -6.092L 301.375, 350.534z"/><polygon points ="403.656, 229.517 320.733, 327.631 389.683, 385.487 472.601, 287.366"/><path d="M 376.02, 66.504l -56.982 -54.141c -5.387 -5.107 -12.014 -8.115 -18.999 -10.069V 90h 89.052 C 387.23, 81.09, 382.69, 72.836, 376.02, 66.504z"/><path d="M 257.792, 368.091c 2.681 -11.221, 8.027 -21.841, 15.439 -30.718l 116.807 -138.214V 120h -105c -8.291, 0 -15 -6.709 -15 -15V 0h -225 c -24.814, 0 -45, 20.186 -45, 45v 422c 0, 24.814, 20.186, 45, 45, 45h 300c 24.814, 0, 45 -20.186, 45 -45v -35.459l -1.948, 2.305 c -7.368, 8.775 -16.875, 15.85 -27.466, 20.465l -55.107, 23.892c -15.532, 6.707 -33.511, 4.331 -46.816 -6.812 c -13.14 -11.03 -18.838 -28.242 -14.854 -44.941L 257.792, 368.091z M 75.038, 90h 150c 8.291, 0, 15, 6.709, 15, 15s -6.709, 15 -15, 15h -150 c -8.291, 0 -15 -6.709 -15 -15S 66.747, 90, 75.038, 90z M 75.038, 181h 240c 8.291, 0, 15, 6.709, 15, 15s -6.709, 15 -15, 15h -240 c -8.291, 0 -15 -6.709 -15 -15S 66.747, 181, 75.038, 181z M 195.038, 391h -120c -8.291, 0 -15 -6.709 -15 -15c 0 -8.291, 6.709 -15, 15 -15h 120 c 8.291, 0, 15, 6.709, 15, 15C 210.038, 384.291, 203.329, 391, 195.038, 391z M 75.038, 301c -8.291, 0 -15 -6.709 -15 -15c 0 -8.291, 6.709 -15, 15 -15 h 180c 8.291, 0, 15, 6.709, 15, 15c 0, 8.291 -6.709, 15 -15, 15H 75.038z"/></g></svg>`
})
})
});
}
toggleAll (type, container, enable) {
BDFDB.ModalUtils.confirm(this, `Are you sure you want to ${enable ? "enable" : "disable"} all ${type[0].toUpperCase() + type.slice(1)}s?`, () => {
for (let header of container.querySelectorAll(BDFDB.dotCN._repoheader)) {
toggleAll (type, instance, enable) {
let listnode = BDFDB.ReactUtils.findDOMNode(BDFDB.ReactUtils.findOwner(instance, {name: "V2C_List"}));
if (listnode) BDFDB.ModalUtils.confirm(this, `Are you sure you want to ${enable ? "enable" : "disable"} all ${type[0].toUpperCase() + type.slice(1)}s?`, () => {
for (let header of listnode.querySelectorAll(BDFDB.dotCN._repoheader)) {
if (header.querySelector(BDFDB.dotCN._reponame).textContent.toLowerCase().indexOf(this.name.toLowerCase()) != 0) {
let switchwrap = header.querySelector(BDFDB.dotCN._repocheckboxwrap);
if (switchwrap) {