sltsv
This commit is contained in:
parent
4c3cacd9fd
commit
508ef57eb2
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
|
@ -987,7 +987,7 @@ body .ace_closeButton:active {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
#bd-settingspane-container h2.ui-form-title {
|
||||
h2.ui-form-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
|
@ -995,32 +995,32 @@ body .ace_closeButton:active {
|
|||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.theme-dark #bd-settingspane-container h2.ui-form-title {
|
||||
.theme-dark h2.ui-form-title {
|
||||
color: #f6f6f7;
|
||||
}
|
||||
.theme-light #bd-settingspane-container h2.ui-form-title {
|
||||
.theme-light h2.ui-form-title {
|
||||
color: #4f545c;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item {
|
||||
.ui-switch-item {
|
||||
flex-direction: column;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item h3 {
|
||||
.ui-switch-item h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
flex: 1;
|
||||
}
|
||||
.theme-dark #bd-settingspane-container .ui-switch-item h3 {
|
||||
.theme-dark .ui-switch-item h3 {
|
||||
color: #f6f6f7;
|
||||
}
|
||||
.theme-light #bd-settingspane-container .ui-switch-item h3 {
|
||||
.theme-light .ui-switch-item h3 {
|
||||
color: #4f545c;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .style-description {
|
||||
.ui-switch-item .style-description {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
|
@ -1028,14 +1028,14 @@ body .ace_closeButton:active {
|
|||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid hsla(218,5%,47%,.3);
|
||||
}
|
||||
.theme-dark #bd-settingspane-container .ui-switch-item .style-description {
|
||||
.theme-dark .ui-switch-item .style-description {
|
||||
color: #72767d;
|
||||
}
|
||||
.theme-light #bd-settingspane-container .ui-switch-item .style-description {
|
||||
.theme-light .ui-switch-item .style-description {
|
||||
color: rgba(114,118,125,.6);
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .ui-switch-wrapper {
|
||||
.ui-switch-item .ui-switch-wrapper {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
|
@ -1047,7 +1047,7 @@ body .ace_closeButton:active {
|
|||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .ui-switch-wrapper input {
|
||||
.ui-switch-item .ui-switch-wrapper input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
|
@ -1056,7 +1056,7 @@ body .ace_closeButton:active {
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .ui-switch-wrapper .ui-switch {
|
||||
.ui-switch-item .ui-switch-wrapper .ui-switch {
|
||||
background: var(--bd-blue);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -1068,7 +1068,7 @@ body .ace_closeButton:active {
|
|||
transition: background .15s ease-in-out,box-shadow .15s ease-in-out,border .15s ease-in-out;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .ui-switch-wrapper .ui-switch:before {
|
||||
.ui-switch-item .ui-switch-wrapper .ui-switch:before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 18px;
|
||||
|
@ -1083,19 +1083,19 @@ body .ace_closeButton:active {
|
|||
box-shadow: 0 3px 1px 0 rgba(0,0,0,.05),0 2px 2px 0 rgba(0,0,0,.1),0 3px 3px 0 rgba(0,0,0,.05);
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .ui-switch-wrapper .ui-switch.checked {
|
||||
.ui-switch-item .ui-switch-wrapper .ui-switch.checked {
|
||||
background: var(--bd-blue);
|
||||
}
|
||||
|
||||
#bd-settingspane-container .ui-switch-item .ui-switch-wrapper .ui-switch.checked:before {
|
||||
.ui-switch-item .ui-switch-wrapper .ui-switch.checked:before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
#bd-settingspane-container .scroller-wrap {
|
||||
.scroller-wrap {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#bd-settingspane-container .scroller-wrap .scroller {
|
||||
.scroller-wrap .scroller {
|
||||
display: flex;
|
||||
}
|
||||
.content-column .ui-form-title:first-child {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4614,8 +4614,7 @@
|
|||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "2.5.2",
|
||||
|
@ -4799,7 +4798,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
|
@ -5249,8 +5247,7 @@
|
|||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-copy": {
|
||||
"version": "0.1.0",
|
||||
|
@ -5667,6 +5664,16 @@
|
|||
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.8.1"
|
||||
}
|
||||
},
|
||||
"prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
||||
|
@ -5757,6 +5764,21 @@
|
|||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz",
|
||||
"integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||
|
|
|
@ -39,5 +39,8 @@
|
|||
"webpack": "^4.29.6",
|
||||
"webpack-cli": "^3.2.3",
|
||||
"@types/react-dom": "^16.9.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^16.13.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,11 +89,11 @@ export const settings = {
|
|||
"React DevTools": {id: "reactDevTools", info: "Adds react developer tools to the devtools. Must be installed in Google Chrome on your pc.", implemented: true, hidden: true, cat: "core", category: "developer settings"},
|
||||
|
||||
/** Lightcord */
|
||||
"Disable BetterDiscord": {id: "bd-disable", info: "Disable Betterdiscord (plugins, themes, etc).", implemented: false, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Disable BetterDiscord": {id: "bd-disable", info: "Disable Betterdiscord (plugins, themes, etc) (Not implemented).", implemented: false, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Blur Personnal Informations":{id: "lightcord-6", info: "Blur sensitive informations like email, payment infos and more.", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Calling Ring Beat": {id: "lightcord-2", info: "Enable Discord's special calling beat.", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Developer Options": {id: "lightcord-1", info: "Enable Discord's Internal Developer Options. This allow the \"Experiments\" tab and the \"Developer Options\" tab. (must reopen settings)", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Ad Block": {id: "lightcord-4", info: "Block any BOT that dm you with an invite link. Even in an embed.", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Developer Options": {id: "lightcord-1", info: "Enable Discord's & Lightcord's Internal Developer Options. This allow the \"Experiments\" tab, the \"Developer Options\" tab and the \"Api Components\" tab. (must reopen settings)", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Ad Block": {id: "lightcord-4", info: "Block any BOT that dms you with an invite link. Even in an embed.", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Enable Lightcord Servers": {id: "lightcord-5", info: "Enable Lightcord's servers. Disabling this will disable custom badges.", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
"Disable typing": {id: "lightcord-7", info: "Don't let other see you're typing.", implemented: true, hidden: false, cat: "lightcord", category: "Lightcord"},
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ import PluginCertifier from "./pluginCertifier";
|
|||
import distant, { uuidv4 } from "./distant";
|
||||
import EmojiModule from "./emojiModule"
|
||||
import {remote as electron} from "electron"
|
||||
import v2 from "./v2";
|
||||
import webpackModules from "./webpackModules";
|
||||
|
||||
function Core() {
|
||||
// Object.assign(bdConfig, __non_webpack_require__(DataStore.configFile));
|
||||
|
@ -47,6 +49,8 @@ Core.prototype.init = async function() {
|
|||
return;
|
||||
}
|
||||
|
||||
Utils.suppressErrors(this.patchAttributes.bind(this), "LC Plugin Certifier Patch")();
|
||||
|
||||
/*
|
||||
const latestLocalVersion = bdConfig.updater ? bdConfig.updater.LatestVersion : bdConfig.latestVersion;
|
||||
if (latestLocalVersion > bdConfig.version) {
|
||||
|
@ -135,6 +139,35 @@ Core.prototype.init = async function() {
|
|||
}
|
||||
};
|
||||
|
||||
Core.prototype.patchAttributes = async function() {
|
||||
let attribsPatchs = []
|
||||
this.cancelPatchAttributes = function() {
|
||||
attribsPatchs.forEach(e => e())
|
||||
}
|
||||
|
||||
while(!v2.MessageComponent)await new Promise(resolve => setTimeout(resolve, 100))
|
||||
|
||||
window.Lightcord.Api.ensureExported(e => e.default && e.default.displayName && e.default.displayName.includes("UserPopout"))
|
||||
.then(UserPopout => {
|
||||
console.log(UserPopout)
|
||||
const render = UserPopout.default.prototype.render
|
||||
UserPopout.default.prototype.render = function(){
|
||||
const returnValue = render.call(this, ...arguments)
|
||||
console.log(returnValue, this.props)
|
||||
return returnValue
|
||||
}
|
||||
})
|
||||
attribsPatchs.push(Utils.monkeyPatch(v2.MessageComponent, "default", {after: (data) => {
|
||||
if(data.methodArguments[0].childrenMessageContent.props.message){ // this can be a blocked message (not opened)
|
||||
data.returnValue.props["data-message-id"] = data.methodArguments[0].childrenMessageContent.props.message.id
|
||||
}
|
||||
}}))
|
||||
/*
|
||||
attribsPatchs.push(Utils.monkeyPatch(v2.MessageComponent, "default", {after: (data) => {
|
||||
data.returnValue.props["message-id"] = data.methodArguments[0].childrenMessageContent.props.message.id
|
||||
}}))*/
|
||||
}
|
||||
|
||||
Core.prototype.checkForGuilds = function() {
|
||||
let timesChecked = 0;
|
||||
return new Promise(resolve => {
|
||||
|
@ -176,6 +209,30 @@ Core.prototype.initSettings = function () {
|
|||
}
|
||||
}
|
||||
}
|
||||
window.Lightcord.Api.ensureExported(e => e.default && e.default.prototype && e.default.prototype.getPredicateSections)
|
||||
.then(settingModule => {
|
||||
|
||||
let getPredicateSections = settingModule.default.prototype.getPredicateSections
|
||||
settingModule.default.prototype.getPredicateSections = function(){
|
||||
let result = getPredicateSections.call(this, ...arguments)
|
||||
|
||||
if(result[1].section === "My Account"){ // user settings, not guild settings
|
||||
let poped = []
|
||||
|
||||
poped.push(result.pop())
|
||||
poped.push(result.pop())
|
||||
poped.push(result.pop())
|
||||
poped.push(result.pop())
|
||||
|
||||
result.push(...settingsPanel.renderSidebar())
|
||||
|
||||
while(poped[0]){
|
||||
result.push(poped.pop())
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
|
@ -204,7 +261,6 @@ Core.prototype.initObserver = function () {
|
|||
if (node.getElementsByClassName(classNameSocialLinks).length) {
|
||||
node.setAttribute("layer-id", "user-settings");
|
||||
node.setAttribute("id", "user-settings");
|
||||
if (!document.getElementById("bd-settings-sidebar")) settingsPanel.renderSidebar();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,13 +388,15 @@ Core.prototype.patchGuildListItems = function() {
|
|||
if (data.returnValue && data.thisObject) {
|
||||
const returnValue = data.returnValue;
|
||||
const guildData = data.thisObject.props;
|
||||
returnValue.props.className += " bd-guild";
|
||||
if (guildData.unread) returnValue.props.className += " bd-unread";
|
||||
if (guildData.selected) returnValue.props.className += " bd-selected";
|
||||
if (guildData.audio) returnValue.props.className += " bd-audio";
|
||||
if (guildData.video) returnValue.props.className += " bd-video";
|
||||
if (guildData.badge) returnValue.props.className += " bd-badge";
|
||||
if (guildData.animatable) returnValue.props.className += " bd-animatable";
|
||||
let className = returnValue.props.className
|
||||
className += " bd-guild";
|
||||
if (guildData.unread) className += " bd-unread";
|
||||
if (guildData.selected) className += " bd-selected";
|
||||
if (guildData.audio) className += " bd-audio";
|
||||
if (guildData.video) className += " bd-video";
|
||||
if (guildData.badge) className += " bd-badge";
|
||||
if (guildData.animatable) className += " bd-animatable";
|
||||
returnValue.props.className = className
|
||||
return returnValue;
|
||||
}
|
||||
}});
|
||||
|
@ -421,7 +479,6 @@ Core.prototype.patchMessageHeader = function() {
|
|||
)
|
||||
);
|
||||
}
|
||||
// TODO: fix 12787689 badges duplicate
|
||||
const id = uuidv4()
|
||||
children.push(
|
||||
BDV2.React.createElement("div", {
|
||||
|
@ -439,6 +496,10 @@ function applyBadges(id, user, chat){
|
|||
process.nextTick(() => {
|
||||
const div = document.getElementById("badges-"+id)
|
||||
if(!div || div.childNodes.length > 0)return
|
||||
if(div.childNodes.length)return
|
||||
let blockDiv = document.createElement("div")
|
||||
blockDiv.style.display = "none"
|
||||
div.appendChild(blockDiv)
|
||||
|
||||
const Anchor = WebpackModules.find(m => m.displayName == "Anchor");
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ export default new class DevMode {
|
|||
if (el==el.ownerDocument.documentElement) names.unshift(el.tagName.toLowerCase()+Array.from(el.classList.entries()).map(e => "."+e).join(""));
|
||||
else{
|
||||
for (var c=1,e=el;e.previousElementSibling;e=e.previousElementSibling,c++);
|
||||
names.unshift(el.tagName.toLowerCase()+(el.className || "").split(" ").map(e => "."+e).join("")+":nth-child("+c+")");
|
||||
names.unshift(el.tagName.toLowerCase()+((typeof el.className === "string" && el.className) || "").split(" ").filter(e => !!e).map(e => "."+e).join("")+":nth-child("+c+")");
|
||||
}
|
||||
el=el.parentNode;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ class LightcordError extends Error {
|
|||
export const Constants = {
|
||||
SERVER_URL: "http://127.0.0.1",
|
||||
badges: [ // TODO:
|
||||
{
|
||||
/*{
|
||||
name: "Lightcord User",
|
||||
id: "01cfa7b0-7cdb-4b0e-8258-9c6a78235c93",
|
||||
defaultUsers: [],
|
||||
|
@ -148,7 +148,7 @@ export const Constants = {
|
|||
"user"
|
||||
],
|
||||
component: LightcordUserBadge
|
||||
}, {
|
||||
}, */{
|
||||
name: "Lightcord Bug Hunter",
|
||||
id: "f04698f5-816b-41e3-bd01-92291193d7a5",
|
||||
defaultUsers: [
|
||||
|
|
|
@ -38,6 +38,8 @@ PluginModule.prototype.loadPlugins = async function () {
|
|||
bdpluginErrors.push({name: name, file: bdplugins[plugins[i]].filename, message: "start() could not be fired.", error: {message: err.message, stack: err.stack}});
|
||||
}
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||
}
|
||||
this.savePluginData();
|
||||
|
||||
|
|
|
@ -28,17 +28,33 @@ import { remote } from "electron";
|
|||
import AntiAdDM from "./AntiAdDM";
|
||||
import blurPrivate from "./blurPrivate";
|
||||
import disableTyping from "./disableTyping";
|
||||
import ApiPreview from "../ui/ApiPreview";
|
||||
import V2C_SettingsTitle from "../ui/settingsTitle";
|
||||
import Switch from "../ui/switch";
|
||||
import MarginTop from "../ui/margintop";
|
||||
|
||||
export default new class V2_SettingsPanel {
|
||||
|
||||
constructor() {
|
||||
this.sideBarOnClick = this.sideBarOnClick.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.updateSettings = this.updateSettings.bind(this);
|
||||
this.sidebar = new V2_SettingsPanel_Sidebar(this.sideBarOnClick);
|
||||
// this.buildPluginProps = this.buildPluginProps.bind(this);
|
||||
// this.buildThemeProps = this.buildThemeProps.bind(this);
|
||||
this.showOriginal = this.showOriginal.bind(this);
|
||||
this.sidebar = new V2_SettingsPanel_Sidebar();
|
||||
|
||||
this.registerComponents()
|
||||
}
|
||||
|
||||
registerComponents(){
|
||||
/** Lightcord */
|
||||
this.sidebar.register("lightcord", makeComponent(this.lightcordComponent.bind(this)))
|
||||
this.sidebar.register("status", makeComponent(this.PresenceComponent.bind(this)))
|
||||
this.sidebar.register("accountinfo", makeComponent(this.AccountInfosComponent.bind(this)))
|
||||
this.sidebar.register("lcapipreview", makeComponent(this.ApiPreviewComponent.bind(this)))
|
||||
|
||||
/* Bandaged BD */
|
||||
this.sidebar.register("core", makeComponent(this.coreComponent.bind(this)))
|
||||
this.sidebar.register("customcss", makeComponent(this.customCssComponent.bind(this)))
|
||||
this.sidebar.register("plugins", makeComponent(this.renderAddonPane("plugins")))
|
||||
this.sidebar.register("themes", makeComponent(this.renderAddonPane("themes")))
|
||||
}
|
||||
|
||||
get root() {
|
||||
|
@ -102,33 +118,6 @@ export default new class V2_SettingsPanel {
|
|||
}, []);
|
||||
}
|
||||
|
||||
sideBarOnClick(id) {
|
||||
const contentRegion = DOM.query(".contentRegion-3nDuYy, .content-region");
|
||||
contentRegion.style.display = "none";
|
||||
this.root.style.display = "";
|
||||
switch (id) {
|
||||
case "core":
|
||||
this.renderCoreSettings();
|
||||
break;
|
||||
case "customcss":
|
||||
this.renderCustomCssEditor();
|
||||
break;
|
||||
case "plugins":
|
||||
case "themes":
|
||||
this.renderAddonPane(id);
|
||||
break;
|
||||
case "lightcord":
|
||||
this.renderLightcordSettings()
|
||||
break
|
||||
case "status":
|
||||
this.renderPresenceSettings()
|
||||
break
|
||||
case "accountinfo":
|
||||
this.renderAccountInfos()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onClick() {}
|
||||
|
||||
onChange(id, checked) {
|
||||
|
@ -295,100 +284,62 @@ export default new class V2_SettingsPanel {
|
|||
Object.assign(settingsRPC, DataStore.getSettingGroup("rpc"));
|
||||
}
|
||||
|
||||
showOriginal() {
|
||||
BDV2.reactDom.unmountComponentAtNode(this.root);
|
||||
this.root.style.display = "none";
|
||||
DOM.query("."+BDModules.get(e => e.contentRegion)[0].contentRegion.split(" ")[0]+", .content-region").style.display = "";
|
||||
}
|
||||
|
||||
renderSidebar() {
|
||||
const tabs = document.querySelectorAll("[class*='side-'] > [class*='item-']");
|
||||
for (const element of tabs) {
|
||||
element.removeEventListener("click", this.showOriginal);
|
||||
element.addEventListener("click", this.showOriginal);
|
||||
}
|
||||
this.sidebar.render();
|
||||
return this.sidebar.render();
|
||||
}
|
||||
|
||||
get coreComponent() {
|
||||
return BDV2.react.createElement(Scroller, {contentColumn: true, fade: true, dark: true},
|
||||
BDV2.react.createElement(SectionedSettingsPanel, {key: "cspanel", onChange: this.onChange, sections: this.coreSettings}),
|
||||
BDV2.react.createElement(Tools, {key: "tools"})
|
||||
);
|
||||
coreComponent() {
|
||||
return BDV2.react.createElement(SectionedSettingsPanel, {key: "cspanel", onChange: this.onChange, sections: this.coreSettings})
|
||||
}
|
||||
|
||||
get lightcordComponent() {
|
||||
return BDV2.react.createElement(Scroller, {contentColumn: true, fade: true, dark: true},
|
||||
BDV2.react.createElement(SectionedSettingsPanel, {key: "lspannel", onChange: this.onChange, sections: this.lightcordSettings}),
|
||||
BDV2.react.createElement(Tools, {key: "tools"})
|
||||
);
|
||||
}
|
||||
|
||||
get PresenceComponent() {
|
||||
return BDV2.react.createElement(Scroller, {contentColumn: true, fade: true, dark: true},
|
||||
BDV2.react.createElement(V2C_PresenceSettings, {
|
||||
key: "lppannel",
|
||||
onChange: this.onChange,
|
||||
settings: this.PresenceSettings
|
||||
lightcordComponent() {
|
||||
return [
|
||||
this.lightcordSettings.map((section, i) => {
|
||||
return [
|
||||
(i === 0 ? null : BDV2.react.createElement(MarginTop)),
|
||||
BDV2.react.createElement("h2", {className: "ui-form-title h2 margin-reset margin-bottom-20"}, section.title),
|
||||
section.settings.map(setting => {
|
||||
return BDV2.react.createElement(Switch, {id: setting.id, key: setting.id, data: setting, checked: settingsCookie[setting.id], onChange: (id, checked) => {
|
||||
this.onChange(id, checked);
|
||||
}})
|
||||
})
|
||||
]
|
||||
}),
|
||||
BDV2.react.createElement(Tools, {key: "tools"})
|
||||
);
|
||||
BDV2.react.createElement(window.Lightcord.Api.Components.inputs.Button, {color: "yellow", onClick(){
|
||||
console.log("Should relaunch")
|
||||
remote.app.relaunch({
|
||||
args: remote.process.argv.slice(1).concat(["--disable-betterdiscord"])
|
||||
})
|
||||
remote.app.quit()
|
||||
}}, "Relaunch without BetterDiscord")
|
||||
]
|
||||
}
|
||||
|
||||
get AccountInfosComponent() {
|
||||
return BDV2.react.createElement(Scroller, {contentColumn: true, fade: true, dark: true},
|
||||
BDV2.react.createElement(V2C_AccountInfos, {
|
||||
key: "lapannel"
|
||||
}),
|
||||
BDV2.react.createElement(Tools, {key: "tools"})
|
||||
);
|
||||
PresenceComponent() {
|
||||
return BDV2.react.createElement(V2C_PresenceSettings, {
|
||||
key: "lppannel",
|
||||
onChange: this.onChange,
|
||||
settings: this.PresenceSettings
|
||||
})
|
||||
}
|
||||
|
||||
get customCssComponent() {
|
||||
return BDV2.react.createElement(Scroller, {contentColumn: true, fade: true, dark: true},
|
||||
BDV2.react.createElement(CssEditor, {key: "csseditor"}),
|
||||
BDV2.react.createElement(Tools, {key: "tools"})
|
||||
);
|
||||
AccountInfosComponent() {
|
||||
return BDV2.react.createElement(V2C_AccountInfos, {
|
||||
key: "lapannel"
|
||||
})
|
||||
}
|
||||
|
||||
renderCoreSettings() {
|
||||
const root = this.root;
|
||||
if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
BDV2.reactDom.render(this.coreComponent, root);
|
||||
ApiPreviewComponent() {
|
||||
return BDV2.react.createElement(ApiPreview, {
|
||||
key: "lapipannel"
|
||||
})
|
||||
}
|
||||
|
||||
renderLightcordSettings() {
|
||||
const root = this.root;
|
||||
if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
BDV2.reactDom.render(this.lightcordComponent, root);
|
||||
customCssComponent() {
|
||||
return BDV2.react.createElement(CssEditor, {key: "csseditor"})
|
||||
}
|
||||
|
||||
renderPresenceSettings() {
|
||||
const root = this.root;
|
||||
if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
BDV2.reactDom.render(this.PresenceComponent, root);
|
||||
}
|
||||
|
||||
renderAccountInfos() {
|
||||
const root = this.root;
|
||||
if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
BDV2.reactDom.render(this.AccountInfosComponent, root);
|
||||
}
|
||||
|
||||
renderCustomCssEditor() {
|
||||
const root = this.root;
|
||||
if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
BDV2.reactDom.render(this.customCssComponent, root);
|
||||
}
|
||||
|
||||
// renderAddonPane(type) {
|
||||
// const root = this.root;
|
||||
// if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
// BDV2.reactDom.render(this.contentComponent(type), root);
|
||||
// }
|
||||
|
||||
renderAddonPane(type) {
|
||||
if (!this.root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
// I know this shouldn't be here, but when it isn't,
|
||||
// React refuses to change the button when going
|
||||
// between plugins and themes page... something
|
||||
|
@ -397,19 +348,6 @@ export default new class V2_SettingsPanel {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
this.prefix = this.props.type.replace("s", "");
|
||||
this.onChange = this.onChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
BDEvents.on(`${this.prefix}-reloaded`, this.onChange);
|
||||
BDEvents.on(`${this.prefix}-loaded`, this.onChange);
|
||||
BDEvents.on(`${this.prefix}-unloaded`, this.onChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
BDEvents.off(`${this.prefix}-reloaded`, this.onChange);
|
||||
BDEvents.off(`${this.prefix}-loaded`, this.onChange);
|
||||
BDEvents.off(`${this.prefix}-unloaded`, this.onChange);
|
||||
}
|
||||
|
||||
onChange() {
|
||||
|
@ -425,7 +363,17 @@ export default new class V2_SettingsPanel {
|
|||
set: function() {console.warn("Addon policy for plugins #5 https://github.com/rauenzi/BetterDiscordApp/wiki/Addon-Policies#plugins");},
|
||||
get: () => originalRender
|
||||
});
|
||||
const list = type === "plugins" ? Object.values(bdplugins) : Object.values(bdthemes);
|
||||
return BDV2.reactDom.render(BDV2.react.createElement(ContentList, {type, onChange: this.sideBarOnClick}, BDV2.react.createElement(CardList, {type, list})), this.root);
|
||||
return function(){
|
||||
return BDV2.react.createElement(ContentList, {type}, BDV2.react.createElement(CardList, {type}))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function makeComponent(children){
|
||||
class SettingComponent extends React.Component {
|
||||
render(){
|
||||
return children()
|
||||
}
|
||||
}
|
||||
return SettingComponent
|
||||
}
|
|
@ -9,8 +9,16 @@ import TooltipWrap from "../ui/tooltipWrap";
|
|||
|
||||
export default class V2_SettingsPanel_Sidebar {
|
||||
|
||||
constructor(onClick) {
|
||||
this.onClick = onClick;
|
||||
constructor() {
|
||||
this.panels = {}
|
||||
}
|
||||
|
||||
register(panel, component){
|
||||
this.panels[panel] = component
|
||||
}
|
||||
|
||||
getComponent(panel){
|
||||
return this.panels[panel]
|
||||
}
|
||||
|
||||
get items() {
|
||||
|
@ -30,7 +38,7 @@ export default class V2_SettingsPanel_Sidebar {
|
|||
}
|
||||
|
||||
get LCitems(){
|
||||
return [
|
||||
let items = [
|
||||
{
|
||||
text: "Lightcord Settings",
|
||||
id: "lightcord"
|
||||
|
@ -42,53 +50,43 @@ export default class V2_SettingsPanel_Sidebar {
|
|||
id: "accountinfo"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
get component() {
|
||||
//<TooltipWrap color="black" side="top" text={title}>
|
||||
|
||||
const changelogButton = BDV2.react.createElement(TooltipWrap, {color: "black", side: "top", text: "BBD's Changelog"},
|
||||
BDV2.react.createElement("div", {className: "bd-changelog-button", onClick: () => {Utils.showChangelogModal(bbdChangelog);}},
|
||||
BDV2.react.createElement(History, {className: "bd-icon", size: "16px"})
|
||||
)
|
||||
);
|
||||
const changelogButtonLC = BDV2.react.createElement(TooltipWrap, {color: "black", side: "top", text: "Lightcord's Changelog"},
|
||||
BDV2.react.createElement("div", {className: "bd-changelog-button", onClick: () => {Utils.showChangelogModal(LCChanelog);}},
|
||||
BDV2.react.createElement(History, {className: "bd-icon", size: "16px"})
|
||||
)
|
||||
);
|
||||
return [
|
||||
BDV2.react.createElement("span", null, BDV2.react.createElement(SideBar, {onClick: this.onClick, headerText: "Lightcord", headerButton: changelogButtonLC, items: this.LCitems})),
|
||||
BDV2.react.createElement("span", null, BDV2.react.createElement(SideBar, {onClick: this.onClick, headerText: "Bandaged BD", headerButton: changelogButton, items: this.items}))
|
||||
]
|
||||
}
|
||||
|
||||
get root() {
|
||||
const _root = DOM.query("#bd-settings-sidebar");
|
||||
if (!_root) {
|
||||
if (!this.injectRoot()) return null;
|
||||
return this.root;
|
||||
}
|
||||
return _root;
|
||||
}
|
||||
|
||||
injectRoot() {
|
||||
const tabs = DOM.queryAll("[class*='side-'] > [class*='item-']:not([class*=Danger])");
|
||||
const changeLog = tabs[tabs.length - 1];
|
||||
if (!changeLog) return false;
|
||||
changeLog.parentElement.insertBefore(DOM.createElement(`<div id="bd-settings-sidebar">`), changeLog.previousElementSibling);
|
||||
return true;
|
||||
if(!!window.Lightcord.Settings.devMode)items.push({
|
||||
text: "Api Components Preview",
|
||||
id: "lcapipreview"
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
render() {
|
||||
const root = this.root;
|
||||
if (!root) {
|
||||
console.log("FAILED TO LOCATE ROOT: [class*='side-'] > [class*='item-']:not([class*=Danger])");
|
||||
return;
|
||||
}
|
||||
BDV2.reactDom.render(this.component, root);
|
||||
Utils.onRemoved(root, () => {
|
||||
BDV2.reactDom.unmountComponentAtNode(root);
|
||||
});
|
||||
return [
|
||||
{
|
||||
section: "HEADER",
|
||||
label: "Lightcord"
|
||||
},
|
||||
...this.LCitems.map(e => {
|
||||
return {
|
||||
section: e.id,
|
||||
label: e.text,
|
||||
element: this.getComponent(e.id)
|
||||
}
|
||||
}),
|
||||
{
|
||||
section: "DIVIDER"
|
||||
},
|
||||
{
|
||||
section: "HEADER",
|
||||
label: "Bandaged BD"
|
||||
},
|
||||
...this.items.map(e => {
|
||||
return {
|
||||
section: e.id,
|
||||
label: e.text,
|
||||
element: this.getComponent(e.id)
|
||||
}
|
||||
}),
|
||||
{
|
||||
section: "DIVIDER"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@ ThemeModule.prototype.loadThemes = async function () {
|
|||
const theme = bdthemes[themes[i]];
|
||||
if (!themeCookie[theme.name]) themeCookie[theme.name] = false;
|
||||
if (themeCookie[theme.name]) DOM.addStyle(DOM.escapeID(theme.id), unescape(theme.css));
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||
}
|
||||
for (const theme in themeCookie) {
|
||||
if (!bdthemes[theme]) delete themeCookie[theme];
|
||||
|
|
|
@ -110,11 +110,16 @@ export default class Utils {
|
|||
else return console.error(methodName, "does not exist for", displayName); // eslint-disable-line no-console
|
||||
}
|
||||
const origMethod = what[methodName];
|
||||
let canceled = false
|
||||
const cancel = () => {
|
||||
if (!silent) console.log("unpatch", methodName, "of", displayName); // eslint-disable-line no-console
|
||||
what[methodName] = origMethod;
|
||||
//what[methodName] = origMethod;
|
||||
canceled = true // this allow to monkeypatch more than one time.
|
||||
};
|
||||
what[methodName] = function() {
|
||||
if(canceled){
|
||||
return origMethod.call(this, ...arguments)
|
||||
}
|
||||
const data = {
|
||||
thisObject: this,
|
||||
methodArguments: arguments,
|
||||
|
|
|
@ -6,7 +6,6 @@ import V2C_SettingsTitle from "./settingsTitle";
|
|||
*/
|
||||
const React = BDV2.React;
|
||||
|
||||
let contentModule = BDModules.get(e => e.contentColumn)[0]
|
||||
let marginModule2 = BDModules.get(e => e.defaultMarginh5)[0]
|
||||
let colorModule = BDModules.get(e => e.colorStandard)[0]
|
||||
let sizeModule = BDModules.get(e => e.size32)[0]
|
||||
|
@ -22,29 +21,27 @@ export default class V2C_AccountInfos extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
if(!contentModule)contentModule = BDModules.get(e => e.contentColumn)[0]
|
||||
if(!marginModule2)marginModule2 = BDModules.get(e => e.defaultMarginh5)[0]
|
||||
if(!colorModule)colorModule = BDModules.get(e => e.colorStandard)[0]
|
||||
if(!sizeModule)sizeModule = BDModules.get(e => e.size32)[0]
|
||||
return (<div className={contentModule.contentColumn+" "+contentModule.contentColumnDefault+" content-column default"}
|
||||
style={{padding: "60px 40px 0px"}}>
|
||||
<V2C_SettingsTitle text="Account Infos"/>
|
||||
<div>
|
||||
<h5 className={colorModule.colorStandard+" "+sizeModule.size14+" "+marginModule2.h5+" "+marginModule2.defaultMarginh5}>
|
||||
Profile
|
||||
</h5>
|
||||
<CodeContent content={this.getProfileValue()} language="diff" />
|
||||
<h5 className={colorModule.colorStandard+" "+sizeModule.size14+" "+marginModule2.h5+" "+marginModule2.defaultMarginh5}>
|
||||
Statistics
|
||||
</h5>
|
||||
<CodeContent content={this.getStatistics()} language="diff" />
|
||||
<h5 className={colorModule.colorStandard+" "+sizeModule.size14+" "+marginModule2.h5+" "+marginModule2.defaultMarginh5}>
|
||||
Connected Sessions
|
||||
</h5>
|
||||
<CodeContent content={this.getSessionValue()} language="diff" />
|
||||
</div>
|
||||
<div className={BDModules.get(e => e.marginBottom20)[0].marginBottom20}></div>
|
||||
</div>)
|
||||
return [
|
||||
<V2C_SettingsTitle text="Account Infos"/>,
|
||||
<div>
|
||||
<h5 className={colorModule.colorStandard+" "+sizeModule.size14+" "+marginModule2.h5+" "+marginModule2.defaultMarginh5}>
|
||||
Profile
|
||||
</h5>
|
||||
<CodeContent content={this.getProfileValue()} language="diff" />
|
||||
<h5 className={colorModule.colorStandard+" "+sizeModule.size14+" "+marginModule2.h5+" "+marginModule2.defaultMarginh5}>
|
||||
Statistics
|
||||
</h5>
|
||||
<CodeContent content={this.getStatistics()} language="diff" />
|
||||
<h5 className={colorModule.colorStandard+" "+sizeModule.size14+" "+marginModule2.h5+" "+marginModule2.defaultMarginh5}>
|
||||
Connected Sessions
|
||||
</h5>
|
||||
<CodeContent content={this.getSessionValue()} language="diff" />
|
||||
</div>,
|
||||
<div className={BDModules.get(e => e.marginBottom20)[0].marginBottom20}></div>
|
||||
]
|
||||
}
|
||||
|
||||
getSessionValue(){
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
// Good luck to read my code, Even me can't read it properly.
|
||||
|
||||
import { stat } from "fs"
|
||||
import { uuidv4 } from "../modules/distant"
|
||||
import webpackModules from "../modules/webpackModules"
|
||||
import { remote } from "electron"
|
||||
import MarginTop from "./margintop"
|
||||
|
||||
const keys = {
|
||||
settingTitle: uuidv4()
|
||||
}
|
||||
let formModule
|
||||
export default class ApiPreview extends React.PureComponent {
|
||||
constructor(){
|
||||
super(...arguments)
|
||||
this.state = {
|
||||
states: []
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
if(!formModule)formModule = webpackModules.find(e => e.FormSection)
|
||||
/**
|
||||
* @type {Function[]}
|
||||
*/
|
||||
const allComponents = [...new Set(Object.keys(window.Lightcord.Api.Components).map(e => {
|
||||
return Object.keys(window.Lightcord.Api.Components[e]).map(k => window.Lightcord.Api.Components[e][k])
|
||||
}).flat())]
|
||||
return [
|
||||
<formModule.FormSection tag="h2" title="Lightcord's Api Availlable components">
|
||||
<formModule.FormText type="description" className="" selectable={false}>
|
||||
These components are here for the plugin devs. They can quickly embed any component below with this panel.
|
||||
</formModule.FormText>
|
||||
<MarginTop></MarginTop>
|
||||
<Lightcord.Api.Components.inputs.Button color="brand" look="outlined" size="medium" hoverColor="green" onClick={() => {
|
||||
remote.shell.openExternal("https://github.com/lightcord/lightcord/wiki/apis")
|
||||
}} wrapper={false}>
|
||||
Documentation
|
||||
</Lightcord.Api.Components.inputs.Button>
|
||||
</formModule.FormSection>,
|
||||
allComponents.map(comp => {
|
||||
let AllPreviews = []
|
||||
if(comp.AllPreviews)AllPreviews = comp.AllPreviews
|
||||
let onChange = (tab) => {
|
||||
setState({
|
||||
tab
|
||||
})
|
||||
}
|
||||
let setState = (newState) => {
|
||||
this.setState({
|
||||
states: [Object.assign(state, newState)].concat(this.state.states.filter(e => e.elem !== comp))
|
||||
})
|
||||
}
|
||||
let state = this.state.states.find(e => e.elem === comp)
|
||||
if(!state){
|
||||
state = {
|
||||
tab: "preview",
|
||||
elem: comp,
|
||||
options: {}
|
||||
}
|
||||
this.state.states.push(state)
|
||||
}
|
||||
let getProps = () => {
|
||||
let final = {}
|
||||
AllPreviews.forEach(category => {
|
||||
final[Object.keys(category[0])[0]] = category[0][Object.keys(category[0])[0]]
|
||||
})
|
||||
Object.keys(state.options).forEach(key => {
|
||||
final[key] = AllPreviews.find(e => e.find(e => e[key]))[state.options[key]][key]
|
||||
})
|
||||
return final
|
||||
}
|
||||
let renderPreview = () => {
|
||||
return <div style={{marginTop: "20px", marginBottom: "20px"}}>
|
||||
<div style={{
|
||||
backgroundColor: "var(--background-primary)",
|
||||
padding: "30px 30px",
|
||||
borderRadius: "8px"
|
||||
}} className="lc-tab-box-shadow">
|
||||
{React.createElement(comp, getProps())}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
let renderCode = () => {
|
||||
return <div style={{marginTop: "20px", marginBottom: "20px"}}>
|
||||
<div style={{
|
||||
backgroundColor: "var(--background-primary)",
|
||||
padding: "30px 30px",
|
||||
borderRadius: "8px"
|
||||
}} className="lc-tab-box-shadow">
|
||||
<window.Lightcord.Api.Components.general.SettingSubTitle>
|
||||
JSX
|
||||
</window.Lightcord.Api.Components.general.SettingSubTitle>
|
||||
<window.Lightcord.Api.Components.general.CodeBlock language="jsx" content={generateCode("jsx")}/>
|
||||
|
||||
<window.Lightcord.Api.Components.general.SettingSubTitle>
|
||||
React
|
||||
</window.Lightcord.Api.Components.general.SettingSubTitle>
|
||||
<window.Lightcord.Api.Components.general.CodeBlock language="js" content={generateCode("react")}/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
let getStrForProp = (value) => {
|
||||
if(typeof value === "string"){
|
||||
return value
|
||||
}else if(typeof value === "boolean"){
|
||||
return String(value)
|
||||
}else if(typeof value === "function"){
|
||||
return value.toString()
|
||||
}else if(typeof value === "object"){
|
||||
if(value && value.$$typeof && (value.$$typeof === Symbol.for("react.element") || value.$$typeof === 0xeac7)){
|
||||
return "Your components here."
|
||||
}
|
||||
return JSON.stringify(value, null, " ")
|
||||
}else if(typeof value === "number"){
|
||||
return String(value)
|
||||
}
|
||||
return String(value)
|
||||
}
|
||||
let generateCode = function(lang){ // code formatting is hard
|
||||
const compName = comp.displayName || comp.name
|
||||
let categories = Object.keys(window.Lightcord.Api.Components)
|
||||
const compCategory = categories.find(e => window.Lightcord.Api.Components[e][compName])
|
||||
const compPath = `Lightcord.Api.Components.${compCategory}.${compName}`
|
||||
const props = getProps()
|
||||
|
||||
if(lang === "jsx"){
|
||||
let propStrings = []
|
||||
let childrenProp = null
|
||||
Object.keys(props).forEach(key => {
|
||||
if(key == "children"){
|
||||
childrenProp = getStrForProp(props[key])
|
||||
}else{
|
||||
let str = key+"="
|
||||
if(typeof props[key] === "string"){
|
||||
str += JSON.stringify(props[key])
|
||||
}else{
|
||||
str += `{${getStrForProp(props[key])}}`
|
||||
}
|
||||
propStrings.push(str)
|
||||
}
|
||||
})
|
||||
let openTag
|
||||
if(childrenProp){
|
||||
openTag = `<${compPath} ${propStrings.join(" ")}>`
|
||||
let closeTag = `</${compPath}>`
|
||||
return `${openTag}\n ${childrenProp}\n${closeTag}`
|
||||
}else{
|
||||
openTag = `<${compPath} ${propStrings.join(" ")}/>`
|
||||
return openTag
|
||||
}
|
||||
}else if(lang === "react"){
|
||||
let children = props.children || null
|
||||
delete props.children
|
||||
if(children && children.$$typeof && (children.$$typeof === Symbol.for("react.element") || children.$$typeof === 0xeac7)){
|
||||
children = "Your components here."
|
||||
}
|
||||
let propStrings = []
|
||||
Object.keys(props).forEach(key => {
|
||||
let visibleKey = /[^\w\d_]/g.test(key) ? JSON.stringify(key) : key
|
||||
let str = visibleKey+": "
|
||||
if(typeof props[key] === "string"){
|
||||
str += JSON.stringify(props[key])
|
||||
}else{
|
||||
str += getStrForProp(props[key]).split("\n").map((str, i) => {
|
||||
if(i === 0)return str
|
||||
return " " + str
|
||||
}).join("\n")
|
||||
}
|
||||
propStrings.push(str)
|
||||
})
|
||||
let propObject = "{"
|
||||
if(propStrings.length){
|
||||
propStrings.forEach((str, i) => {
|
||||
let isLast = i === propStrings.length - 1
|
||||
let isFirst = i === 0
|
||||
if(!isFirst){
|
||||
propObject += ","
|
||||
}
|
||||
propObject += "\n "
|
||||
propObject += str
|
||||
if(isLast){
|
||||
propObject +="\n}"
|
||||
}
|
||||
})
|
||||
}else{
|
||||
propObject += "}"
|
||||
}
|
||||
return `React.createElement(${compPath}, ${propObject}, ${JSON.stringify(children)})`
|
||||
}
|
||||
}
|
||||
return (<div>
|
||||
<window.Lightcord.Api.Components.general.SettingsTitle>
|
||||
{comp.displayName || comp.name}
|
||||
</window.Lightcord.Api.Components.general.SettingsTitle>
|
||||
{AllPreviews.map(category => {
|
||||
if(category[0].onClick)return null
|
||||
if(category[0].text)return null
|
||||
if(category[0].children)return null
|
||||
if(category.length === 1)return null
|
||||
|
||||
let key = Object.keys(category[0])[0]
|
||||
return [
|
||||
<window.Lightcord.Api.Components.general.SettingSubTitle>
|
||||
{key}
|
||||
</window.Lightcord.Api.Components.general.SettingSubTitle>,
|
||||
<window.Lightcord.Api.Components.inputs.Dropdown options={category.map((e, index) => {
|
||||
return {
|
||||
value: "opt-"+index,
|
||||
label: JSON.stringify(e[Object.keys(e)[0]])
|
||||
}
|
||||
})} value={"opt-"+(state.options[key] || "0")} onChange={(value) => {
|
||||
setState({
|
||||
options: Object.assign({}, state.options, {
|
||||
[key]: (value.value || "0").replace("opt-", "")
|
||||
})
|
||||
})
|
||||
}} searchable={true}/>,
|
||||
<div style={{marginBottom: "8px"}}></div>
|
||||
]
|
||||
})}
|
||||
<window.Lightcord.Api.Components.general.Tabs tabs={[{label: "Preview", id: "preview"}, {label: "Code", id: "code"}]}
|
||||
active={state.tab} children={state.tab === "preview" ? renderPreview() : renderCode()} onChange={onChange}/>
|
||||
</div>)
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
get renders(){
|
||||
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
|
|||
};
|
||||
|
||||
const thisNode = this.refs.cardNode;
|
||||
const container = thisNode.closest(".scroller");
|
||||
const container = thisNode.closest("div[class*=\"scroller-\"]")
|
||||
if (!isHidden(container, thisNode)) return;
|
||||
const thisNodeOffset = DOM.offset(thisNode);
|
||||
const containerOffset = DOM.offset(container);
|
||||
|
|
|
@ -105,8 +105,12 @@ export default class CardList extends BDV2.reactComponent {
|
|||
return typeof value == "string" ? value : value.toString();
|
||||
}
|
||||
|
||||
get list(){
|
||||
return this.props.type === "plugins" ? Object.values(bdplugins) : Object.values(bdthemes);
|
||||
}
|
||||
|
||||
getAddons() {
|
||||
const sortedAddons = this.props.list.sort((a, b) => {
|
||||
const sortedAddons = this.list.sort((a, b) => {
|
||||
const cap = this.state.sort.charAt(0).toUpperCase() + this.state.sort.slice(1);
|
||||
const first = a.plugin && a.plugin[`get${cap}`] ? this.getString(a.plugin[`get${cap}`]()) : a[this.state.sort];
|
||||
const second = b.plugin && b.plugin[`get${cap}`] ? this.getString(b.plugin[`get${cap}`]()) : b[this.state.sort];
|
||||
|
@ -153,28 +157,25 @@ export default class CardList extends BDV2.reactComponent {
|
|||
}</Tooltip>;
|
||||
const addonCards = this.getAddons();
|
||||
|
||||
return <Scroller contentColumn={true} fade={true} dark={true}>
|
||||
<ContentColumn title={`${this.props.type.toUpperCase()}—${addonCards.length}`}>
|
||||
<button key="folder-button" className="bd-button bd-pfbtn" onClick={this.openFolder.bind(this)}>Open {this.isPlugins ? "Plugin" : "Theme"} Folder</button>
|
||||
{!settingsCookie["fork-ps-5"] && refreshIcon}
|
||||
<div className="bd-controls bd-addon-controls">
|
||||
<Search onChange={this.search} placeholder={`Search ${this.props.type}...`} />
|
||||
<div className="bd-addon-dropdowns">
|
||||
<div className="bd-select-wrapper">
|
||||
<label className="bd-label">Sort by:</label>
|
||||
<Dropdown options={this.sortOptions} onChange={this.sort} style="transparent" />
|
||||
</div>
|
||||
<div className="bd-select-wrapper">
|
||||
<label className="bd-label">Order:</label>
|
||||
<Dropdown options={this.directions} onChange={this.reverse} style="transparent" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
return <ContentColumn title={`${this.props.type.toUpperCase()}—${addonCards.length}`}>
|
||||
<button key="folder-button" className="bd-button bd-pfbtn" onClick={this.openFolder.bind(this)}>Open {this.isPlugins ? "Plugin" : "Theme"} Folder</button>
|
||||
{!settingsCookie["fork-ps-5"] && refreshIcon}
|
||||
<div className="bd-controls bd-addon-controls">
|
||||
<Search onChange={this.search} placeholder={`Search ${this.props.type}...`} />
|
||||
<div className="bd-addon-dropdowns">
|
||||
<div className="bd-select-wrapper">
|
||||
<label className="bd-label">Sort by:</label>
|
||||
<Dropdown options={this.sortOptions} onChange={this.sort} style="transparent" />
|
||||
</div>
|
||||
<div className="bda-slist bd-addon-list">{addonCards}</div>
|
||||
</ContentColumn>
|
||||
<Tools key="tools" />
|
||||
</Scroller>;
|
||||
<div className="bd-select-wrapper">
|
||||
<label className="bd-label">Order:</label>
|
||||
<Dropdown options={this.directions} onChange={this.reverse} style="transparent" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="bda-slist bd-addon-list">{addonCards}</div>
|
||||
</ContentColumn>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,16 @@ export default class V2C_ContentColumn extends BDV2.reactComponent {
|
|||
static get displayName() {return "ContentColumn";}
|
||||
|
||||
render() {
|
||||
let contentModule = BDModules.get(e => e.contentColumn)[0]
|
||||
//let contentModule = BDModules.get(e => e.contentColumn)[0]
|
||||
let title = this.props.title ? BDV2.react.createElement("h2", {className: "ui-form-title h2 margin-reset margin-bottom-20"}, this.props.title) : null
|
||||
return [
|
||||
title,
|
||||
this.props.children
|
||||
]
|
||||
return BDV2.react.createElement(
|
||||
"div",
|
||||
{className: contentModule.contentColumn + " "+contentModule.contentColumnDefault+" content-column default"},
|
||||
BDV2.react.createElement(
|
||||
"h2",
|
||||
{className: "ui-form-title h2 margin-reset margin-bottom-20"},
|
||||
this.props.title
|
||||
),
|
||||
{className: contentModule.contentColumn + " "+contentModule.contentColumnDefault+" content-column default", style: {padding: "60px 40px 0px"}},
|
||||
title,
|
||||
this.props.children
|
||||
);
|
||||
}
|
||||
|
|
|
@ -87,10 +87,7 @@ export default class V2C_CssEditor extends BDV2.reactComponent {
|
|||
const self = this;
|
||||
|
||||
const {detached} = self.state;
|
||||
let contentModule = BDModules.get(e => e.contentColumn)[0]
|
||||
return BDV2.react.createElement(
|
||||
"div",
|
||||
{className: contentModule.contentColumn+" "+contentModule.contentColumnDefault+" content-column default", style: {padding: "60px 40px 0px"}},
|
||||
return [
|
||||
detached && BDV2.react.createElement(
|
||||
"div",
|
||||
{id: "editor-detached"},
|
||||
|
@ -162,7 +159,7 @@ export default class V2C_CssEditor extends BDV2.reactComponent {
|
|||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
}
|
||||
|
||||
onClick(arg) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
let marginModule = BDModules.get(e => e.marginTop60)[0]
|
||||
|
||||
export default class MarginTop extends React.Component {
|
||||
render(){
|
||||
if(!marginModule)marginModule = BDModules.get(e => e.marginTop60)[0]
|
||||
return <div className={marginModule.marginTop60}></div>
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import { defaultRPC, settingsRPC } from "../0globals";
|
|||
import CustomRichPresence from "../modules/CustomRichPresence"
|
||||
import timestampRender from "./timestampRender"
|
||||
import { remote } from "electron";
|
||||
import MarginTop from "./margintop";
|
||||
|
||||
|
||||
const React = BDV2.React;
|
||||
|
@ -114,7 +115,6 @@ export default class V2C_PresenceSettings extends React.Component {
|
|||
|
||||
get modules(){
|
||||
return V2C_PresenceSettingsModules || (V2C_PresenceSettingsModules = [
|
||||
BDModules.get(e => e.contentColumn)[0],
|
||||
BDModules.get(e => e.marginBottom20)[0]
|
||||
])
|
||||
}
|
||||
|
@ -122,32 +122,32 @@ export default class V2C_PresenceSettings extends React.Component {
|
|||
render() {
|
||||
console.log("Rerendering rpc manager")
|
||||
let [
|
||||
contentModule,
|
||||
marginModule
|
||||
] = this.modules
|
||||
return (<div className={contentModule.contentColumn+" "+contentModule.contentColumnDefault+" content-column default"}
|
||||
style={{padding: "60px 40px 0px"}}>
|
||||
<V2C_SettingsGroup title="RichPresence Settings" settings={this.props.settings} onChange={this.props.onChange}/>
|
||||
<V2C_SettingsTitle text="RichPresence"/>
|
||||
<div>
|
||||
{/** options */}
|
||||
{this.optionsComponents}
|
||||
</div>
|
||||
<div>
|
||||
<V2C_SettingsTitle text="Preview"/>
|
||||
{/** preview */}
|
||||
<RpcPreview settings={this}/>
|
||||
</div>
|
||||
<div className={marginModule.marginBottom20}></div>
|
||||
<button style={{opacity: 0.01}} onClick={window.ohgodohfuck}>
|
||||
Oh god Oh fuck
|
||||
</button>
|
||||
<button style={{opacity: 0.01}} onClick={() => {
|
||||
remote.shell.openExternal("https://www.youtube.com/watch?v=LkYa7rps_g4")
|
||||
}}>
|
||||
See ? I pulled a litle sneaky on ya
|
||||
</button>
|
||||
</div>)
|
||||
return [
|
||||
<V2C_SettingsGroup title="RichPresence Settings" settings={this.props.settings} onChange={this.props.onChange}/>,
|
||||
<MarginTop />,
|
||||
<V2C_SettingsTitle text="RichPresence"/>,
|
||||
<div>
|
||||
{/** options */}
|
||||
{this.optionsComponents}
|
||||
</div>,
|
||||
<div>
|
||||
<MarginTop />
|
||||
<V2C_SettingsTitle text="Preview"/>
|
||||
{/** preview */}
|
||||
<RpcPreview settings={this}/>
|
||||
</div>,
|
||||
<div className={marginModule.marginBottom20}></div>,
|
||||
<button style={{opacity: 0.01}} onClick={window.ohgodohfuck}>
|
||||
Oh god Oh fuck
|
||||
</button>,
|
||||
<button style={{opacity: 0.01}} onClick={() => {
|
||||
remote.shell.openExternal("https://www.youtube.com/watch?v=LkYa7rps_g4")
|
||||
}}>
|
||||
See ? I pulled a litle sneaky on ya
|
||||
</button>
|
||||
]
|
||||
}
|
||||
|
||||
get optionsComponents(){
|
||||
|
@ -354,9 +354,9 @@ class InputNumber extends React.PureComponent {
|
|||
</h5>
|
||||
{this.input}
|
||||
{setting.id === "timestamps.start" ?
|
||||
<Lightcord.Api.Components.inputs.Button text="Copy current timestamp" onClick={() => {
|
||||
<Lightcord.Api.Components.inputs.Button onClick={() => {
|
||||
DiscordNative.clipboard.copy(Date.now()+"")
|
||||
}} color="brand"/> : null}
|
||||
}} color="brand">Copy current timestamp</Lightcord.Api.Components.inputs.Button> : null}
|
||||
</div>
|
||||
<Divider/>
|
||||
</div>)
|
||||
|
@ -468,7 +468,9 @@ class DiscordButton extends React.Component {
|
|||
|
||||
return (<div className={rowModule.row+" "+marginModule.marginBottom20}>
|
||||
<div className={`${rowModule.item} ${flexModule.flexChild}`}>
|
||||
<Lightcord.Api.Components.inputs.Button text={this.props.title} onClick={this.props.onClick} color="brand"/>
|
||||
<Lightcord.Api.Components.inputs.Button onClick={this.props.onClick} color="brand">
|
||||
{this.props.title}
|
||||
</Lightcord.Api.Components.inputs.Button>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
|
@ -612,7 +614,7 @@ class Popout extends React.Component {
|
|||
</div>
|
||||
})()
|
||||
|
||||
return (<div className="lc-userPopout">
|
||||
return (<div className="lc-userPopout lc-tab-box-shadow">
|
||||
<div class={rootModule1.userPopout} role="dialog" tabindex="-1">
|
||||
<div class={rootModule1.headerPlaying}>
|
||||
<div class={`${flexModule1.flex} ${stylingModule1.vertical} ${stylingModule1.justifyCenter} ${stylingModule1.alignCenter} ${stylingModule1.noWrap} ${rootModule1.headerTop}`} style={{flex: "1 1 auto"}}>
|
||||
|
@ -773,7 +775,7 @@ class Profile extends React.Component {
|
|||
})()
|
||||
|
||||
return [
|
||||
<div className="lc-tab">
|
||||
<div className="lc-tab lc-tab-box-shadow">
|
||||
<div class={`${flexModule1.flex} ${stylingModule1.vertical} ${stylingModule1.justifyStart} ${stylingModule1.alignStretch} ${stylingModule1.noWrap} ${rootModule1.root}`} style={{flex: "1 1 auto"}}>
|
||||
<div class={rootModule1.topSectionPlaying}>
|
||||
<header class={rootModule1.header}>
|
||||
|
@ -854,8 +856,7 @@ class Profile extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div class="lc- "></div>
|
||||
</div>
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import BDV2 from "../modules/v2";
|
||||
|
||||
import SettingsGroup from "./settingsGroup";
|
||||
import MarginTop from "./margintop";
|
||||
|
||||
export default class V2C_SectionedSettingsPanel extends BDV2.reactComponent {
|
||||
|
||||
|
@ -9,12 +10,11 @@ export default class V2C_SectionedSettingsPanel extends BDV2.reactComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
let columnModule = BDModules.get(e => e.contentColumnDefault)[0]
|
||||
return BDV2.react.createElement(
|
||||
"div", {className: columnModule.contentColumn+" "+columnModule.contentColumnDefault+" content-column default"},
|
||||
this.props.sections.map(section => {
|
||||
return BDV2.react.createElement(SettingsGroup, Object.assign({}, section, {onChange: this.props.onChange}));
|
||||
})
|
||||
);
|
||||
return this.props.sections.map((section, i) => {
|
||||
return [
|
||||
i !== 0 ? BDV2.react.createElement(MarginTop, {}) : null,
|
||||
BDV2.react.createElement(SettingsGroup, Object.assign({}, section, {onChange: this.props.onChange}))
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ export default class V2C_SettingsTitle extends BDV2.reactComponent {
|
|||
render() {
|
||||
return BDV2.react.createElement(
|
||||
"h2",
|
||||
{className: "ui-form-title h2 margin-reset margin-bottom-20 "+BDModules.get(e => e.marginTop60)[0].marginTop60},
|
||||
{className: "ui-form-title h2 margin-reset margin-bottom-20"},
|
||||
this.props.text
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Lightcord's Discord.js
|
||||
|
||||
### What is this ?
|
||||
Lightcord includes a Discord.js-like api. This is written in this folder.
|
||||
|
||||
### Where can I get the documentation ?
|
||||
[Documentation here](https://discord.js.org/#/docs/main/11.6.4/general/welcome)
|
||||
Discord.js on Lightcord is following Discord.js 11.6.4 specs.
|
||||
|
||||
### How do I use it ?
|
||||
Discord.js can be accessed under the following global properties
|
||||
|
||||
| Name | Global Properties | alias | Limitations |
|
||||
|------------------------------|-------------------------|-------------------------|-----------------------------------------------------------------------|
|
||||
| DiscordJS main module | window.DiscordJS | none | none |
|
||||
| DiscordJS client | window.DiscordJSClient | window.DiscordJS.client | none |
|
||||
| DiscordJS Client constructor | window.DiscordJS.Client | none | Can't be constructed because there's no need for more than one client |
|
||||
|
||||
### Deprecations
|
||||
1. Any method that only bot can use (it will throw a `DiscordJSError` saying that Lightcord can't do that)
|
||||
3. Any method
|
File diff suppressed because one or more lines are too long
|
@ -8,6 +8,248 @@
|
|||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.5.tgz",
|
||||
"integrity": "sha512-CU1q0UXQUpFNzNB7gufgoisDHP7n+T3tkqTsp3MNUkVJ5+hS3BCvME8uCXAUFlz+6T2FbTCu75A+yQ7HMKqRKw=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"emojis-list": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
|
||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
|
||||
"integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"memory-fs": "^0.5.0",
|
||||
"tapable": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"errno": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
|
||||
"integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
|
||||
"requires": {
|
||||
"prr": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
|
||||
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"memory-fs": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
|
||||
"integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
|
||||
"requires": {
|
||||
"errno": "^0.1.3",
|
||||
"readable-stream": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
||||
"requires": {
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.0.5"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
||||
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tapable": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
||||
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz",
|
||||
"integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==",
|
||||
"requires": {
|
||||
"chalk": "^2.3.0",
|
||||
"enhanced-resolve": "^4.0.0",
|
||||
"loader-utils": "^1.0.2",
|
||||
"micromatch": "^4.0.0",
|
||||
"semver": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
|
||||
"integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==",
|
||||
"dev": true
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,16 @@
|
|||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"watch": "tsc --watch",
|
||||
"build": "tsc"
|
||||
},
|
||||
"author": "jeanouina",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^0.1.5"
|
||||
"@discordjs/collection": "^0.1.5",
|
||||
"ts-loader": "^7.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^3.9.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,25 +2,52 @@ import { EventEmitter } from "events";
|
|||
import DiscordJSError from "../util/DiscordJSError";
|
||||
import Collection from "@discordjs/collection";
|
||||
import { Snowflake, Channel } from "..";
|
||||
import { channelsModule } from "../util/DiscordToModules";
|
||||
import { createChannel } from "../util/util";
|
||||
import { channelsModule, guildModule, UserModule, DispatcherModule } from "../util/DiscordToModules";
|
||||
import { createChannel, createGuild, createMessage, createUser } from "../util/util";
|
||||
import Guild from "../structures/Guild";
|
||||
import ClientUser from "../structures/ClientUser";
|
||||
import User from "../structures/User";
|
||||
|
||||
let hasInit = false
|
||||
function setupEvents(client:Client){
|
||||
let dispatcher = DispatcherModule
|
||||
|
||||
dispatcher.subscribe("CONNECTION_OPEN", () => {
|
||||
client.emit("self.ready")
|
||||
})
|
||||
|
||||
dispatcher.subscribe("MESSAGE_CREATE", action => {
|
||||
if(action.optimistic)return // disable not sent messages
|
||||
action.message && client.emit("self.messageCreate", action.message)
|
||||
})
|
||||
}
|
||||
|
||||
export default class Client extends EventEmitter {
|
||||
constructor(){
|
||||
super()
|
||||
if(hasInit)throw new DiscordJSError("Cannot initialized more than one client.")
|
||||
hasInit = true
|
||||
super()
|
||||
|
||||
setupEvents(this)
|
||||
|
||||
this.on("self.ready", () => {
|
||||
try{
|
||||
this.user = new ClientUser(UserModule.getCurrentUser())
|
||||
console.log(this.user)
|
||||
}catch(e){
|
||||
console.error(e)
|
||||
console.log(UserModule.getCurrentUser, UserModule, typeof UserModule.getCurrentUser)
|
||||
}
|
||||
|
||||
this.emit("ready")
|
||||
})
|
||||
|
||||
this.on("self.messageCreate", (message) => {
|
||||
this.emit("messageCreate", createMessage(message))
|
||||
})
|
||||
}
|
||||
|
||||
/** Warnings and overrides for functions that are not compatible. */
|
||||
async login():Promise<never>{
|
||||
throw new DiscordJSError("Client#login is not supported. DiscordJS on lightcord will use the connected account.")
|
||||
}
|
||||
|
||||
get token():never{
|
||||
throw new DiscordJSError("Client#token is not supported. DiscordJS on lightcord will use the connected account.")
|
||||
}
|
||||
user:ClientUser = null
|
||||
|
||||
get broadcasts(){
|
||||
return [] // not giving any since they're not supported.
|
||||
|
@ -34,4 +61,27 @@ export default class Client extends EventEmitter {
|
|||
const channels = Object.values(channelsModule.getAllChannels())
|
||||
return new Collection(channels.map(e => ([e.id, createChannel(e)])))
|
||||
}
|
||||
|
||||
get emojis():Collection<Snowflake, any /* Emoji */>{ // TODO: Return Emojis
|
||||
return new Collection()
|
||||
}
|
||||
|
||||
get guilds():Collection<Snowflake, Guild>{
|
||||
const channels = Object.values(guildModule.getAllGuilds())
|
||||
return new Collection(channels.map(e => ([e.id, createGuild(e)])))
|
||||
}
|
||||
|
||||
get users():Collection<Snowflake, User>{
|
||||
const users = Object.values(UserModule.getUsers())
|
||||
return new Collection(users.map(e => [e.id, createUser(e)]))
|
||||
}
|
||||
|
||||
/** Warnings and overrides for functions that are not compatible. */
|
||||
async login():Promise<never>{
|
||||
throw new DiscordJSError("Client#login is not supported. DiscordJS on lightcord will use the connected account.")
|
||||
}
|
||||
|
||||
get token():never{
|
||||
throw new DiscordJSError("Client#token is not supported. DiscordJS on lightcord will use the connected account.")
|
||||
}
|
||||
}
|
|
@ -6,10 +6,12 @@ import Snowflake from "../util/Snowflake"
|
|||
export default class BaseChannel extends BaseStructure {
|
||||
id:string
|
||||
deleted:boolean
|
||||
DiscordChannel:DiscordChannel
|
||||
constructor(channel:DiscordChannel){
|
||||
super()
|
||||
this.id = channel.id
|
||||
this.deleted = false
|
||||
this.DiscordChannel = channel
|
||||
}
|
||||
|
||||
get createdAt():Date{
|
||||
|
@ -21,5 +23,5 @@ export default class BaseChannel extends BaseStructure {
|
|||
|
||||
delete() {
|
||||
return channelsModule.delete(this.id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import User from "./User";
|
||||
import { DiscordUser } from "../util/DiscordToModules";
|
||||
|
||||
export default class ClientUser extends User {
|
||||
|
||||
}
|
|
@ -0,0 +1,299 @@
|
|||
import { Snowflake, Channel } from ".."
|
||||
import { DiscordGuild, channelsModule, guildModule, UserSettingsModule, ConstantsModule, CdnModule, AckModule } from "../util/DiscordToModules"
|
||||
import BaseStructure from "./BaseStructure"
|
||||
import { createChannel, createGuildMember, createRole, UserResolvable, resolveUserID } from "../util/util"
|
||||
import Collection from "@discordjs/collection"
|
||||
import SnowflakeUtil from "../util/Snowflake"
|
||||
import GuildMember from "./GuildMember"
|
||||
import { MessageNotificationType } from "../util/Constants"
|
||||
import Role from "./Role"
|
||||
import DiscordJSError from "../util/DiscordJSError"
|
||||
|
||||
export default class Guild extends BaseStructure {
|
||||
DiscordGuild:DiscordGuild
|
||||
constructor(data:DiscordGuild){
|
||||
super()
|
||||
this.DiscordGuild = data
|
||||
}
|
||||
|
||||
get id(): Snowflake{
|
||||
return this.DiscordGuild.id
|
||||
}
|
||||
|
||||
get afkChannel():Channel{
|
||||
if(!this.afkChannelID)return null
|
||||
return createChannel(channelsModule.getChannel(this.afkChannelID))
|
||||
}
|
||||
|
||||
get afkChannelID():Snowflake{
|
||||
return this.DiscordGuild.afkChannelId
|
||||
}
|
||||
|
||||
get afkTimeout():number{
|
||||
return this.DiscordGuild.afkTimeout
|
||||
}
|
||||
|
||||
get applicationID():Snowflake{
|
||||
return this.DiscordGuild.application_id
|
||||
}
|
||||
|
||||
get available():boolean{
|
||||
return true
|
||||
}
|
||||
|
||||
get channels():Collection<Snowflake, Channel>{{
|
||||
return this.client.channels.filter(channel => channel.guild_id === this.id)
|
||||
}}
|
||||
|
||||
get createdAt():Date{
|
||||
return SnowflakeUtil.deconstruct(this.id).date
|
||||
}
|
||||
|
||||
get createdTimestamp():number{
|
||||
return this.createdAt.getTime()
|
||||
}
|
||||
|
||||
get defaultChannel(){
|
||||
return this.channels.get(this.id)
|
||||
}
|
||||
|
||||
get defaultMessageNotifications():number{
|
||||
return this.DiscordGuild.defaultMessageNotifications
|
||||
}
|
||||
|
||||
deleted:boolean = false
|
||||
|
||||
get embedEnabled(){
|
||||
return true
|
||||
}
|
||||
|
||||
get emojis(){
|
||||
return this.client.emojis.filter(e => e.guild_id === this.id)
|
||||
}
|
||||
|
||||
get explicitContentFilter(){
|
||||
return this.DiscordGuild.explicitContentFilter
|
||||
}
|
||||
|
||||
get features(){
|
||||
return Array.from(this.DiscordGuild.features)
|
||||
}
|
||||
|
||||
get icon(){
|
||||
return this.DiscordGuild.icon
|
||||
}
|
||||
|
||||
get iconURL(){
|
||||
return this.DiscordGuild.getIconURL().replace(".webp", ".jpg")
|
||||
}
|
||||
|
||||
get joinedAt(){
|
||||
return new Date(this.DiscordGuild.joinedAt)
|
||||
}
|
||||
|
||||
get joinedTimestamp(){
|
||||
return this.DiscordGuild.joinedAt.getTime()
|
||||
}
|
||||
|
||||
get large(){
|
||||
return false
|
||||
}
|
||||
|
||||
get me(){
|
||||
return this.members.find(member => member.id === this.client.user.id)
|
||||
}
|
||||
|
||||
get memberCount(){
|
||||
return guildModule.getMemberCount(this.id)
|
||||
}
|
||||
|
||||
get members(){
|
||||
return new Collection<Snowflake, GuildMember>(guildModule.getMembers(this.id).map(member => [member.userId, createGuildMember(member)]))
|
||||
}
|
||||
|
||||
get messageNotifications():MessageNotificationType{
|
||||
return MessageNotificationType[guildModule.getMessageNotifications(this.id)] as unknown as MessageNotificationType
|
||||
}
|
||||
|
||||
get mfaLevel(){
|
||||
return this.DiscordGuild.mfaLevel
|
||||
}
|
||||
|
||||
get mobilePush():boolean{
|
||||
return guildModule.getNotificationsState().userGuildSettings[this.id].mobile_push
|
||||
}
|
||||
|
||||
get muted(){
|
||||
return guildModule.getNotificationsState().userGuildSettings[this.id].muted
|
||||
}
|
||||
|
||||
get name(){
|
||||
return this.DiscordGuild.name
|
||||
}
|
||||
|
||||
get nameAcronym(){
|
||||
return this.DiscordGuild.acronym
|
||||
}
|
||||
|
||||
get owner(){
|
||||
return this.members.get(this.ownerID)
|
||||
}
|
||||
|
||||
get ownerID(){
|
||||
return this.DiscordGuild.ownerId
|
||||
}
|
||||
|
||||
get position(){
|
||||
let guildPositions = UserSettingsModule.getAllSettings().guildPositions
|
||||
if(!guildPositions)return 0
|
||||
return guildPositions.indexOf(this.id)
|
||||
}
|
||||
|
||||
get presences(){ // TODO: Add activities.
|
||||
return new Collection()
|
||||
}
|
||||
|
||||
get region(){
|
||||
return this.DiscordGuild.region
|
||||
}
|
||||
|
||||
get roles(){
|
||||
return new Collection<Snowflake, Role>(Object.values(this.DiscordGuild.roles).map(role => [role.id, createRole(role)]))
|
||||
}
|
||||
|
||||
get splash(){
|
||||
return this.DiscordGuild.splash
|
||||
}
|
||||
|
||||
get splashURL(){
|
||||
return CdnModule.getGuildSplashURL({
|
||||
id: this.id,
|
||||
splash: this.splash,
|
||||
size: ConstantsModule.SPLASH_SIZE
|
||||
})
|
||||
}
|
||||
|
||||
get suppressEveryone(){
|
||||
return guildModule.getNotificationsState().userGuildSettings[this.id].suppress_everyone
|
||||
}
|
||||
|
||||
get systemChannel(){
|
||||
return this.client.channels.get(this.systemChannelID)
|
||||
}
|
||||
|
||||
get systemChannelID(){
|
||||
return this.DiscordGuild.systemChannelId
|
||||
}
|
||||
|
||||
get verificationLevel(){
|
||||
return this.DiscordGuild.verificationLevel
|
||||
}
|
||||
|
||||
get verified(){
|
||||
return this.features.includes("VERIFIED")
|
||||
}
|
||||
|
||||
get voiceConnection(){// TODO: Implement if possible VoiceConnection. Maybe not fully like discord.js, but at least can see if you're connected.
|
||||
return null
|
||||
}
|
||||
|
||||
get banner(){
|
||||
return this.DiscordGuild.banner
|
||||
}
|
||||
|
||||
get bannerURL(){
|
||||
return CdnModule.getGuildBannerURL({
|
||||
id: this.id,
|
||||
banner: this.banner
|
||||
})
|
||||
}
|
||||
|
||||
get description(){
|
||||
return this.DiscordGuild.description
|
||||
}
|
||||
|
||||
get embedChannel(){ // TODO: Implement embedChannel
|
||||
return null
|
||||
}
|
||||
|
||||
get embedChannelID(){ // TODO: Implement embedChannelID
|
||||
return null
|
||||
}
|
||||
|
||||
get maximumMembers(){ // TODO: Correctly Implement maximumMembers if possible
|
||||
return 250000
|
||||
}
|
||||
|
||||
get maximumPresences(){ // TODO: Correctly Implement maximumPresences if possible
|
||||
return 5000
|
||||
}
|
||||
|
||||
get widgetEnabled(){ // TODO: Correctly Implement widgetEnabled if possible
|
||||
return false
|
||||
}
|
||||
|
||||
get widgetChannelID(){ // TODO: Correctly Implement widgetChannelID if possible
|
||||
return null
|
||||
}
|
||||
|
||||
get widgetChannel(){ // TODO: Correctly Implement widgetChannel if possible
|
||||
return null
|
||||
}
|
||||
|
||||
get vanityURLCode(){
|
||||
return this.DiscordGuild.vanityURLCode
|
||||
}
|
||||
/** FUNCTIONS */
|
||||
async acknowledge(){
|
||||
AckModule.bulkAck(this.channels.filter(e => e.type === "text").map(e => {
|
||||
return {
|
||||
channelId: e.id,
|
||||
messageId: channelsModule.lastMessageId(e.id)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
addMember(...args:any):Promise<GuildMember>{
|
||||
return Promise.reject(new DiscordJSError("This method is not available on Lightcord."))
|
||||
}
|
||||
|
||||
allowDMs(allow:boolean){
|
||||
let restricted = UserSettingsModule.getAllSettings().restrictedGuilds
|
||||
if(allow){
|
||||
if(!restricted.includes(this.id))return Promise.resolve(this)
|
||||
restricted = restricted.filter(e => e !== this.id)
|
||||
}else{
|
||||
if(restricted.includes(this.id))return Promise.resolve(this)
|
||||
restricted.push(this.id)
|
||||
}
|
||||
return UserSettingsModule.updateRemoteSettings({
|
||||
restrictedGuilds: restricted
|
||||
}).then(() => this)
|
||||
}
|
||||
|
||||
ban(user:UserResolvable, {
|
||||
days = 0,
|
||||
reason = null
|
||||
}: {
|
||||
days?: number,
|
||||
reason?: string
|
||||
}){
|
||||
let id = resolveUserID(user)
|
||||
if(!id)return Promise.reject(new DiscordJSError("Given user could not be resolved to an user ID."))
|
||||
|
||||
|
||||
}
|
||||
|
||||
fetch():Promise<Guild>{ // Guild is synced by Discord. Only refreshing from cache.
|
||||
let guild = guildModule.getGuild(this.id)
|
||||
if(!guild){
|
||||
this.deleted = true
|
||||
return Promise.resolve(this)
|
||||
}
|
||||
this.DiscordGuild = guild
|
||||
return Promise.resolve(this)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import BaseChannel from "./BaseChannel";
|
||||
import { DiscordChannel, guildModule } from "../util/DiscordToModules";
|
||||
import { createChannel, createGuild } from "../util/util";
|
||||
|
||||
export default class GuildChannel extends BaseChannel {
|
||||
constructor(channel:DiscordChannel){
|
||||
super(channel)
|
||||
}
|
||||
|
||||
get guild(){
|
||||
return createGuild(guildModule.getGuild(this.DiscordChannel.guild_id))
|
||||
}
|
||||
|
||||
get guild_id(){
|
||||
return this.DiscordChannel.guild_id
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import BaseStructure from "./BaseStructure";
|
||||
import { DiscordGuildMember } from "../util/DiscordToModules";
|
||||
|
||||
export default class GuildMember extends BaseStructure {
|
||||
DiscordGuildMember: DiscordGuildMember
|
||||
constructor(data: DiscordGuildMember){
|
||||
super()
|
||||
this.DiscordGuildMember = data
|
||||
}
|
||||
|
||||
get id(){
|
||||
return this.DiscordGuildMember.userId
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import BaseStructure from "./BaseStructure";
|
||||
import { DiscordMessage, UserModule } from "../util/DiscordToModules";
|
||||
import User from "./User";
|
||||
|
||||
export default class Message extends BaseStructure {
|
||||
DiscordMessage:DiscordMessage
|
||||
constructor(data:DiscordMessage){
|
||||
super()
|
||||
this.DiscordMessage = data
|
||||
}
|
||||
|
||||
get author(){
|
||||
return new User(UserModule.getUser(this.DiscordMessage.author.id))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import BaseStructure from "./BaseStructure";
|
||||
|
||||
export default class Presence extends BaseStructure {
|
||||
constructor(data){
|
||||
super()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import BaseStructure from "./BaseStructure";
|
||||
import { DiscordRole } from "../util/DiscordToModules";
|
||||
|
||||
export default class Role extends BaseStructure {
|
||||
DiscordRole:DiscordRole
|
||||
constructor(data:DiscordRole){
|
||||
super()
|
||||
this.DiscordRole = data
|
||||
}
|
||||
}
|
|
@ -1,3 +1,14 @@
|
|||
export class TextChannel extends TextBasedChannel, GuildChannel {
|
||||
import { applyMixins } from "../util/util";
|
||||
import GuildChannel from "./GuildChannel";
|
||||
import { DiscordChannel } from "../util/DiscordToModules";
|
||||
import { ChannelTypes } from "../util/Constants";
|
||||
|
||||
export class TextChannel extends GuildChannel/* implements TextBasedChannel*/ {
|
||||
constructor(data:DiscordChannel){
|
||||
super(data)
|
||||
}
|
||||
|
||||
get type(): ChannelTypes.TEXT{
|
||||
return ChannelTypes.TEXT
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
import BaseStructure from "./BaseStructure";
|
||||
import { DiscordUser, CdnModule, UserModule } from "../util/DiscordToModules";
|
||||
|
||||
export default class User extends BaseStructure {
|
||||
DiscordUser:DiscordUser
|
||||
constructor(data:DiscordUser){
|
||||
super()
|
||||
|
||||
this.DiscordUser = data
|
||||
}
|
||||
|
||||
get id(){
|
||||
return this.DiscordUser.id
|
||||
}
|
||||
|
||||
get avatar(){
|
||||
return this.DiscordUser.avatar
|
||||
}
|
||||
|
||||
get avatarURL(){
|
||||
return this.DiscordUser.avatarURL
|
||||
}
|
||||
|
||||
get bot(){
|
||||
return this.DiscordUser.bot
|
||||
}
|
||||
|
||||
get createdAt(){
|
||||
return new Date(this.DiscordUser.createdAt)
|
||||
}
|
||||
|
||||
get createdTimestamp(){
|
||||
return this.createdAt.getTime()
|
||||
}
|
||||
|
||||
get defaultAvatarURL(){
|
||||
return CdnModule.getDefaultAvatarURL(this.discriminator)
|
||||
}
|
||||
|
||||
get discriminator(){
|
||||
return this.DiscordUser.discriminator
|
||||
}
|
||||
|
||||
get displayAvatarURL(){
|
||||
return CdnModule.getUserAvatarURL({
|
||||
id: this.id,
|
||||
avatar: this.avatar,
|
||||
bot: this.bot,
|
||||
discriminator: this.discriminator
|
||||
}, "png", 4096)
|
||||
}
|
||||
|
||||
get dmChannel(){
|
||||
return this.client.channels.find(e => e.type === "dm" && e.recipient.id === this.id)
|
||||
}
|
||||
|
||||
get lastMessage(){ // TODO: Implement User#lastMessage
|
||||
return null
|
||||
}
|
||||
|
||||
get lastMessageID(){ // TODO: Implement User#lastMessageID
|
||||
return null
|
||||
}
|
||||
|
||||
get note(){
|
||||
let note = UserModule.getNote(this.id)
|
||||
if(!note || !note.note)return null
|
||||
return note.note
|
||||
}
|
||||
|
||||
get presence(){
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { Snowflake } from ".."
|
||||
|
||||
export enum ChannelTypes {
|
||||
TEXT = "text",
|
||||
DM = "dm",
|
||||
VOICE = "voice",
|
||||
GROUP_DM = "group",
|
||||
CATEGORY = "category",
|
||||
NEWS = "news",
|
||||
STORE = "store"
|
||||
}
|
||||
|
||||
export enum MessageNotificationType {
|
||||
"EVERYTHING",
|
||||
"MENTIONS",
|
||||
"NOTHING",
|
||||
"INHERIT"
|
||||
}
|
||||
|
||||
export type Status = "online" | "idle" | "invisible" | "offline" | "dnd"
|
||||
|
||||
export const AVATAR_SIZE = 4096
|
|
@ -1,4 +1,6 @@
|
|||
import { Snowflake } from ".."
|
||||
import { lazyLoad } from "./LazyLoader"
|
||||
import { Status } from "./Constants"
|
||||
|
||||
export default function getModule(name:string){
|
||||
return exports[name+"Module"]
|
||||
|
@ -6,35 +8,220 @@ export default function getModule(name:string){
|
|||
|
||||
const BDModules = window.BDModules
|
||||
|
||||
function requireModule(filter: (module:any) => boolean){
|
||||
export function requireModule(filter: (module:any) => boolean){
|
||||
let module = BDModules.get(filter)[0]
|
||||
return module && module.default || module
|
||||
}
|
||||
|
||||
const channelsModuleInternal1:{
|
||||
getChannel(id:Snowflake): DiscordChannel,
|
||||
getChannels(): {
|
||||
[k:string]: DiscordChannel
|
||||
export const channelsModule = lazyLoad<typeof import("./modules/channels")>("channels")
|
||||
|
||||
export const guildModule = lazyLoad<typeof import("./modules/guilds")>("guilds")
|
||||
|
||||
export const UserSettingsModule = lazyLoad<typeof import("./modules/userSettings")>("userSettings")
|
||||
|
||||
export const ConstantsModule = lazyLoad<typeof import("./modules/constants")>("constants")
|
||||
|
||||
export const UserModule = lazyLoad<typeof import("./modules/users")>("users")
|
||||
|
||||
export const CdnModule = lazyLoad<typeof import("./modules/cdn")>("cdn")
|
||||
|
||||
export const AckModule = lazyLoad<typeof import("./modules/acknowledge")>("acknowledge")
|
||||
|
||||
export const DispatcherModule = lazyLoad<typeof import("./modules/dispatcher")>("dispatcher")
|
||||
|
||||
export interface DiscordMessage {
|
||||
guild_id?: Snowflake,
|
||||
attachments: {
|
||||
filename: string,
|
||||
height: number,
|
||||
id: Snowflake,
|
||||
proxy_url: string,
|
||||
size: number,
|
||||
url: string,
|
||||
width: number
|
||||
}[],
|
||||
author: {
|
||||
avatar?: string,
|
||||
discriminator: string,
|
||||
id: Snowflake,
|
||||
username: string,
|
||||
publicFlags?: number
|
||||
},
|
||||
getDMFromUserId(id:string):Snowflake,
|
||||
getDMUserIds():Snowflake[],
|
||||
getFollowerStatsForChannel(id: Snowflake):{
|
||||
loadingStatus: "succeeded"|"failed",
|
||||
lastFetched: number,
|
||||
channelsFollowing: number,
|
||||
guildMembers: number,
|
||||
guildsFollowing: number,
|
||||
usersSeenEver: number,
|
||||
subscribersGainedSinceLastPost: number,
|
||||
subscribersLostSinceLastPost: number
|
||||
channel_id: Snowflake,
|
||||
content: string,
|
||||
edited_timestamp?: number,
|
||||
embeds: any[],
|
||||
flags: number,
|
||||
id: Snowflake,
|
||||
member: {
|
||||
deaf: boolean,
|
||||
hoisted_role?: Snowflake,
|
||||
joined_at: string,
|
||||
mute: boolean,
|
||||
roles: Snowflake[]
|
||||
},
|
||||
getGDMsForRecipients(recipients: Snowflake[]):Set<Snowflake>
|
||||
} = requireModule(e => e.default && e.default.getChannels && e.default.getChannel)
|
||||
export const channelsModule = {
|
||||
getChannel: channelsModuleInternal1.getChannel,
|
||||
getAllChannels: channelsModuleInternal1.getChannels
|
||||
mention_roles: Snowflake[],
|
||||
mentions: Snowflake[],
|
||||
pinned: boolean,
|
||||
timestamp: string,
|
||||
tts: boolean,
|
||||
type: number
|
||||
}
|
||||
|
||||
export interface DiscordUser {
|
||||
createdAt: Date,
|
||||
avatarURL: string,
|
||||
tag: string,
|
||||
hasPremiumSubscription: boolean,
|
||||
id: Snowflake,
|
||||
username: string,
|
||||
usernameNormalized: string,
|
||||
discriminator: string,
|
||||
avatar?: string,
|
||||
email?: string,
|
||||
verified: boolean,
|
||||
bot: boolean,
|
||||
system: boolean,
|
||||
mfaEnabled: boolean,
|
||||
mobile: boolean,
|
||||
desktop: boolean,
|
||||
premiumType?: undefined|1|2,
|
||||
flags: number,
|
||||
publicFlags: number,
|
||||
phone?: string,
|
||||
nsfwAllowed?: boolean,
|
||||
getAvatarURL(format:string):string,
|
||||
getAvatarSource():string,
|
||||
isClaimed(): boolean,
|
||||
isPhoneVerified(): boolean,
|
||||
toString(): string,
|
||||
hasFlag(flag:number):boolean,
|
||||
hasFreePremium():boolean,
|
||||
hasUrgentMessages():boolean,
|
||||
isNonUserBot():boolean,
|
||||
isLocalBot():boolean,
|
||||
isVerifiedBot():boolean,
|
||||
isSystemUser():boolean,
|
||||
isStaff():boolean
|
||||
}
|
||||
|
||||
export interface DiscordUserSettings {
|
||||
locale: string,
|
||||
status: Status,
|
||||
showCurrentGame: boolean,
|
||||
inlineAttachmentMedia: boolean,
|
||||
inlineEmbedMedia: boolean,
|
||||
gifAutoPlay: boolean,
|
||||
renderEmbeds: boolean,
|
||||
renderReactions: boolean,
|
||||
animateEmoji: boolean,
|
||||
showInAppNotifications: boolean,
|
||||
streamNotificationsEnabled: boolean,
|
||||
theme: "dark"|"light",
|
||||
enableTTSCommand: boolean,
|
||||
useRichChatTextBox: boolean,
|
||||
messageDisplayCompact: boolean,
|
||||
convertEmoticons: boolean,
|
||||
renderSpoilers: "ALWAYS"|"ON_CLICK"|"IF_MODERATOR",
|
||||
restrictedGuilds: Snowflake[],
|
||||
defaultGuildsRestricted: boolean,
|
||||
explicitContentFilter: number,
|
||||
friendSourceFlags: {
|
||||
all?: boolean,
|
||||
friends?: boolean,
|
||||
guilds?: boolean
|
||||
},
|
||||
developerMode: boolean,
|
||||
guildPositions: Snowflake[],
|
||||
guildFolders: {
|
||||
guildIds: Snowflake[],
|
||||
folderId?: number,
|
||||
folderName?: string,
|
||||
folderColor?: number
|
||||
},
|
||||
detectPlatformAccounts: boolean,
|
||||
afkTimeout: number,
|
||||
timezoneOffset: number,
|
||||
installShortcutDesktop: boolean,
|
||||
installShortcutStartMenu: boolean,
|
||||
customStatus: {
|
||||
text: string,
|
||||
expires_at: string
|
||||
emoji_id?: string
|
||||
emoji_name?: string
|
||||
},
|
||||
lowQualityImageMode: boolean,
|
||||
allowAccessibilityDetection: boolean,
|
||||
contactSyncEnabled: boolean,
|
||||
nativePhoneIntegrationEnabled: boolean,
|
||||
useSystemTheme: number,
|
||||
disableGamesTab: boolean,
|
||||
expressionPickerWidth: "min"|"max",
|
||||
emojiPickerCollapsedSections: string[],
|
||||
sync: {}
|
||||
}
|
||||
|
||||
export interface DiscordGuild {
|
||||
acronym: string,
|
||||
id: Snowflake,
|
||||
name: string,
|
||||
description?: string,
|
||||
ownerId: Snowflake,
|
||||
icon?: string,
|
||||
splash?: string,
|
||||
banner?: string,
|
||||
features: Set<Feature>,
|
||||
preferredLocale: string,
|
||||
roles: {
|
||||
[ID: string]: DiscordRole
|
||||
},
|
||||
afkChannelId?: Snowflake,
|
||||
afkTimeout: number,
|
||||
systemChannelId?: Snowflake,
|
||||
verificationLevel: number,
|
||||
region: string,
|
||||
joinedAt: Date,
|
||||
defaultMessageNotifications: number,
|
||||
mfaLevel: number,
|
||||
application_id?: Snowflake,
|
||||
explicitContentFilter: number,
|
||||
vanityURLCode?: string,
|
||||
premiumTier: number,
|
||||
premiumSubscriberCount: number,
|
||||
systemChannelFlags: number,
|
||||
discoverySplash?: string,
|
||||
rulesChannelId?: Snowflake,
|
||||
publicUpdatesChannelId?: Snowflake,
|
||||
maxVideoChannelUsers: number,
|
||||
getIconURL(format?: string):string,
|
||||
getIconSource(format?: string):string,
|
||||
getSplashURL(size: number):string,
|
||||
getApplicationId():Snowflake,
|
||||
toString():string,
|
||||
isOwner(user_id: Snowflake):boolean,
|
||||
isOwnerWithRequiredMfaLevel(user_id: Snowflake):boolean,
|
||||
isNew(days: number):boolean,
|
||||
hasFeature(feature: Feature): boolean,
|
||||
getRole(role_id: Snowflake): DiscordRole,
|
||||
getMaxEmojiSlots():number
|
||||
}
|
||||
|
||||
export interface DiscordRole {
|
||||
color: number,
|
||||
hoist: boolean,
|
||||
id: Snowflake,
|
||||
managed: boolean,
|
||||
mentionnable: boolean,
|
||||
name: string,
|
||||
permissions: number,
|
||||
position: number,
|
||||
originalPosition: number,
|
||||
colorString: string
|
||||
}
|
||||
|
||||
export type Feature = "INVITE_SPLASH" | "VIP_REGIONS" | "VANITY_URL" | "VERIFIED" | "PARTNERED" | "PUBLIC" | "COMMERCE" | "NEWS" |
|
||||
"DISCOVERABLE" | "FEATURABLE" | "ANIMATED_ICON" | "BANNER" | "PUBLIC_DISABLED" | "WELCOME_SCREEN_ENABLED"
|
||||
|
||||
export interface DiscordChannel {
|
||||
application_id?: Snowflake,
|
||||
bitrate?: number,
|
||||
|
@ -68,3 +255,12 @@ interface DiscordRecipient {
|
|||
avatar?: string,
|
||||
public_flags: number
|
||||
}
|
||||
|
||||
export interface DiscordGuildMember {
|
||||
userId: Snowflake,
|
||||
nick?: string,
|
||||
roles: DiscordRole[],
|
||||
colorString?: string,
|
||||
hoistRoleId?: Snowflake,
|
||||
premiumSince?: Date
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
const cache = {}
|
||||
|
||||
export function lazyLoad<T>(id:string):T{
|
||||
if(cache[id])return cache[id]
|
||||
|
||||
let mdl = null
|
||||
let setModule = () => {
|
||||
if(!mdl)mdl = require("./modules/"+id)
|
||||
}
|
||||
|
||||
const handlers:ProxyHandler<{}> = {
|
||||
get(target, prop){
|
||||
setModule()
|
||||
return mdl[prop]
|
||||
},
|
||||
set(target, prop, value){
|
||||
setModule()
|
||||
mdl[prop] = value
|
||||
return true
|
||||
},
|
||||
apply(target, thisArg, args){
|
||||
setModule()
|
||||
mdl.apply(this, args)
|
||||
},
|
||||
construct(target, args){
|
||||
setModule()
|
||||
const prototype = Object.create(mdl.prototype)
|
||||
handlers.apply(target, prototype, args)
|
||||
return prototype
|
||||
}
|
||||
}
|
||||
let proxy = new Proxy({}, handlers)
|
||||
|
||||
return cache[id] = proxy as T
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { requireModule } from "../DiscordToModules"
|
||||
import { Snowflake } from "../.."
|
||||
|
||||
let acknowledgeModuleInternal1:{
|
||||
bulkAck(channels:{
|
||||
channelId: Snowflake,
|
||||
messageId: Snowflake
|
||||
}[]):void
|
||||
} = requireModule(e => e && e.bulkAck)
|
||||
|
||||
export = {
|
||||
bulkAck: acknowledgeModuleInternal1.bulkAck
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import { requireModule } from "../DiscordToModules"
|
||||
import { Snowflake } from "../.."
|
||||
|
||||
let cdnModuleInternal1:{
|
||||
getUserAvatarURL(user:{
|
||||
id: Snowflake,
|
||||
avatar: string,
|
||||
discriminator: string,
|
||||
bot: boolean
|
||||
}, format?:string, size?: number):string,
|
||||
getGuildSplashURL(infos:{
|
||||
id: Snowflake,
|
||||
splash: string,
|
||||
size?: number
|
||||
}): string,
|
||||
getGuildBannerURL(infos:{
|
||||
id: Snowflake,
|
||||
banner: string
|
||||
}): string
|
||||
} = requireModule(e => e.default && e.default.getGuildSplashURL)
|
||||
|
||||
let cdnModuleInternal2:{
|
||||
DEFAULT_AVATARS: string[]
|
||||
} = requireModule(e => e.default && e.default.DEFAULT_AVATARS)
|
||||
|
||||
export = {
|
||||
getUserAvatarURL: cdnModuleInternal1.getUserAvatarURL,
|
||||
getGuildSplashURL: cdnModuleInternal1.getGuildSplashURL,
|
||||
getGuildBannerURL: cdnModuleInternal1.getGuildBannerURL,
|
||||
|
||||
getDefaultAvatarURL(discriminator){
|
||||
let asset = cdnModuleInternal2.DEFAULT_AVATARS[(typeof discriminator === "string" ? parseInt(discriminator) || 0 : isNaN(discriminator) ? 0 : discriminator) % cdnModuleInternal2.DEFAULT_AVATARS.length]
|
||||
return `${location.protocol}://${window["GLOBAL_ENV"].ASSET_ENDPOINT}/assets/${asset}`
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import {requireModule, DiscordChannel} from "../DiscordToModules"
|
||||
import { Snowflake } from "../.."
|
||||
|
||||
let channelsModuleInternal1:{
|
||||
getChannel(id:Snowflake): DiscordChannel,
|
||||
getChannels(): {
|
||||
[k:string]: DiscordChannel
|
||||
},
|
||||
getDMFromUserId(id:string):Snowflake,
|
||||
getDMUserIds():Snowflake[],
|
||||
getFollowerStatsForChannel(id: Snowflake):{
|
||||
loadingStatus: "succeeded"|"failed",
|
||||
lastFetched: number,
|
||||
channelsFollowing: number,
|
||||
guildMembers: number,
|
||||
guildsFollowing: number,
|
||||
usersSeenEver: number,
|
||||
subscribersGainedSinceLastPost: number,
|
||||
subscribersLostSinceLastPost: number
|
||||
},
|
||||
getGDMsForRecipients(recipients: Snowflake[]):Set<Snowflake>
|
||||
} = requireModule(e => e.default && e.default.getChannels && e.default.getChannel)
|
||||
|
||||
let channelsModuleInternal2:{
|
||||
deleteChannel(id: Snowflake):void
|
||||
}
|
||||
|
||||
let channelsModuleInternal3:{
|
||||
hasUnread(channel_id:Snowflake):boolean,
|
||||
hasCategoryUnread(channel_id:Snowflake):boolean,
|
||||
getUnreadCount(channel_id:Snowflake):number,
|
||||
getMentionCount(channel_id:Snowflake):number,
|
||||
ackMessageId(channel_id:Snowflake):Snowflake,
|
||||
lastMessageId(channel_id:Snowflake):Snowflake,
|
||||
getOldestUnreadMessageId(channel_id:Snowflake):Snowflake,
|
||||
getOldestUnreadTimestamp(channel_id:Snowflake):number,
|
||||
isEstimated(channel_id:Snowflake):boolean,
|
||||
hasUnreadPins(channel_id:Snowflake):boolean,
|
||||
getAllReadStates()
|
||||
} = requireModule(e => e.default && e.default.lastMessageId)
|
||||
|
||||
function set3(){
|
||||
if(channelsModuleInternal3)return
|
||||
channelsModuleInternal3 = requireModule(e => e.default && e.default.lastMessageId)
|
||||
}
|
||||
|
||||
export = {
|
||||
getChannel: channelsModuleInternal1.getChannel,
|
||||
getAllChannels: channelsModuleInternal1.getChannels,
|
||||
get delete():typeof channelsModuleInternal2.deleteChannel{
|
||||
return channelsModuleInternal2 ? channelsModuleInternal2.deleteChannel : (channelsModuleInternal2 = requireModule(e => e.default && e.default.deleteChannel), channelsModuleInternal2.deleteChannel)
|
||||
},
|
||||
|
||||
get lastMessageId(){
|
||||
set3()
|
||||
return channelsModuleInternal3.lastMessageId
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import { requireModule } from "../DiscordToModules";
|
||||
|
||||
export = requireModule(e => e.API_HOST)
|
|
@ -0,0 +1,48 @@
|
|||
import { requireModule } from "../DiscordToModules";
|
||||
|
||||
export = requireModule(m=>m.Dispatcher&&m.default&&m.default.dispatch) as {
|
||||
_subscriptions: any,
|
||||
_waitQueue: (() => void)[],
|
||||
_processingWaitQueue: boolean,
|
||||
_currentDispatchActionType: string | null,
|
||||
_orderedActionHandlers: any,
|
||||
_orderedCallbackTokens: any,
|
||||
_lastID: number,
|
||||
_dependencyGraph: any
|
||||
|
||||
isDispatching():boolean,
|
||||
/**
|
||||
* If the dispatcher isn't dispatching, then dispatch
|
||||
*/
|
||||
maybeDispatch(event: {type: string, [k: string]:any}):void,
|
||||
/**
|
||||
* Wait until the dispatcher finished dispatching, then dispatch
|
||||
*/
|
||||
dirtyDispatch(event: {type: string, [k: string]:any}):void,
|
||||
/**
|
||||
* dispatch
|
||||
*/
|
||||
dispatch(event: {type: string, [k: string]:any}):void,
|
||||
/** Same as dispatcher.dispatch */
|
||||
_dispatch(event: {type: string, [k: string]:any}):void,
|
||||
/**
|
||||
* Intercept events before they happens, if returning true, then the event will be blocked from dispatching.
|
||||
*/
|
||||
setInterceptor(interceptor: (event) => boolean):void,
|
||||
/**
|
||||
* Wait until the dispatcher has finished dispatching
|
||||
*/
|
||||
wait(waiting: () => void):void,
|
||||
/** Subscribe to an event */
|
||||
subscribe(event: string, listener: (event: {type: string, [k: string]:any}) => void):void,
|
||||
/**
|
||||
* Unsubscribe from the event.
|
||||
*/
|
||||
unsubscribe(event: string, listener: (event: {type: string, [k: string]:any}) => void):void,
|
||||
register(name: string, actionHandler: any, storeDidChange: any):void
|
||||
addDependencies,
|
||||
_invalidateCaches,
|
||||
_processWaitQueue,
|
||||
_computeOrderedActionHandlers,
|
||||
_computeOrderedCallbackTokens
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
import { DiscordGuild, requireModule, DiscordGuildMember } from "../DiscordToModules"
|
||||
import { Snowflake } from "../.."
|
||||
|
||||
let guildModuleInternal1:{
|
||||
getGuilds():{
|
||||
[k:string]:DiscordGuild
|
||||
},
|
||||
getGuild(id: Snowflake):DiscordGuild
|
||||
} = requireModule(e => e.default && e.default.getGuilds && e.default.getGuild && !e.default.isFetching)
|
||||
|
||||
let guildModuleInternal2:{
|
||||
getMemberCount(id:Snowflake):number,
|
||||
getMemberCounts():{
|
||||
[k:string]:number
|
||||
}
|
||||
} = requireModule(e => e.default && e.default.getMemberCounts && e.default.getMemberCount)
|
||||
|
||||
let guildModuleInternal3:{
|
||||
getAllGuildsAndMembers():{
|
||||
[guild_id:string]: {
|
||||
[user_id:string]: DiscordGuildMember
|
||||
}
|
||||
},
|
||||
memberOf(user_id:Snowflake):Snowflake[],
|
||||
getNicknames(user_id:Snowflake):string[],
|
||||
isMember(guild_id:Snowflake, user_id:Snowflake):boolean,
|
||||
getMemberIds(guild_id:Snowflake):Snowflake[],
|
||||
getMembers(guild_id:Snowflake):DiscordGuildMember[],
|
||||
getKeyedMembers(guild_id:Snowflake): {
|
||||
[user_id:string]: DiscordGuildMember
|
||||
},
|
||||
getMember(guild_id:Snowflake, user_id:Snowflake):DiscordGuildMember,
|
||||
getNick(guild_id:Snowflake, user_id:Snowflake):string
|
||||
} = requireModule(e => e.default && e.default.getMembers)
|
||||
|
||||
type guildState = {
|
||||
suppress_everyone: boolean,
|
||||
suppress_roles: boolean,
|
||||
mobile_push: boolean,
|
||||
muted: boolean,
|
||||
message_notifications: 0|1|2,
|
||||
channel_overrides: {
|
||||
[channel_id:string]: {
|
||||
channel_id: Snowflake,
|
||||
message_notifications: 0|1|2|3,
|
||||
mute_config: {
|
||||
end_time?: string,
|
||||
selected_time_window: number
|
||||
},
|
||||
muted: boolean
|
||||
}
|
||||
},
|
||||
guild_id?: Snowflake,
|
||||
mute_config: {
|
||||
end_time?: string,
|
||||
selected_time_window: number
|
||||
},
|
||||
version: 26,
|
||||
}
|
||||
let guildModuleInternal4:{
|
||||
getState():{
|
||||
collapsedGuilds:any,
|
||||
userGuildSettings:{
|
||||
null: guildState,
|
||||
[guild_id:string]: guildState
|
||||
}
|
||||
},
|
||||
sSuppressEveryoneEnabled(guild_id:Snowflake):boolean,
|
||||
isSuppressRolesEnabled(guild_id:Snowflake):boolean,
|
||||
isSuppressRolesEnabled(guild_id:Snowflake):boolean,
|
||||
isMuted(guild_id:Snowflake):boolean,
|
||||
getMuteConfig(guild_id:Snowflake):guildState["mute_config"],
|
||||
getMessageNotifications(guild_id:Snowflake):0|1|2,
|
||||
getChannelOverrides(guild_id:Snowflake):guildState["channel_overrides"],
|
||||
getChannelMessageNotifications(guild_id:Snowflake, channel_id:Snowflake):0|1|2|3,
|
||||
getChannelMuteConfig(guild_id:Snowflake, channel_id:Snowflake):guildState["channel_overrides"]["id"]["mute_config"],
|
||||
getMutedChannels(guild_id:Snowflake):Set<Snowflake>,
|
||||
isChannelMuted(guild_id:Snowflake, channel_id:Snowflake):boolean,
|
||||
_isCategoryMuted(guild_id:Snowflake, channel_id:Snowflake):boolean,
|
||||
_resolvedMessageNotifications(infos:{
|
||||
guild_id: Snowflake,
|
||||
id: Snowflake,
|
||||
parent_id?: Snowflake
|
||||
}):0|1|2,
|
||||
isGuildOrCategoryOrChannelMuted(guild_id: Snowflake, channel_id: Snowflake):boolean,
|
||||
allowNoMessages(infos:{
|
||||
guild_id: Snowflake,
|
||||
id: Snowflake,
|
||||
parent_id?: Snowflake
|
||||
}):boolean,
|
||||
(infos:{
|
||||
guild_id: Snowflake,
|
||||
id: Snowflake,
|
||||
parent_id?: Snowflake
|
||||
}):boolean,
|
||||
isGuildCollapsed(guild_id: Snowflake):boolean,
|
||||
getAllSettings(): {
|
||||
userGuildSettings: {
|
||||
null: guildState,
|
||||
[guild_id:string]: guildState
|
||||
},
|
||||
mutedChannels: {
|
||||
null: Set<Snowflake>,
|
||||
[guild_id:string]: Set<Snowflake>
|
||||
},
|
||||
collapsedGuilds: any
|
||||
}
|
||||
} = requireModule(e => e.default && e.default.isGuildOrCategoryOrChannelMuted)
|
||||
|
||||
let guildModuleInternal5:{
|
||||
kickUser(guild_id:Snowflake, user_id:Snowflake, reason:string):Promise<any>
|
||||
banUser(guild_id:Snowflake, user_id:Snowflake, days:number, reason:string):Promise<any>
|
||||
} = requireModule(e => e.default && e.default.banUser)
|
||||
|
||||
export = {
|
||||
getAllGuilds: guildModuleInternal1.getGuilds,
|
||||
getGuild: guildModuleInternal1.getGuild,
|
||||
|
||||
getMemberCount: guildModuleInternal2.getMemberCount,
|
||||
getMemberCounts: guildModuleInternal2.getMemberCounts,
|
||||
|
||||
getMembers: guildModuleInternal3.getMembers,
|
||||
getMember: guildModuleInternal3.getMember,
|
||||
getMemberIds: guildModuleInternal3.getMemberIds,
|
||||
isMember: guildModuleInternal3.isMember,
|
||||
memberOf: guildModuleInternal3.memberOf,
|
||||
getNick: guildModuleInternal3.getNick,
|
||||
|
||||
getMessageNotifications: guildModuleInternal4.getMessageNotifications,
|
||||
getNotificationsState: guildModuleInternal4.getState,
|
||||
|
||||
banUser: guildModuleInternal5.banUser,
|
||||
kickUser: guildModuleInternal5.kickUser
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import { requireModule, DiscordUserSettings } from "../DiscordToModules";
|
||||
import { Snowflake } from "../..";
|
||||
|
||||
let userSettingModuleInternal1:{
|
||||
isGuildRestricted(guild_id:Snowflake):boolean,
|
||||
getAllSettings():DiscordUserSettings
|
||||
} = requireModule(e => e.default && e.default.isGuildRestricted)
|
||||
|
||||
let userSettingModuleInternal2:{
|
||||
updateRemoteSettings(settings:Partial<DiscordUserSettings>):any,
|
||||
updateLocalSettings(settings:Partial<DiscordUserSettings>):void
|
||||
} = requireModule(e => e.default && e.default.updateLocalSettings)
|
||||
|
||||
export = {
|
||||
getAllSettings: userSettingModuleInternal1.getAllSettings,
|
||||
getSetting: (setting) => {
|
||||
return userSettingModuleInternal1.getAllSettings()[setting]
|
||||
},
|
||||
|
||||
...userSettingModuleInternal2
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import { requireModule, DiscordUser } from "../DiscordToModules";
|
||||
import { Snowflake } from "../..";
|
||||
|
||||
let userModuleInteral1:{
|
||||
getUser(user_id: Snowflake):DiscordUser,
|
||||
getUsers():{
|
||||
[user_id:string]: DiscordUser
|
||||
},
|
||||
forEach(callbackfn: (user:DiscordUser) => void):void,
|
||||
findByTag(username:string, discriminator:string):DiscordUser,
|
||||
filter(filterdn: (user:DiscordUser) => boolean, sort?:boolean):DiscordUser[],
|
||||
getCurrentUser():DiscordUser,
|
||||
getNullableCurrentUser():DiscordUser
|
||||
} = requireModule(e => e.default && e.default.getUser)
|
||||
|
||||
let userModuleInteral2:{
|
||||
getNote(user_id: Snowflake):{
|
||||
loading: boolean,
|
||||
note?: string
|
||||
}
|
||||
} = requireModule(e => e.default && e.default.getNote)
|
||||
|
||||
export = {
|
||||
getUser: userModuleInteral1.getUser,
|
||||
getUsers: userModuleInteral1.getUsers,
|
||||
forEach: userModuleInteral1.forEach,
|
||||
findByTag: userModuleInteral1.findByTag,
|
||||
filter: userModuleInteral1.filter,
|
||||
getCurrentUser: userModuleInteral1.getCurrentUser,
|
||||
getNullableCurrentUser: userModuleInteral1.getNullableCurrentUser,
|
||||
|
||||
getNote: userModuleInteral2.getNote
|
||||
}
|
|
@ -1,15 +1,42 @@
|
|||
import { DiscordChannel } from "./DiscordToModules"
|
||||
import { Channel } from "..";
|
||||
import { DiscordChannel, DiscordGuild, DiscordGuildMember, DiscordRole, DiscordMessage, DiscordUser } from "./DiscordToModules"
|
||||
import { Channel, Snowflake } from "..";
|
||||
import BaseChannel from "../structures/BaseChannel";
|
||||
import Guild from "../structures/Guild";
|
||||
import { TextChannel } from "../structures/TextChannel";
|
||||
import GuildMember from "../structures/GuildMember";
|
||||
import Role from "../structures/Role";
|
||||
import User from "../structures/User";
|
||||
import Message from "../structures/Message";
|
||||
|
||||
export function createChannel(channel:DiscordChannel):Channel{
|
||||
let constructor = channels[channel.type]
|
||||
let constructor = channels[channel.type] || BaseChannel
|
||||
return new constructor(channel)
|
||||
}
|
||||
|
||||
const channels:(new(channel:DiscordChannel) => Channel)[] = [
|
||||
TextChann
|
||||
TextChannel
|
||||
]
|
||||
|
||||
export function createGuild(guild:DiscordGuild):Guild{
|
||||
return new Guild(guild)
|
||||
}
|
||||
|
||||
export function createGuildMember(member:DiscordGuildMember):GuildMember{
|
||||
return new GuildMember(member)
|
||||
}
|
||||
|
||||
export function createRole(role:DiscordRole):Role{
|
||||
return new Role(role)
|
||||
}
|
||||
|
||||
export function createMessage(message:DiscordMessage):Message{
|
||||
return new Message(message)
|
||||
}
|
||||
|
||||
export function createUser(user:DiscordUser):User{
|
||||
return new User(user)
|
||||
}
|
||||
|
||||
export function applyMixins(derivedCtor: any, baseCtors: any[]) {
|
||||
baseCtors.forEach(baseCtor => {
|
||||
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
|
||||
|
@ -69,3 +96,16 @@ export function binaryToID(num:string):string {
|
|||
|
||||
return dec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export type UserResolvable = User | Snowflake | Message | Guild | GuildMember
|
||||
|
||||
export function resolveUserID(user:UserResolvable){
|
||||
if(typeof user === "string")return user // ID
|
||||
if(user instanceof User)return user.id // User
|
||||
if(user instanceof Message)return user.author.id // Message Author
|
||||
if(user instanceof Guild)return user.ownerID // Guild
|
||||
if(user instanceof GuildMember)return user.id // GuildMember
|
||||
return null
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
const path = require("path");
|
||||
//const CircularDependencyPlugin = require("circular-dependency-plugin");
|
||||
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
target: "node",
|
||||
devtool: "inline-source-map",
|
||||
entry: "./src/index.ts",
|
||||
output: {
|
||||
filename: "main.js",
|
||||
path: path.resolve(__dirname, "js"),
|
||||
library: "LightcordApi",
|
||||
libraryTarget: "commonjs2"
|
||||
},
|
||||
externals: {
|
||||
electron: `electron`,
|
||||
fs: `fs`,
|
||||
path: `path`,
|
||||
events: `events`,
|
||||
rimraf: `rimraf`,
|
||||
yauzl: `yauzl`,
|
||||
mkdirp: `mkdirp`,
|
||||
request: `request`,
|
||||
"node-fetch": "node-fetch",
|
||||
"uuid/v1": "uuid/v1",
|
||||
"uuid/v4": "uuid/v4"
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".js", ".jsx", ".json", ".ts", ".tsx"],
|
||||
alias: {
|
||||
"react$": path.resolve(__dirname, "src", "alias", "react.ts"),
|
||||
"react-dom$": path.resolve(__dirname, "src", "alias", "react-dom.ts")
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.jsx?$/,
|
||||
loader: "babel-loader",
|
||||
exclude: /node_modules/,
|
||||
query: {
|
||||
presets: [
|
||||
["@babel/env", {
|
||||
targets: {
|
||||
node: "12.8.1",
|
||||
chrome: "78"
|
||||
}
|
||||
}], "@babel/react"
|
||||
]
|
||||
}
|
||||
}, {
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
}]
|
||||
}
|
||||
};
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,9 @@ import TextInput from "./inputs/TextInput"
|
|||
import Dropdown from "./inputs/Dropdown"
|
||||
import Title from "./general/Title"
|
||||
import SettingsTitle from "./general/SettingsTitle"
|
||||
import Tabs, { Tab } from "./general/Tabs"
|
||||
import SettingSubTitle from "./general/SettingSubTitle"
|
||||
import CodeBlock from "./general/CodeBlock"
|
||||
|
||||
export default {
|
||||
inputs: {
|
||||
|
@ -19,6 +22,9 @@ export default {
|
|||
},
|
||||
general: {
|
||||
Title: Title,
|
||||
SettingsTitle: SettingsTitle
|
||||
SettingsTitle: SettingsTitle,
|
||||
SettingSubTitle: SettingSubTitle,
|
||||
Tabs: Tabs,
|
||||
CodeBlock: CodeBlock
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
|
||||
type CodeBlockProps = {
|
||||
language?: string,
|
||||
content: string
|
||||
}
|
||||
|
||||
let CodeBlockModules
|
||||
export default class CodeBlock extends React.Component<CodeBlockProps> {
|
||||
static defaultProps:CodeBlockProps = {
|
||||
language: "plaintext",
|
||||
content: ""
|
||||
}
|
||||
|
||||
get modules(){
|
||||
return CodeBlockModules || (CodeBlockModules = [
|
||||
WebpackLoader.find(e => e.markup),
|
||||
WebpackLoader.find(e => e.messageContent),
|
||||
WebpackLoader.find(e => e.scrollbarGhostHairline),
|
||||
WebpackLoader.find(e => e.highlight),
|
||||
WebpackLoader.find(e => e.marginBottom8)
|
||||
])
|
||||
}
|
||||
|
||||
render(){
|
||||
let [
|
||||
messageModule1,
|
||||
messageModule2,
|
||||
scrollbarModule1,
|
||||
hightlightJS,
|
||||
marginModule1
|
||||
] = this.modules
|
||||
|
||||
const code = this.props.language === "plaintext" ? <code className={`${scrollbarModule1.scrollbarGhostHairline} hljs`}>
|
||||
{this.props.content}
|
||||
</code> : <code className={`${scrollbarModule1.scrollbarGhostHairline} hljs`}
|
||||
dangerouslySetInnerHTML={{__html: hightlightJS.highlight(this.props.language, this.props.content).value}} />
|
||||
return (<div className={`${messageModule1.markup} ${messageModule2.messageContent}`}>
|
||||
<pre>
|
||||
{code}
|
||||
</pre>
|
||||
<div className={marginModule1.marginBottom8}></div>
|
||||
</div>)
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([
|
||||
{
|
||||
content: "console.log(\"Exemple code\")"
|
||||
}
|
||||
])
|
||||
AllPreviews.push([
|
||||
{
|
||||
language: "js"
|
||||
},
|
||||
{
|
||||
language: "plaintext"
|
||||
},
|
||||
...CodeBlock.prototype.modules[3].listLanguages().filter(e => e !== "js").map(e => ({language: e}))
|
||||
])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -0,0 +1,67 @@
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
|
||||
type CodeBlockProps = {
|
||||
language?: string,
|
||||
content: string
|
||||
}
|
||||
|
||||
let CodeBlockModules
|
||||
export default class CodeBlock extends React.Component<CodeBlockProps> {
|
||||
static defaultProps:CodeBlockProps = {
|
||||
language: "plaintext",
|
||||
content: ""
|
||||
}
|
||||
|
||||
get modules(){
|
||||
return CodeBlockModules || (CodeBlockModules = [
|
||||
WebpackLoader.find(e => e.markup),
|
||||
WebpackLoader.find(e => e.messageContent),
|
||||
WebpackLoader.find(e => e.scrollbarGhostHairline),
|
||||
WebpackLoader.find(e => e.highlight),
|
||||
WebpackLoader.find(e => e.marginBottom8)
|
||||
])
|
||||
}
|
||||
|
||||
render(){
|
||||
let [
|
||||
messageModule1,
|
||||
messageModule2,
|
||||
scrollbarModule1,
|
||||
hightlightJS,
|
||||
marginModule1
|
||||
] = this.modules
|
||||
|
||||
const code = this.props.language === "plaintext" ? <code className={`${scrollbarModule1.scrollbarGhostHairline} hljs`}>
|
||||
{this.props.content}
|
||||
</code> : <code className={`${scrollbarModule1.scrollbarGhostHairline} hljs`}
|
||||
dangerouslySetInnerHTML={{__html: hightlightJS.highlight(this.props.language, this.props.content).value}} />
|
||||
return (<div className={`${messageModule1.markup} ${messageModule2.messageContent}`}>
|
||||
<pre>
|
||||
{code}
|
||||
</pre>
|
||||
<div className={marginModule1.marginBottom8}></div>
|
||||
</div>)
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([
|
||||
{
|
||||
content: "console.log(\"Exemple code\")"
|
||||
}
|
||||
])
|
||||
AllPreviews.push([
|
||||
{
|
||||
language: "js"
|
||||
},
|
||||
{
|
||||
language: "plaintext"
|
||||
},
|
||||
...CodeBlock.prototype.modules[3].listLanguages().filter(e => e !== "js").map(e => ({language: e}))
|
||||
])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -0,0 +1,54 @@
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
import { ReactNode } from "react"
|
||||
import Utils from "../../modules/Utils"
|
||||
|
||||
type SettingSubTitleProps = {
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
let TitleModules
|
||||
export default class SettingSubTitle extends React.Component<SettingSubTitleProps> {
|
||||
static defaultProps:SettingSubTitleProps = {
|
||||
children: [],
|
||||
className: ""
|
||||
}
|
||||
|
||||
get modules(){
|
||||
return TitleModules || (TitleModules = [
|
||||
WebpackLoader.find(e => typeof e.marginTop60 === "string"),
|
||||
WebpackLoader.findByUniqueProperties(["h5"]),
|
||||
window.Lightcord.Api.WebpackLoader.findByUniqueProperties(["size14"]),
|
||||
window.Lightcord.Api.WebpackLoader.findByUniqueProperties(["colorStandard"])
|
||||
])
|
||||
}
|
||||
|
||||
render(){
|
||||
let [
|
||||
marginModule,
|
||||
titleModule,
|
||||
sizeModule,
|
||||
colorModule
|
||||
] = this.modules
|
||||
|
||||
let props = this.props
|
||||
|
||||
let className = `${colorModule.colorStandard} ${sizeModule.size14} ${titleModule.h5} ${marginModule.marginBottom4}`
|
||||
if(props.className)className =+ " "+props.className
|
||||
|
||||
return React.createElement("h5", {className}, props.children)
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([
|
||||
{
|
||||
children: "Exemple title"
|
||||
}
|
||||
])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -1,7 +1,6 @@
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
import Title from "./Title"
|
||||
import { ReactNode } from "react"
|
||||
import Utils from "../../modules/Utils"
|
||||
|
||||
type SettingsTitleProps = {
|
||||
children: ReactNode
|
||||
|
@ -9,25 +8,9 @@ type SettingsTitleProps = {
|
|||
}
|
||||
|
||||
let TitleModules
|
||||
export default class SettingsTitle extends React.Component<SettingsTitleProps, SettingsTitleProps> {
|
||||
export default class SettingsTitle extends React.Component<SettingsTitleProps> {
|
||||
constructor(props: SettingsTitleProps){
|
||||
super(props)
|
||||
props = SettingsTitle.normalizeProps(props)
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
|
||||
static normalizeProps(props: SettingsTitleProps):SettingsTitleProps{
|
||||
props = Object.create(props)
|
||||
if(!props || typeof props !== "object")props = {children: []}
|
||||
if(typeof props.className !== "string")delete props.className
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
}
|
||||
|
||||
get modules(){
|
||||
|
@ -41,14 +24,29 @@ export default class SettingsTitle extends React.Component<SettingsTitleProps, S
|
|||
marginModule
|
||||
] = this.modules
|
||||
|
||||
let props = SettingsTitle.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
let props = this.props
|
||||
|
||||
let className = `${marginModule.marginTop60} ${marginModule.marginBottom20}`
|
||||
if(props.className)className =+ " "+props.className
|
||||
|
||||
return React.createElement(Title, {className}, props.children)
|
||||
}
|
||||
|
||||
static defaultProps:SettingsTitleProps = {
|
||||
children: [""],
|
||||
className: ""
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([
|
||||
{
|
||||
children: "Exemple title"
|
||||
}
|
||||
])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -0,0 +1,139 @@
|
|||
import { ReactNode } from "react"
|
||||
import NOOP from "../../modules/noop"
|
||||
import Title from "./Title"
|
||||
|
||||
|
||||
export default class Tabs extends React.Component<{
|
||||
children?: ReactNode,
|
||||
tabs: {label: string, id: string}[],
|
||||
active?: string
|
||||
onChange?: (tab: string) => void
|
||||
}, {
|
||||
active: string
|
||||
}> {
|
||||
static defaultProps = {
|
||||
children: null,
|
||||
tabs: {label: "No tabs was passed to <Tabs>.", id: "none"},
|
||||
active: null,
|
||||
onChange: NOOP
|
||||
}
|
||||
|
||||
constructor(props){
|
||||
super(props)
|
||||
this.state = {
|
||||
active: this.props.active || null
|
||||
}
|
||||
}
|
||||
|
||||
tabsElements:Tab[] = []
|
||||
|
||||
get tabs():Tabs["props"]["tabs"]{
|
||||
return this.props.tabs || []
|
||||
}
|
||||
|
||||
changeTab(tab:string){
|
||||
if(tab === this.state.active)return
|
||||
if(this.props.onChange)this.props.onChange(tab)
|
||||
this.setState({
|
||||
active: tab
|
||||
})
|
||||
this.tabsElements.forEach(e => e.setActive(tab === e.props.id))
|
||||
}
|
||||
|
||||
render(){
|
||||
return (<div className="lc-tabWrapper">
|
||||
<div className="lc-tabnav" style={{flex: "0 1 auto"}}>
|
||||
{this.tabs.map(tab => {
|
||||
return React.createElement(Tab, {TabContainer: this, title: tab.label, id: tab.id, key: btoa(tab.label+":"+tab.id)})
|
||||
})}
|
||||
</div>
|
||||
<div className="lc-tab">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
|
||||
isActive(tab){
|
||||
return this.state.active === tab
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([
|
||||
{
|
||||
children: (<div style={{marginTop: "20px", marginBottom: "20px"}}>
|
||||
<div style={{
|
||||
backgroundColor: "var(--background-primary)",
|
||||
padding: "30px 30px",
|
||||
borderRadius: "8px"
|
||||
}} className="lc-tab-box-shadow">
|
||||
<Title>Preview tabs</Title>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
], [
|
||||
{
|
||||
tabs: [
|
||||
{
|
||||
label: "Active tab",
|
||||
id: "1"
|
||||
},
|
||||
{
|
||||
label: "Unactive tab",
|
||||
id: "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
], [
|
||||
{
|
||||
active: "1"
|
||||
}
|
||||
], [
|
||||
{
|
||||
onChange: (tabId) => {}
|
||||
}
|
||||
])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
||||
|
||||
export class Tab extends React.Component<{
|
||||
TabContainer: Tabs,
|
||||
title: string,
|
||||
id: string
|
||||
}, {
|
||||
active: boolean
|
||||
}> {
|
||||
constructor(props){
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
active: props.TabContainer.isActive(props.id)
|
||||
}
|
||||
|
||||
this.props.TabContainer.tabsElements.push(this)
|
||||
}
|
||||
|
||||
setActive(isActive:boolean){
|
||||
this.setState({
|
||||
active: !!isActive
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
let className = `lc-navItem`
|
||||
if(this.state.active){
|
||||
className += ` lc-navItemActive`
|
||||
}else{
|
||||
className += ` lc-navItemInactive`
|
||||
}
|
||||
return (<div className={className} onClick={()=>{
|
||||
this.props.TabContainer.changeTab(this.props.id)
|
||||
}}>
|
||||
{this.props.title}
|
||||
</div>)
|
||||
}
|
||||
}
|
|
@ -9,32 +9,9 @@ type TitleProps = {
|
|||
}
|
||||
|
||||
let TitleModules
|
||||
export default class Title extends React.Component<TitleProps, TitleProps> {
|
||||
export default class Title extends React.Component<TitleProps> {
|
||||
constructor(props: TitleProps){
|
||||
super(props)
|
||||
props = Title.normalizeProps(props)
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
|
||||
_key: string
|
||||
|
||||
get key(){
|
||||
return this._key || uuid()
|
||||
}
|
||||
|
||||
static normalizeProps(props: TitleProps):TitleProps{
|
||||
props = Object.create(props)
|
||||
if(!props || typeof props !== "object")props = {children: []}
|
||||
if(!props.children)props.children = []
|
||||
if(typeof props.className !== "string")props.className = ""
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
}
|
||||
|
||||
get modules(){
|
||||
|
@ -52,14 +29,29 @@ export default class Title extends React.Component<TitleProps, TitleProps> {
|
|||
titleModule
|
||||
] = this.modules
|
||||
|
||||
let props = Title.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = props
|
||||
}
|
||||
let props = this.props
|
||||
|
||||
let className = `${colorModule.colorStandard} ${sizeModule.size14} ${titleModule.h2} ${titleModule.defaultColor} ${titleModule.defaultMarginh2}`
|
||||
if(props.className)className += " "+props.className
|
||||
|
||||
return React.createElement("h2", {className, key: this.key}, props.children)
|
||||
return React.createElement("h2", {className}, props.children)
|
||||
}
|
||||
|
||||
static defaultProps:TitleProps = {
|
||||
children: null,
|
||||
className: null
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([
|
||||
{
|
||||
children: "Exemple title"
|
||||
}
|
||||
])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -1,29 +1,31 @@
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
import { MouseEventHandler } from "react"
|
||||
import { MouseEventHandler, ReactNode } from "react"
|
||||
|
||||
let ButtonModules
|
||||
export default class Button extends React.Component<{
|
||||
text: string,
|
||||
onClick: MouseEventHandler,
|
||||
color?: ButtonColor
|
||||
}> {
|
||||
constructor(props:{
|
||||
text: string,
|
||||
onClick: MouseEventHandler,
|
||||
color?: ButtonColor
|
||||
}){
|
||||
if(props.color){
|
||||
props.color = props.color.toLowerCase() as ButtonColor
|
||||
if(!["brand", "grey", "red", "green", "yellow", "primary", "link", "white", "black", "transparent"].includes(props.color)){
|
||||
props.color = "brand"
|
||||
}
|
||||
}else{
|
||||
props.color = "brand"
|
||||
}
|
||||
props.onClick = typeof props.onClick === "function" ? props.onClick : () => {}
|
||||
|
||||
type ButtonProps = {
|
||||
children?: ReactNode,
|
||||
onClick?: MouseEventHandler,
|
||||
color?: ButtonColor,
|
||||
wrapper?: boolean,
|
||||
look?: ButtonLook,
|
||||
size?: ButtonSize,
|
||||
hoverColor?: ButtonHovers
|
||||
}
|
||||
export default class Button extends React.Component<ButtonProps, {hover: boolean}> {
|
||||
constructor(props:ButtonProps){
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
hover: false
|
||||
}
|
||||
}
|
||||
|
||||
static Colors:ButtonColor[] = ["brand", "grey", "red", "green", "yellow", "primary", "link", "white", "black", "transparent"]
|
||||
static Looks:ButtonLook[] = ["filled", "inverted", "outlined", "ghost", "link", "blank"]
|
||||
static Sizes:ButtonSize[] = ["small", "medium", "large", "xlarge", "min", "max", "icon", "none"]
|
||||
static HoverColors: ButtonHovers[] = ["default", ...Button.Colors]
|
||||
|
||||
get modules(){ // caching modules
|
||||
return ButtonModules || (ButtonModules = [
|
||||
WebpackLoader.findByUniqueProperties(["_horizontal"]),
|
||||
|
@ -41,20 +43,140 @@ export default class Button extends React.Component<{
|
|||
colorsModule,
|
||||
] = this.modules
|
||||
|
||||
return (<div className={buttonModule.buttonWrapper}>
|
||||
<button type="button" className={`${flexModule.flexChild} ${euhModule1.button} ${euhModule1.lookFilled} ${colorsModule.ButtonColors[this.props.color.toUpperCase()]} ${euhModule1.sizeSmall} ${euhModule1.grow}`} style={{flex: "0 1 auto"}} onClick={this.props.onClick}>
|
||||
<div className={euhModule1.contents}>{this.props.text}</div>
|
||||
</button>
|
||||
</div>)
|
||||
let props:ButtonProps = {}
|
||||
if(this.props){
|
||||
if("color" in this.props){
|
||||
props.color = this.props.color
|
||||
}
|
||||
if("children" in this.props){
|
||||
props.children = this.props.children
|
||||
}
|
||||
if("onClick" in this.props){
|
||||
props.onClick = this.props.onClick
|
||||
}
|
||||
if("wrapper" in this.props){
|
||||
props.wrapper = !!this.props.wrapper
|
||||
}
|
||||
if("look" in this.props){
|
||||
props.look = this.props.look
|
||||
}
|
||||
if("size" in this.props){
|
||||
props.size = this.props.size
|
||||
}
|
||||
if("hoverColor" in this.props){
|
||||
props.hoverColor = this.props.hoverColor
|
||||
}
|
||||
}
|
||||
|
||||
if(props.color){
|
||||
props.color = props.color.toLowerCase() as ButtonColor
|
||||
if(!Button.Colors.includes(props.color)){
|
||||
props.color = Button.Colors[0]
|
||||
}
|
||||
}else{
|
||||
props.color = Button.Colors[0]
|
||||
}
|
||||
|
||||
if(props.look){
|
||||
props.look = props.look.toLowerCase() as ButtonLook
|
||||
if(!Button.Looks.includes(props.look)){
|
||||
props.look = Button.Looks[0]
|
||||
}
|
||||
}else{
|
||||
props.look = Button.Looks[0]
|
||||
}
|
||||
|
||||
if(props.size){
|
||||
props.size = props.size.toLowerCase() as ButtonSize
|
||||
if(!Button.Sizes.includes(props.size)){
|
||||
props.size = Button.Sizes[0]
|
||||
}
|
||||
}else{
|
||||
props.size = Button.Sizes[0]
|
||||
}
|
||||
|
||||
if(props.hoverColor){
|
||||
props.hoverColor = props.hoverColor.toLowerCase() as ButtonHovers
|
||||
if(!Button.HoverColors.includes(props.hoverColor)){
|
||||
props.hoverColor = Button.HoverColors[0]
|
||||
}
|
||||
}else{
|
||||
props.hoverColor = Button.HoverColors[0]
|
||||
}
|
||||
|
||||
let buttonSize = props.size ? colorsModule.ButtonSizes[props.size.toUpperCase()] || "" : ""
|
||||
if(buttonSize)buttonSize = " " + buttonSize
|
||||
|
||||
let hoverColor = props.hoverColor ? colorsModule.ButtonHovers[props.hoverColor.toUpperCase()] || "" : ""
|
||||
if(hoverColor)hoverColor = " " + hoverColor
|
||||
|
||||
props.onClick = typeof props.onClick === "function" ? props.onClick : () => {}
|
||||
if(typeof props.wrapper !== "boolean")props.wrapper = true
|
||||
|
||||
let hover = this.state.hover ? euhModule1.hasHover : ""
|
||||
if(hover)hover = " " + hover
|
||||
|
||||
let button = <button type="button"
|
||||
className={`${flexModule.flexChild} ${euhModule1.button} ${colorsModule.ButtonLooks[props.look.toUpperCase()]} ${colorsModule.ButtonColors[props.color.toUpperCase()]}${buttonSize}${hoverColor}${hover} ${euhModule1.grow}`}
|
||||
style={{flex: "0 1 auto"}} onClick={this.props.onClick} onMouseEnter={(ev) => {
|
||||
if(!hoverColor)return
|
||||
this.setState({hover: true})
|
||||
}} onMouseLeave={(ev) => {
|
||||
if(!hoverColor)return
|
||||
this.setState({hover: false})
|
||||
}}>
|
||||
<div className={euhModule1.contents}>{props.children}</div>
|
||||
</button>
|
||||
if(props.wrapper){
|
||||
return <div className={buttonModule.buttonWrapper}>
|
||||
{button}
|
||||
</div>
|
||||
}
|
||||
return button
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (AllPreviews = [
|
||||
|
||||
])
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
let colors = []
|
||||
for(let color of Button.Colors){
|
||||
colors.push({
|
||||
color: color
|
||||
})
|
||||
}
|
||||
AllPreviews.push(colors)
|
||||
let looks = []
|
||||
for(let look of Button.Looks){
|
||||
looks.push({
|
||||
look: look
|
||||
})
|
||||
}
|
||||
AllPreviews.push(looks)
|
||||
let sizes = []
|
||||
for(let size of Button.Sizes){
|
||||
sizes.push({
|
||||
size: size
|
||||
})
|
||||
}
|
||||
AllPreviews.push(sizes)
|
||||
let hovers = []
|
||||
for(let hover of Button.HoverColors){
|
||||
hovers.push({
|
||||
hoverColor: hover
|
||||
})
|
||||
}
|
||||
AllPreviews.push(hovers)
|
||||
AllPreviews.push([{children: "Test Button"}])
|
||||
AllPreviews.push([{onClick: () => {}}])
|
||||
AllPreviews.push([{wrapper: false}])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
|
||||
let AllPreviews
|
||||
|
||||
|
||||
export type ButtonColor = "brand" | "grey" | "red" | "green" | "yellow" | "primary" | "link" | "white" | "black" | "transparent"
|
||||
export type ButtonLook = "filled" | "inverted" | "outlined" | "ghost" | "link" | "blank"
|
||||
export type ButtonSize = "none" | "small" | "medium" | "large" | "xlarge" | "min" | "max" | "icon"
|
||||
export type ButtonHovers = "default" | ButtonColor
|
|
@ -2,6 +2,7 @@ import NOOP from "../../modules/noop"
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
import { ReactNode, CSSProperties } from "react"
|
||||
import Utils from "../../modules/Utils"
|
||||
import unfreeze from "../../modules/Unfreeze"
|
||||
|
||||
type DropdownProps = {
|
||||
className?: string,
|
||||
|
@ -42,47 +43,38 @@ type themeOverride = {
|
|||
}
|
||||
|
||||
let DropdownModules
|
||||
export default class Dropdown extends React.Component<DropdownProps, DropdownProps> {
|
||||
export default class Dropdown extends React.Component<DropdownProps, {value: string|null}> {
|
||||
constructor(props:DropdownProps){
|
||||
super(props)
|
||||
props = Dropdown.normalizeProps(props)
|
||||
this.state = props
|
||||
this.onChange = this.onChange.bind(this)
|
||||
this.state = {
|
||||
value: props.value || null
|
||||
}
|
||||
}
|
||||
|
||||
static normalizeProps(props:DropdownProps):DropdownProps{
|
||||
props = Object.create(props)
|
||||
if(!props || typeof props !== "object")props = {}
|
||||
if(typeof props.className !== "string")delete props.className
|
||||
if(typeof props.darkThemeColorOverrides !== "object" || !props.darkThemeColorOverrides)delete props.darkThemeColorOverrides
|
||||
if(typeof props.disabled !== "boolean")props.disabled = false
|
||||
if(typeof props.error !== "string")delete props.error
|
||||
if(typeof props.isMulti !== "boolean")props.isMulti = false
|
||||
if(typeof props.lightThemeColorOverrides !== "object" || !props.lightThemeColorOverrides)delete props.lightThemeColorOverrides
|
||||
if(typeof props.multiValueRenderer !== "function")delete props.multiValueRenderer
|
||||
if(typeof props.valueRenderer !== "function")delete props.valueRenderer
|
||||
if(typeof props.optionRenderer !== "function")delete props.optionRenderer
|
||||
if(typeof props.onChange !== "function")props.onChange = NOOP
|
||||
if(!Array.isArray(props.options))props.options = [{
|
||||
static defaultProps:DropdownProps = {
|
||||
className: null,
|
||||
error: null,
|
||||
options: [{
|
||||
value: "none",
|
||||
"label": "No options - No options was passed to Dropdown. If you meant to put an empty dropdown, input an empty array."
|
||||
}]
|
||||
if(typeof props.searchable !== "boolean")props.searchable = false
|
||||
if(typeof props.styleOverrides !== "object")delete props.styleOverrides
|
||||
if(typeof props.value !== "string")props.value = null
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
}],
|
||||
valueRenderer: null,
|
||||
multiValueRenderer: null,
|
||||
optionRenderer: null,
|
||||
onChange: NOOP,
|
||||
value: null,
|
||||
disabled: false,
|
||||
searchable: false,
|
||||
clearable: false,
|
||||
styleOverrides: null,
|
||||
lightThemeColorOverrides: null,
|
||||
darkThemeColorOverrides: null,
|
||||
isMulti: false
|
||||
}
|
||||
|
||||
onChange(value){
|
||||
console.log(value)
|
||||
this.state.onChange(value)
|
||||
this.props.onChange(value)
|
||||
this.setState({
|
||||
value: value
|
||||
})
|
||||
|
@ -99,14 +91,58 @@ export default class Dropdown extends React.Component<DropdownProps, DropdownPro
|
|||
DropdownComponent
|
||||
] = this.modules
|
||||
|
||||
let props = Dropdown.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
return <DropdownComponent {...this.props} onChange={this.onChange}/>
|
||||
let props = this.props
|
||||
let returnValue = <DropdownComponent {...props} onChange={this.onChange} value={this.state.value}/>
|
||||
return returnValue
|
||||
}
|
||||
|
||||
get value(){
|
||||
return this.state.value
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([{
|
||||
error: null
|
||||
}, {
|
||||
error: "An error occured"
|
||||
}], [{
|
||||
options: [
|
||||
{
|
||||
value: "option1",
|
||||
label: "Option 1"
|
||||
},
|
||||
{
|
||||
value: "option2",
|
||||
label: "Option 2"
|
||||
},
|
||||
{
|
||||
value: "option3",
|
||||
label: "Option 3"
|
||||
}
|
||||
]
|
||||
}], [{
|
||||
value: "option1"
|
||||
}], [{
|
||||
disabled: false
|
||||
}, {
|
||||
disabled: true
|
||||
}], [{
|
||||
searchable: true
|
||||
}, {
|
||||
searchable: false
|
||||
}], [{
|
||||
clearable: true
|
||||
}, {
|
||||
clearable: false
|
||||
}], [{
|
||||
isMulti: false
|
||||
}, {
|
||||
isMulti: true
|
||||
}])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -19,51 +19,31 @@ type RadioGroupProps = {
|
|||
}
|
||||
|
||||
let RadioGroupModule
|
||||
export default class RadioGroup extends React.Component<RadioGroupProps, RadioGroupProps> {
|
||||
export default class RadioGroup extends React.Component<RadioGroupProps, {value?: string}> {
|
||||
static defaultProps:RadioGroupProps = {
|
||||
options: [{
|
||||
value: "none",
|
||||
name: "No options",
|
||||
desc: "No options was passed to Choices. If you meant to display no options at all, please pass an empty array.",
|
||||
color: "#f04747"
|
||||
}],
|
||||
value: null,
|
||||
disabled: false,
|
||||
size: "medium",
|
||||
itemType: "bar",
|
||||
infoClassName: null,
|
||||
onChange: NOOP
|
||||
}
|
||||
constructor(props:RadioGroupProps){
|
||||
super(props)
|
||||
props = RadioGroup.normalizeProps(props)
|
||||
this.state = props
|
||||
this.onChange = this.onChange.bind(this)
|
||||
}
|
||||
|
||||
static normalizeProps(props:RadioGroupProps):RadioGroupProps{
|
||||
props = Object.create(props)
|
||||
if(!props || typeof props !== "object")props = {}
|
||||
let defaultOptions = false
|
||||
if(!props.options || !Array.isArray(props.options)){
|
||||
props.options = [{
|
||||
value: "none",
|
||||
name: "No options",
|
||||
desc: "No options was passed to Choices. If you meant to display no options at all, please pass an empty array.",
|
||||
color: "#f04747"
|
||||
}]
|
||||
defaultOptions = true
|
||||
this.state = {
|
||||
value: props.value
|
||||
}
|
||||
if(!props.value || typeof props.value !== "string"){
|
||||
if(defaultOptions){
|
||||
props.value = "none"
|
||||
}else{
|
||||
props.value = null
|
||||
}
|
||||
}
|
||||
if(typeof props.disabled !== "boolean")props.disabled = false
|
||||
if(typeof props.size !== "string" || !["small", "medium"].includes(props.size.toLowerCase()))props.size = "medium"
|
||||
if(typeof props.itemType !== "string" || !["bar", "panel"].includes(props.itemType))props.itemType = "bar"
|
||||
if(typeof props.infoClassName !== "string")props.infoClassName = ""
|
||||
if(!props.onChange || typeof props.onChange !== "function")props.onChange = NOOP
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
}
|
||||
|
||||
onChange(ev){
|
||||
this.state.onChange(ev.value)
|
||||
this.props.onChange(ev.value)
|
||||
this.setState({
|
||||
value: ev.value
|
||||
})
|
||||
|
@ -80,16 +60,54 @@ export default class RadioGroup extends React.Component<RadioGroupProps, RadioGr
|
|||
RadioGroupComponent
|
||||
] = this.modules
|
||||
|
||||
let props = RadioGroup.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
return <RadioGroupComponent options={props.options} onChange={this.onChange} value={props.value} disabled={props.disabled}
|
||||
let props = this.props
|
||||
return <RadioGroupComponent options={props.options} onChange={this.onChange} value={this.state.value} disabled={props.disabled}
|
||||
size={RadioGroupComponent.Sizes[props.size.toUpperCase()]} itemType={RadioGroupComponent.ItemTypes[props.itemType.toUpperCase()]}
|
||||
infoClassName={props.infoClassName}/>
|
||||
}
|
||||
|
||||
get value(){
|
||||
get value():string|null{
|
||||
return this.state.value
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([{
|
||||
options: [
|
||||
{
|
||||
value: "option1",
|
||||
name: "Option 1",
|
||||
desc: "description 1"
|
||||
},
|
||||
{
|
||||
value: "option2",
|
||||
name: "Option 2",
|
||||
desc: "description 2"
|
||||
},
|
||||
{
|
||||
value: "option3",
|
||||
name: "Option 3",
|
||||
desc: "description 3"
|
||||
}
|
||||
]
|
||||
}], [{
|
||||
value: "option1"
|
||||
}], [{
|
||||
disabled: false
|
||||
}, {
|
||||
disabled: true
|
||||
}], [{
|
||||
size: "medium"
|
||||
}, {
|
||||
size: "small"
|
||||
}], [{
|
||||
itemType: "bar"
|
||||
}, {
|
||||
itemType: "panel"
|
||||
}])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -19,36 +19,13 @@ let SwitchModules
|
|||
export default class Switch extends React.Component<SwitchProps, {value: boolean}> {
|
||||
constructor(props:SwitchProps){
|
||||
super(props)
|
||||
props = Switch.normalizeProps(props)
|
||||
|
||||
this.state = Object.create(props)
|
||||
this.state = {
|
||||
value: props.value || false
|
||||
}
|
||||
this.onChange = this.onChange.bind(this)
|
||||
}
|
||||
|
||||
static normalizeProps(props:SwitchProps){
|
||||
props = Object.create(props)
|
||||
if(!props)props = {}
|
||||
if(!props.id || typeof props.id !== "string")props.id = null
|
||||
if(!props.onChange || typeof props.onChange !== "function")props.onChange = NOOP
|
||||
if(!props.value || typeof props.value !== "boolean")props.value = false
|
||||
if(!props.fill || typeof props.fill !== "string")props.fill = null
|
||||
if(!props.theme || !["default", "clear"].includes(props.theme.toLowerCase()))props.theme = "default"
|
||||
if(!("disabled" in props) || typeof props.disabled !== "boolean")props.disabled = false
|
||||
if(!props.className || typeof props.className !== "string")props.className = ""
|
||||
if(!props.size || !["default", "mini"].includes(props.size.toLowerCase()))props.size = "default"
|
||||
if(!props.style || typeof props.style !== "object")props.style = {}
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
}
|
||||
|
||||
|
||||
|
||||
get modules(){
|
||||
return SwitchModules || (SwitchModules = [
|
||||
WebpackLoader.find(e => e.default && e.default.displayName === "Switch").default
|
||||
|
@ -60,10 +37,7 @@ export default class Switch extends React.Component<SwitchProps, {value: boolean
|
|||
SwitchComponent
|
||||
] = this.modules
|
||||
|
||||
let props = Switch.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
let props = this.props
|
||||
return (<SwitchComponent id={props.id} onChange={this.onChange} value={this.state.value || false} fill={props.fill}
|
||||
theme={SwitchComponent.Themes[props.theme.toUpperCase()]} disabled={props.disabled} className={props.className}
|
||||
size={SwitchComponent.Sizes[props.size.toUpperCase()]} style={props.style}/>)
|
||||
|
@ -79,4 +53,46 @@ export default class Switch extends React.Component<SwitchProps, {value: boolean
|
|||
get value(){
|
||||
return this.state.value
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
id: null,
|
||||
onChange: NOOP,
|
||||
value: false,
|
||||
fill: null,
|
||||
theme: "default",
|
||||
disabled: false,
|
||||
className: null,
|
||||
size: "default",
|
||||
style: {}
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([{onChange: (value) => {}}])
|
||||
AllPreviews.push([{
|
||||
value: false
|
||||
}], [{
|
||||
theme: "default"
|
||||
}, {
|
||||
theme: "clear"
|
||||
}], [{
|
||||
disabled: false
|
||||
}, {
|
||||
disabled: true
|
||||
}], [{
|
||||
id: "api-preview-switch"
|
||||
}], [{
|
||||
fill: null
|
||||
}], [{
|
||||
size: "default"
|
||||
}, {
|
||||
size: "mini"
|
||||
}], [{
|
||||
style: {}
|
||||
}])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -23,46 +23,18 @@ type TextAreaProps = {
|
|||
}
|
||||
|
||||
let TextAreaModules
|
||||
export default class TextArea extends React.Component<TextAreaProps, TextAreaProps> {
|
||||
constructor(props){
|
||||
export default class TextArea extends React.Component<TextAreaProps, {value: string}> {
|
||||
constructor(props:TextAreaProps){
|
||||
super(props)
|
||||
props = TextArea.normalizeProps(props)
|
||||
this.state = Object.create(props)
|
||||
|
||||
this.onChange = this.onChange.bind(this)
|
||||
this.onFocus = this.onFocus.bind(this)
|
||||
this.onBlur = this.onBlur.bind(this)
|
||||
this.onKeyDown = this.onKeyDown.bind(this)
|
||||
}
|
||||
|
||||
static normalizeProps(props:TextAreaProps):TextAreaProps {
|
||||
props = Object.create(props)
|
||||
if(!props)props = {}
|
||||
if(!props.name || typeof props.name !== "string")props.name = ""
|
||||
if(!props.disabled || typeof props.disabled !== "boolean")props.disabled = false
|
||||
if(typeof props.placeholder !== "string")props.placeholder = ""
|
||||
if(typeof props.autoFocus !== "boolean")props.autoFocus = false
|
||||
if(typeof props.resizeable !== "boolean")props.resizeable = false
|
||||
if(typeof props.flex !== "boolean")props.flex = false
|
||||
if(typeof props.autosize !== "boolean")props.autosize = false
|
||||
if(typeof props.rows !== "number")props.rows = 3
|
||||
if(typeof props.value !== "string")props.value = ""
|
||||
if(typeof props.error !== "string")props.error = null
|
||||
if(props.maxLength && typeof props.maxLength !== "number")props.maxLength = 999
|
||||
if(typeof props.className !== "string")props.className = ""
|
||||
if(typeof props.id !== "string")props.id = null
|
||||
if(typeof props.onChange !== "function")props.onChange = NOOP
|
||||
if(typeof props.onFocus !== "function")props.onFocus = NOOP
|
||||
if(typeof props.onBlur !== "function")props.onBlur = NOOP
|
||||
if(typeof props.onKeyDown !== "function")props.onKeyDown = NOOP
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
this.state = {
|
||||
value: props.value || ""
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
}
|
||||
|
||||
get modules(){
|
||||
|
@ -72,22 +44,22 @@ export default class TextArea extends React.Component<TextAreaProps, TextAreaPro
|
|||
}
|
||||
|
||||
onChange(value, name){
|
||||
this.state.onChange(value, name)
|
||||
this.props.onChange(value, name)
|
||||
this.setState({
|
||||
value
|
||||
})
|
||||
}
|
||||
|
||||
onFocus(ev, name){
|
||||
this.state.onFocus(ev, name)
|
||||
this.props.onFocus(ev, name)
|
||||
}
|
||||
|
||||
onBlur(ev, name){
|
||||
this.state.onBlur(ev, name)
|
||||
this.props.onBlur(ev, name)
|
||||
}
|
||||
|
||||
onKeyDown(ev){
|
||||
this.state.onKeyDown(ev)
|
||||
this.props.onKeyDown(ev)
|
||||
}
|
||||
|
||||
render(){
|
||||
|
@ -95,15 +67,97 @@ export default class TextArea extends React.Component<TextAreaProps, TextAreaPro
|
|||
TextAreaComponent
|
||||
] = this.modules
|
||||
|
||||
let props = TextArea.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = Object.create(props)
|
||||
}
|
||||
let props = this.props
|
||||
|
||||
return <TextAreaComponent {...props} onChange={this.onChange} onFocus={this.onFocus} onBlur={this.onBlur} onKeyDown={this.onKeyDown}/>
|
||||
return <TextAreaComponent {...props} onChange={this.onChange} onFocus={this.onFocus} onBlur={this.onBlur} onKeyDown={this.onKeyDown} value={this.state.value}/>
|
||||
}
|
||||
|
||||
get value(){
|
||||
return this.state.value
|
||||
return this.state.value || ""
|
||||
}
|
||||
|
||||
static defaultProps:TextAreaProps = {
|
||||
name: null,
|
||||
disabled: false,
|
||||
placeholder: null,
|
||||
autoFocus: false,
|
||||
resizeable: false,
|
||||
flex: false,
|
||||
autosize: false,
|
||||
rows: 3,
|
||||
value: "",
|
||||
error: null,
|
||||
maxLength: null,
|
||||
className: null,
|
||||
id: null,
|
||||
onChange: NOOP,
|
||||
onFocus: NOOP,
|
||||
onBlur: NOOP,
|
||||
onKeyDown: NOOP
|
||||
}
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([{
|
||||
name: "api-preview-textarea"
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
disabled: false
|
||||
}, {
|
||||
disabled: true
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
placeholder: null
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
autoFocus: false
|
||||
}, {
|
||||
autoFocus: true
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
resizeable: false
|
||||
}, {
|
||||
resizeable: true
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
flex: false
|
||||
}, {
|
||||
flex: true
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
autosize: false
|
||||
}, {
|
||||
autosize: true
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
rows: 3
|
||||
}, {
|
||||
rows: 2
|
||||
}, {
|
||||
rows: 1
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
value: ""
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
error: null
|
||||
}, {
|
||||
error: "Example error"
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
maxLength: 100
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
className: ""
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
inputClassName: ""
|
||||
}])
|
||||
AllPreviews.push([{
|
||||
id: "api-preview-textarea"
|
||||
}])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -19,44 +19,34 @@ type TextInputProps = {
|
|||
}
|
||||
|
||||
let TextInputModules
|
||||
export default class TextInput extends React.PureComponent<TextInputProps, TextInputProps> {
|
||||
export default class TextInput extends React.PureComponent<TextInputProps, {value: string}> {
|
||||
hasSet: boolean
|
||||
constructor(props: TextInputProps){
|
||||
super(props)
|
||||
props = TextInput.normalizeProps(props)
|
||||
this.state = props
|
||||
|
||||
console.log(this.state)
|
||||
|
||||
this.onChange = this.onChange.bind(this)
|
||||
this.onFocus = this.onFocus.bind(this)
|
||||
this.onBlur = this.onBlur.bind(this)
|
||||
|
||||
this.state = {
|
||||
value: props.value || ""
|
||||
}
|
||||
}
|
||||
|
||||
static normalizeProps(props:TextInputProps):TextInputProps {
|
||||
props = Object.create(props)
|
||||
if(!props)props = {}
|
||||
if(!props.name || typeof props.name !== "string")props.name = ""
|
||||
if(!props.size || !["default", "mini"].includes(props.size))props.size = "default"
|
||||
if(!props.disabled || typeof props.disabled !== "boolean")props.disabled = false
|
||||
if(typeof props.placeholder !== "string")props.placeholder = ""
|
||||
if(typeof props.value !== "string")props.value = ""
|
||||
if(typeof props.error !== "string")props.error = null
|
||||
if(props.maxLength && typeof props.maxLength !== "number")props.maxLength = 999
|
||||
if(typeof props.className !== "string")props.className = ""
|
||||
if(typeof props.inputClassName !== "string")props.inputClassName = ""
|
||||
if(typeof props.id !== "string")props.id = null
|
||||
if(typeof props.onChange !== "function")props.onChange = NOOP
|
||||
if(typeof props.onFocus !== "function")props.onFocus = NOOP
|
||||
if(typeof props.onBlur !== "function")props.onBlur = NOOP
|
||||
|
||||
let levels = [props]
|
||||
while(Utils.getNestedProps(props, levels.map(e => "__proto__").join("."))){
|
||||
levels.push(Utils.getNestedProps(props, levels.map(e => "__proto__").join(".")))
|
||||
}
|
||||
let finals = Object.assign({}, ...levels)
|
||||
|
||||
return finals
|
||||
static defaultProps:TextInputProps = {
|
||||
name: "",
|
||||
size: "default",
|
||||
disabled: false,
|
||||
placeholder: "",
|
||||
value: "",
|
||||
error: null,
|
||||
maxLength: 999,
|
||||
className: "",
|
||||
inputClassName: "",
|
||||
id: null,
|
||||
onChange: NOOP,
|
||||
onFocus: NOOP,
|
||||
onBlur: NOOP
|
||||
}
|
||||
|
||||
get modules(){
|
||||
|
@ -67,7 +57,7 @@ export default class TextInput extends React.PureComponent<TextInputProps, TextI
|
|||
|
||||
onChange(value, name){
|
||||
this.hasSet = false
|
||||
this.state.onChange(value, name, this)
|
||||
this.props.onChange(value, name, this)
|
||||
if(this.hasSet)return // prevent event if the onChange has changed the value.
|
||||
this.setState({
|
||||
value
|
||||
|
@ -76,11 +66,11 @@ export default class TextInput extends React.PureComponent<TextInputProps, TextI
|
|||
}
|
||||
|
||||
onFocus(ev, name){
|
||||
this.state.onFocus(ev, name, this)
|
||||
this.props.onFocus(ev, name, this)
|
||||
}
|
||||
|
||||
onBlur(ev, name){
|
||||
this.state.onBlur(ev, name, this)
|
||||
this.props.onBlur(ev, name, this)
|
||||
}
|
||||
|
||||
render(){
|
||||
|
@ -88,16 +78,12 @@ export default class TextInput extends React.PureComponent<TextInputProps, TextI
|
|||
TextAreaComponent
|
||||
] = this.modules
|
||||
|
||||
let props = TextInput.normalizeProps(this.state || this.props)
|
||||
if(!this.state){
|
||||
this.state = props
|
||||
}
|
||||
console.log(props)
|
||||
return <TextAreaComponent {...props} onChange={this.onChange} onFocus={this.onFocus} onBlur={this.onBlur}/>
|
||||
let props = this.props
|
||||
return <TextAreaComponent {...props} onChange={this.onChange} onFocus={this.onFocus} onBlur={this.onBlur} value={this.state.value} />
|
||||
}
|
||||
|
||||
get value(){
|
||||
return this.state.value
|
||||
return this.state.value || ""
|
||||
}
|
||||
|
||||
setValue(value:string){
|
||||
|
@ -107,4 +93,41 @@ export default class TextInput extends React.PureComponent<TextInputProps, TextI
|
|||
this.forceUpdate()
|
||||
this.hasSet = true
|
||||
}
|
||||
|
||||
static get AllPreviews(){
|
||||
return AllPreviews || (() => {
|
||||
AllPreviews = []
|
||||
AllPreviews.push([{
|
||||
name: "api-preview-textinput"
|
||||
}], [{
|
||||
size: "default"
|
||||
}, {
|
||||
size: "mini"
|
||||
}], [{
|
||||
disabled: false
|
||||
}, {
|
||||
disabled: true
|
||||
}], [{
|
||||
placeholder: ""
|
||||
}], [{
|
||||
value: ""
|
||||
}], [{
|
||||
error: null
|
||||
}, {
|
||||
error: "Example error"
|
||||
}], [{
|
||||
maxLength: 999
|
||||
}], [{
|
||||
className: ""
|
||||
}], [{
|
||||
inputClassName: ""
|
||||
}], [{
|
||||
id: "api-preview-textinput"
|
||||
}], [{
|
||||
onChange: (value: string, name: string) => {}
|
||||
}])
|
||||
return AllPreviews
|
||||
})()
|
||||
}
|
||||
}
|
||||
let AllPreviews
|
|
@ -16,7 +16,7 @@ export default new class PluginUtilities {
|
|||
renderSettingsToReact(settings:SettingItem[]){
|
||||
let items = []
|
||||
settings.forEach(item => {
|
||||
console.log(item)
|
||||
|
||||
if(typeof item !== "object")return items.push(item)
|
||||
if(item.props && "children" in item.props){
|
||||
if(!Array.isArray(item.props.children))item.props.children = [item.props.children]
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
export default function unfreeze(o) {
|
||||
var oo = undefined;
|
||||
if (o instanceof Array) {
|
||||
oo = [];
|
||||
var clone = function(v) {
|
||||
oo.push(v)
|
||||
};
|
||||
o.forEach(clone);
|
||||
} else if (o instanceof String) {
|
||||
oo = new String(o).toString();
|
||||
} else if (typeof o == 'object') {
|
||||
oo = {};
|
||||
for (var property in o) {
|
||||
oo[property] = o[property];
|
||||
}
|
||||
}
|
||||
return oo;
|
||||
}
|
||||
declare global {
|
||||
interface ObjectConstructor {
|
||||
unfreeze: <T extends any>(obj: Readonly<T>) => T
|
||||
}
|
||||
}
|
||||
Object.unfreeze = unfreeze
|
|
@ -33,7 +33,7 @@ async function main(){
|
|||
for(let file of fs.readdirSync(folder, {withFileTypes: true})){
|
||||
if(file.isFile()){
|
||||
let filepath = path.join(folder, file.name)
|
||||
if(predicate(filepath)){
|
||||
if(predicate(filepath), false){
|
||||
await compile(filepath, path.join(filepath.replace(folders.startDir, folders.newDir)), "..")
|
||||
}else{
|
||||
await fs.promises.copyFile(filepath, filepath.replace(folders.startDir, folders.newDir))
|
||||
|
|
|
@ -54,6 +54,8 @@ async function privateInit(){
|
|||
window.React = React
|
||||
require.cache["react"] = React
|
||||
}
|
||||
|
||||
|
||||
try{
|
||||
window.ReactDOM = require("react-dom")
|
||||
}catch(e){
|
||||
|
@ -62,6 +64,105 @@ async function privateInit(){
|
|||
require.cache["react-dom"] = ReactDOM
|
||||
}
|
||||
|
||||
//stop here if betterdiscord is disabled.
|
||||
if(electron.remote.process.argv.includes("--disable-betterdiscord")){
|
||||
let formComponents
|
||||
let margins
|
||||
let ButtonModules
|
||||
class LightcordSettings extends React.Component {
|
||||
render(){
|
||||
if(!formComponents)formComponents = ModuleLoader.get(e => e.FormSection)[0]
|
||||
if(!margins)margins = ModuleLoader.get(e => e.marginTop60)[0]
|
||||
|
||||
let [
|
||||
flexModule,
|
||||
euhModule1,
|
||||
buttonModule,
|
||||
colorsModule,
|
||||
] = this.ButtonModules
|
||||
return React.createElement("div", {}, [
|
||||
React.createElement(formComponents.FormSection, {
|
||||
className: "",
|
||||
tag: "h2",
|
||||
title: "Lightcord's Settings"
|
||||
}, [
|
||||
React.createElement("div", { className: buttonModule.buttonWrapper }, [
|
||||
React.createElement("button", {
|
||||
type: "button",
|
||||
className: `${flexModule.flexChild} ${euhModule1.button} ${euhModule1.lookFilled} ${colorsModule.ButtonColors.YELLOW} ${euhModule1.sizeSmall} ${euhModule1.grow}`,
|
||||
style: { flex: "0 1 auto" },
|
||||
onClick: () => {
|
||||
console.log("Should relaunch")
|
||||
electron.remote.app.relaunch({
|
||||
args: electron.remote.process.argv.slice(1).filter(e => e !== "--disable-betterdiscord")
|
||||
})
|
||||
electron.remote.app.quit()
|
||||
}
|
||||
},
|
||||
React.createElement("div", { className: euhModule1.contents }, "Relaunch with BetterDiscord"))
|
||||
])
|
||||
])
|
||||
])
|
||||
}
|
||||
|
||||
get ButtonModules(){ // caching modules
|
||||
return ButtonModules || (ButtonModules = [
|
||||
ModuleLoader.get(e => e["_horizontal"])[0],
|
||||
ModuleLoader.get(e => e["colorTransparent"])[0],
|
||||
ModuleLoader.get(e => e["buttonWrapper"])[0],
|
||||
ModuleLoader.get(e => e["ButtonColors"])[0]
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
// fix notifications here
|
||||
let dispatcher = ModuleLoader.get(m=>m.Dispatcher&&m.default&&m.default.dispatch)[0].default
|
||||
dispatcher.subscribe("USER_SETTINGS_UPDATE", (data) => {
|
||||
DiscordNative.ipc.send("UPDATE_THEME", data.settings.theme)
|
||||
})
|
||||
|
||||
let constants = ModuleLoader.get(m=>m.API_HOST)[0]
|
||||
|
||||
// add menu to re enable BetterDiscord
|
||||
constants.UserSettingsSections = Object.freeze(Object.assign({}, constants.UserSettingsSections, {LIGHTCORD: "Lightcord"}))
|
||||
|
||||
ensureExported(e => e.default && e.default.prototype && e.default.prototype.getPredicateSections)
|
||||
.then(settingModule => {
|
||||
|
||||
let getPredicateSections = settingModule.default.prototype.getPredicateSections
|
||||
settingModule.default.prototype.getPredicateSections = function(){
|
||||
let result = getPredicateSections.call(this, ...arguments)
|
||||
console.log(result)
|
||||
if(result[1].section === "My Account"){ // user settings, not guild settings
|
||||
let poped = []
|
||||
|
||||
poped.push(result.pop())
|
||||
poped.push(result.pop())
|
||||
poped.push(result.pop())
|
||||
poped.push(result.pop())
|
||||
|
||||
result.push({
|
||||
section: "HEADER",
|
||||
label: "Lightcord"
|
||||
}, {
|
||||
section: constants.UserSettingsSections.LIGHTCORD,
|
||||
label: "Lightcord",
|
||||
element: LightcordSettings
|
||||
}, {
|
||||
section: "DIVIDER"
|
||||
})
|
||||
|
||||
while(poped[0]){
|
||||
result.push(poped.pop())
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let createSoundOriginal = ModuleLoader.get((e) => e.createSound)[0].createSound
|
||||
ModuleLoader.get((e) => e.createSound)[0].createSound = function(sound){
|
||||
let isCalling = sound === "call_ringing_beat" || sound === "call_ringing"
|
||||
|
@ -153,7 +254,7 @@ async function privateInit(){
|
|||
*/
|
||||
let DiscordJS
|
||||
try{
|
||||
//DiscordJS = require("../../../../../DiscordJS").default
|
||||
DiscordJS = require("../../../../../DiscordJS").default
|
||||
}catch(err){
|
||||
console.error(err)
|
||||
DiscordJS = null
|
||||
|
@ -368,7 +469,13 @@ async function privateInit(){
|
|||
}
|
||||
}
|
||||
let returnValue = _handleDispatch.call(this, ...arguments)
|
||||
if(event === "READY" && DiscordJS)DiscordJS.client.emit("ready")
|
||||
if(event === "READY" && DiscordJS){
|
||||
try{
|
||||
DiscordJS.client.emit("self.ready", data)
|
||||
}catch(e){
|
||||
console.error("[DiscordJS Error]", e)
|
||||
}
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
function cancelGatewayPrototype(methodName){
|
||||
|
@ -963,6 +1070,96 @@ async function privateInit(){
|
|||
}
|
||||
})().catch(() => {})
|
||||
|
||||
|
||||
let usedWebhooks = {}
|
||||
|
||||
ensureExported(e => e && e.Request && e.Request.prototype && e.Request.prototype.end)
|
||||
.then(RequestModule => {
|
||||
console.log("RequestModule", RequestModule)
|
||||
|
||||
const end = RequestModule.Request.prototype.end
|
||||
RequestModule.Request.prototype.end = function(){
|
||||
if(this.url.endsWith("/messages") && /\/channels\/\d+\/messages/g.test(this.url) && this.method === "POST"){ // sending message
|
||||
let channelId = this.url.split("/channels/")[1].split("/messages")[0]
|
||||
|
||||
if(usedWebhooks[channelId]){ // webhook is availlable
|
||||
let webhook = usedWebhooks[channelId]
|
||||
let url = `/webhooks/${webhook.id}/${webhook.token}?wait=true`
|
||||
this.url = url
|
||||
}
|
||||
}
|
||||
|
||||
return end.call(this, ...arguments)
|
||||
}
|
||||
})
|
||||
ensureExported(e => e.default && e.default.displayName === "Webhook")
|
||||
.then(webhookComponent => {
|
||||
const renderEdit = webhookComponent.default.prototype.renderEdit
|
||||
webhookComponent.default.prototype.renderEdit = function(){
|
||||
const webhook = this.props.webhook
|
||||
let returnValue = renderEdit.call(this, ...arguments)
|
||||
returnValue.props.children = [returnValue.props.children]
|
||||
let message = usedWebhooks[webhook.channel_id] && usedWebhooks[webhook.channel_id].id === webhook.id ? "Stop talking with this webhook" : "Talk with this webhook"
|
||||
|
||||
returnValue.props.children.push(React.createElement(window.Lightcord.Api.Components.inputs.Button, {color: "green", wrapper: false, onClick(){
|
||||
if(usedWebhooks[webhook.channel_id] && usedWebhooks[webhook.channel_id].id === webhook.id){
|
||||
delete usedWebhooks[webhook.channel_id]
|
||||
}else{
|
||||
usedWebhooks[webhook.channel_id] = {
|
||||
id: webhook.id,
|
||||
token: webhook.token
|
||||
}
|
||||
}
|
||||
webhookPanels.forEach(e => e())
|
||||
}}, message))
|
||||
|
||||
return returnValue
|
||||
}
|
||||
})
|
||||
|
||||
let webhookPanels = []
|
||||
let getComp = (comp) => {
|
||||
class SettingsWebhooks extends React.PureComponent {
|
||||
constructor(props){
|
||||
super(props)
|
||||
}
|
||||
|
||||
componentWillMount(){
|
||||
this.id = uuid()
|
||||
this.component = new comp(this.props)
|
||||
let func = () => {
|
||||
this.component.forceUpdate()
|
||||
}
|
||||
func.id = this.id
|
||||
webhookPanels.push(func)
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.component = null
|
||||
webhookPanels = webhookPanels.filter(e => e.id !== this.id)
|
||||
}
|
||||
|
||||
render(){
|
||||
return this.component.render()
|
||||
}
|
||||
|
||||
static displayName = "SettingsWebhooks"
|
||||
}
|
||||
|
||||
return SettingsWebhooks
|
||||
}
|
||||
ensureExported(e => e.default && e.default.displayName === "FluxContainer(SettingsWebhooks)")
|
||||
.then(webhooksComponents => {
|
||||
let comp = webhooksComponents.default
|
||||
|
||||
webhooksComponents.default = getComp(comp)
|
||||
|
||||
ModuleLoader.get(e => e.default && e.default.displayName === "FluxContainer(FluxContainer(SettingsWebhooks))")
|
||||
.forEach(mod => {
|
||||
mod.default = getComp(mod.default)
|
||||
})
|
||||
})
|
||||
|
||||
Utils.monkeyPatch(await ensureExported(e => e.default && e.default.displayName == "AuthBox"), "default", {after: (data) => {
|
||||
const children = Utils.getNestedProp(data.returnValue, "props.children.props.children.props.children")
|
||||
children.push(React.createElement(require("./tokenLogin").default, {}))
|
||||
|
@ -1035,7 +1232,7 @@ function ensureGuildClasses(){
|
|||
})
|
||||
}
|
||||
|
||||
global.ensureExported = function ensureExported(filter, maxTime = 500){
|
||||
var ensureExported = global.ensureExported = function ensureExported(filter, maxTime = 500){
|
||||
let tried = 0
|
||||
return new Promise((resolve, reject) => {
|
||||
let mod = ModuleLoader.get(filter)[0]
|
||||
|
|
|
@ -46,14 +46,12 @@
|
|||
flex-direction: row;
|
||||
}
|
||||
.lc-tab {
|
||||
border-radius: 8px;
|
||||
/*border-radius: 8px;*/
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 600px;
|
||||
max-width: 100%;
|
||||
-webkit-box-shadow: 0 0 20px 2px rgba(4,4,5,.3);
|
||||
box-shadow: 0 0 20px 2px rgba(4,4,5,.3);
|
||||
-webkit-transform: scale(.85);
|
||||
transform: scale(.85);
|
||||
-webkit-box-sizing: border-box;
|
||||
|
@ -74,6 +72,10 @@
|
|||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
.lc-tab-box-shadow {
|
||||
-webkit-box-shadow: 0 0 20px 2px rgba(4,4,5,.3);
|
||||
box-shadow: 0 0 20px 2px rgba(4,4,5,.3);
|
||||
}
|
||||
.lc-navItem {
|
||||
padding: 14px 20px;
|
||||
position: relative;
|
||||
|
|
|
@ -42,10 +42,37 @@ global.BDModules = Modules
|
|||
|
||||
function setReq(){
|
||||
try{
|
||||
req = webpackJsonp.push([[], {__extra_id__: (module, exports, req) => module.exports = req}, [["__extra_id__"]]]);
|
||||
req = webpackJsonp.push([[], {__extra_id__: (mdl, exports, req) => mdl.exports = req}, [["__extra_id__"]]]);
|
||||
if(req){
|
||||
delete req.m.__extra_id__;
|
||||
delete req.c.__extra_id__;
|
||||
delete req.c.__extra_id__;/*
|
||||
Object.defineProperty(req.c, "0", {
|
||||
get: () => ({
|
||||
i: 0,
|
||||
l: true,
|
||||
exports: require("react")
|
||||
}),
|
||||
configurable: false,
|
||||
enumerable: true
|
||||
})
|
||||
Object.defineProperty(req.c, "856", {
|
||||
get: () => ({
|
||||
i: 856,
|
||||
l: true,
|
||||
exports: require("react")
|
||||
}),
|
||||
configurable: false,
|
||||
enumerable: true
|
||||
})
|
||||
Object.defineProperty(req.c, "71", {
|
||||
get: () => ({
|
||||
i: 71,
|
||||
l: true,
|
||||
exports: require("react-dom")
|
||||
}),
|
||||
configurable: false,
|
||||
enumerable: true
|
||||
})*/
|
||||
}
|
||||
}catch(e){
|
||||
req = undefined
|
||||
|
|
|
@ -30,7 +30,8 @@ if(process.platform === "win32"){
|
|||
id: this.id,
|
||||
title: this.title,
|
||||
body: this.body,
|
||||
icon: this.icon
|
||||
icon: this.icon,
|
||||
theme: settingStore ? settingStore.default.theme : "dark"
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,9 @@ if(process.platform === "win32"){
|
|||
}
|
||||
}
|
||||
|
||||
let settingStore
|
||||
ensureExported((e => e.default && e.default.theme))
|
||||
.then(themeStore => {
|
||||
settingStore = themeStore
|
||||
ipcRenderer.send("UPDATE_THEME", themeStore.default.theme)
|
||||
}).catch(console.error)
|
|
@ -43,8 +43,6 @@ const DiscordNative = {
|
|||
|
||||
const BetterDiscord = require("./BetterDiscord")
|
||||
|
||||
const _setImmediate = setImmediate;
|
||||
const _clearImmediate = clearImmediate;
|
||||
process.once('loaded', () => {
|
||||
// Implementing DiscordNative
|
||||
global.DiscordNative = DiscordNative;
|
||||
|
@ -56,13 +54,14 @@ process.once('loaded', () => {
|
|||
global.Buffer = Buffer
|
||||
global.require = require
|
||||
|
||||
// We keep these two functions in global because electron doesn't put these
|
||||
// nodejs APIs in the module scope, and these two functions
|
||||
// aren't harmful at all.
|
||||
global.setImmediate = _setImmediate;
|
||||
global.clearImmediate = _clearImmediate;
|
||||
global.setImmediate = function(callback, ...args){
|
||||
return setTimeout(callback, 0, ...args);
|
||||
};
|
||||
global.clearImmediate = clearTimeout;
|
||||
|
||||
const buildInfo = electron.remote.getGlobal("BuildInfo")
|
||||
console.log("%c%s", "color: #3767ad;font-size:25px", 'Lightcord Client\nhttps://github.com/Lightcord/Lightcord');
|
||||
console.log("%c%s", "font-size:15px", `Version: ${buildInfo.version}\nCommit: ${buildInfo.commit || "Unknown"}`)
|
||||
|
||||
|
||||
let ftime = Date.now()
|
||||
|
|
|
@ -121,6 +121,10 @@ function handleNotificationsClear() {
|
|||
}
|
||||
|
||||
function handleNotificationShow(e, notification) {
|
||||
if(lastUsedTheme !== notification.theme){
|
||||
lastUsedTheme = notification.theme
|
||||
webContentsSend(notificationWindow, "UPDATE_THEME", lastUsedTheme)
|
||||
}
|
||||
notifications.push(notification);
|
||||
updateNotifications();
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
.notification {
|
||||
border-radius: 10px;
|
||||
}
|
||||
.notification-icon {
|
||||
border-radius: 10px
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="notifications-mount"></div>
|
||||
|
|
|
@ -5743,9 +5743,14 @@
|
|||
}
|
||||
}), i.default.createElement("div", {
|
||||
className: "notification-body"
|
||||
}, i.default.createElement("header", null, this.props.title), i.default.createElement("p", {className: "notif-text theme-"+this.props.theme}, this.props.body))), i.default.createElement("div", {
|
||||
className: "notification-logo"
|
||||
}))
|
||||
}, i.default.createElement("header", null, this.props.title),
|
||||
i.default.createElement("p", {
|
||||
className: "notif-text theme-"+this.props.theme
|
||||
}, truncateString(this.props.body, 40)))),
|
||||
i.default.createElement("div", {
|
||||
className: "notification-logo"
|
||||
})
|
||||
)
|
||||
}
|
||||
}),
|
||||
f = (0, o.default)({
|
||||
|
@ -5801,6 +5806,12 @@
|
|||
}
|
||||
});
|
||||
t.Notifications = f
|
||||
function truncateString(str, num) {
|
||||
if (str.length <= num) {
|
||||
return str
|
||||
}
|
||||
return str.slice(0, num) + '...'
|
||||
}
|
||||
}, function(e, t, n) {
|
||||
"use strict";
|
||||
var r = n(0),
|
||||
|
|
|
@ -42,6 +42,12 @@
|
|||
"integrity": "sha512-+KQ+/koZ7sJXnf5cnCANofY6yXAdYJNEoVZEuWcwJfuWbUp9u6l09I7KhwD+ivU+cdz7JId4V5ukxscWtHdSuw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/electron-devtools-installer": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz",
|
||||
"integrity": "sha512-HJNxpaOXuykCK4rQ6FOMxAA0NLFYsf7FiPFGmab0iQmtVBHSAfxzy3MRFpLTTDDWbV0yD2YsHOQvdu8yCqtCfw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/events": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
|
||||
|
@ -698,6 +704,12 @@
|
|||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
|
@ -760,6 +772,15 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||
|
@ -846,6 +867,12 @@
|
|||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
|
@ -912,6 +939,17 @@
|
|||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.8.1"
|
||||
}
|
||||
},
|
||||
"proto-list": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
|
||||
|
@ -944,6 +982,35 @@
|
|||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
},
|
||||
"react": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz",
|
||||
"integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
|
||||
"integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"scheduler": "^0.19.1"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
|
@ -1037,6 +1104,16 @@
|
|||
"truncate-utf8-bytes": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"scheduler": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
|
||||
"integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
"private": true,
|
||||
"devDependencies": {
|
||||
"@types/auto-launch": "^5.0.1",
|
||||
"@types/electron-devtools-installer": "^2.2.0",
|
||||
"@types/mkdirp": "^1.0.0",
|
||||
"@types/node": "^12.12.39",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"@types/yauzl": "^2.9.1",
|
||||
"electron": "8.3.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"terser": "^4.7.0"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue