updating
This commit is contained in:
parent
8a3b5f752c
commit
6b9ae8f7d2
File diff suppressed because one or more lines are too long
|
@ -4,12 +4,12 @@ export const currentDiscordVersion = (window.DiscordNative && window.DiscordNati
|
|||
export const minSupportedVersion = "0.3.0";
|
||||
export const bbdVersion = "0.3.4";
|
||||
export const bbdChangelog = {
|
||||
description: "LightCord Edition.",
|
||||
description: "Lightcord Edition.",
|
||||
changes: [
|
||||
{
|
||||
title: "What's New?",
|
||||
items: [
|
||||
"**LightCord** is now using BandagedBD. That means all plugins you were using can be used too !",
|
||||
"**Lightcord** is now using BandagedBD. That means all plugins you were using can be used too !",
|
||||
"**Window Transparency** changes were made to more compatible with external window managers and addons like Glasscord.",
|
||||
"Initialization sequence has once again been changed slightly to hopefully improve loading times.",
|
||||
"We removed emotes. That's sad for people who were actually using it, but it was leading to more loading time and some basic words were emote."
|
||||
|
@ -53,7 +53,7 @@ export const settings = {
|
|||
"Copy Selector": {id: "fork-dm-1", info: "Adds a \"Copy Selector\" option to context menus when developer mode is active", implemented: true, hidden: false, cat: "core", category: "developer 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 */
|
||||
/** Lightcord */
|
||||
"Disable BetterDiscord": {id: "bd-disable", info: "Disable Betterdiscord (plugins, themes, etc).", 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"},
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* Based on DiscordCrypt https://github.com/leogx9r/DiscordCrypt
|
||||
*/
|
||||
|
||||
import { readFileSync } from "fs"
|
||||
import { join } from "path"
|
||||
import Utils from "./utils"
|
||||
|
||||
|
||||
let searchModule = BDModules.get(e => e.search)[0]
|
||||
export default new class DiscordCrypt {
|
||||
constructor(){
|
||||
if(!searchModule)searchModule = BDModules.get(e => e.search)[0]
|
||||
this.searchUiClass = Utils.removeDa(`.${searchModule.search} .${searchModule.searchBar}`)
|
||||
}
|
||||
}
|
||||
|
||||
const Constants = {
|
||||
ENCODED_MESSAGE_HEADER: "⢷⢸⢹⢺",
|
||||
ENCODED_KEY_HEADER: "⢻⢼⢽⢾",
|
||||
ENCRYPT_PARAMETER: Buffer.from('DiscordCrypt KEY GENERATION PARAMETER'),
|
||||
AUTH_TAG_PARAMETER: new Uint8Array(Buffer.from('discordCrypt MAC')),
|
||||
PRIMARY_KEY_PARAMETER: new Uint8Array(Buffer.from('discordCrypt-primary-secret')),
|
||||
SECONDARY_KEY_PARAMETER: new Uint8Array(Buffer.from('discordCrypt-secondary-secret')),
|
||||
KEY_IGNORE_TIMEOUT: 60 * 1000,
|
||||
KEY_DELETE_TIMEOUT: 5,
|
||||
ENCRYPT_MODES: [
|
||||
/* Blowfish(Blowfish, AES, Camellia, IDEA, TripleDES) */
|
||||
0, 1, 2, 3, 4,
|
||||
/* AES(Blowfish, AES, Camellia, IDEA, TripleDES) */
|
||||
5, 6, 7, 8, 9,
|
||||
/* Camellia(Blowfish, AES, Camellia, IDEA, TripleDES) */
|
||||
10, 11, 12, 13, 14,
|
||||
/* IDEA(Blowfish, AES, Camellia, IDEA, TripleDES) */
|
||||
15, 16, 17, 18, 19,
|
||||
/* TripleDES(Blowfish, AES, Camellia, IDEA, TripleDES) */
|
||||
20, 21, 22, 23, 24
|
||||
],
|
||||
ENCRYPT_BLOCK_MODES: [
|
||||
'CBC', /* Cipher Block-Chaining */
|
||||
'CFB', /* Cipher Feedback Mode */
|
||||
'OFB', /* Output Feedback Mode */
|
||||
],
|
||||
PADDING_SCHEMES: [
|
||||
'PKC7', /* PKCS #7 */
|
||||
'ANS2', /* ANSI X.923 */
|
||||
'ISO1', /* ISO-10126 */
|
||||
'ISO9', /* ISO-97972 */
|
||||
],
|
||||
UP1_FILE_HOST: 'https://pastebin.synalabs.hosting',
|
||||
UP1_FILE_HOST_API_KEY: '4034a170b4517897238b58ecbe902dee187bf890',
|
||||
ED25519_SIGNING_KEY: 'GTs+VoJSQC6e0GDTVRcskIVBhdqphUwqwrxqp64gXEQ=',
|
||||
UNLOCK_ICON: "PHN2ZyBjbGFzcz0iZGMtc3ZnIiBmaWxsPSJsaWdodGdyZXkiIGhlaWdodD0iMjBweCIgdmlld0JveD0iMCAwI" +
|
||||
"DI0IDI0IiB3aWR0aD0iMjBweCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTIgMTdjMS4xI" +
|
||||
"DAgMi0uOSAyLTJzLS45LTItMi0yLTIgLjktMiAyIC45IDIgMiAyem02LTloLTFWNmMwLTIuNzYtMi4yNC01LTUtNVM3IDMuMjQgN" +
|
||||
"yA2aDEuOWMwLTEuNzEgMS4zOS0zLjEgMy4xLTMuMSAxLjcxIDAgMy4xIDEuMzkgMy4xIDMuMXYySDZjLTEuMSAwLTIgLjktMiAyd" +
|
||||
"jEwYzAgMS4xLjkgMiAyIDJoMTJjMS4xIDAgMi0uOSAyLTJWMTBjMC0xLjEtLjktMi0yLTJ6bTAgMTJINlYxMGgxMnYxMHoiPjwvc" +
|
||||
"GF0aD48L3N2Zz4=",
|
||||
LOCK_ICON: "PHN2ZyBjbGFzcz0iZGMtc3ZnIiBmaWxsPSJsaWdodGdyZXkiIGhlaWdodD0iMjBweCIgdmlld0JveD0iMCAwIDI" +
|
||||
"0IDI0IiB3aWR0aD0iMjBweCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48cGF0aCBkPSJNMCAwaDI" +
|
||||
"0djI0SDBWMHoiIGlkPSJhIi8+PC9kZWZzPjxjbGlwUGF0aCBpZD0iYiI+PHVzZSBvdmVyZmxvdz0idmlzaWJsZSIgeGxpbms6aHJ" +
|
||||
"lZj0iI2EiLz48L2NsaXBQYXRoPjxwYXRoIGNsaXAtcGF0aD0idXJsKCNiKSIgZD0iTTEyIDE3YzEuMSAwIDItLjkgMi0ycy0uOS0" +
|
||||
"yLTItMi0yIC45LTIgMiAuOSAyIDIgMnptNi05aC0xVjZjMC0yLjc2LTIuMjQtNS01LTVTNyAzLjI0IDcgNnYySDZjLTEuMSAwLTI" +
|
||||
"gLjktMiAydjEwYzAgMS4xLjkgMiAyIDJoMTJjMS4xIDAgMi0uOSAyLTJWMTBjMC0xLjEtLjktMi0yLTJ6TTguOSA2YzAtMS43MSA" +
|
||||
"xLjM5LTMuMSAzLjEtMy4xczMuMSAxLjM5IDMuMSAzLjF2Mkg4LjlWNnpNMTggMjBINlYxMGgxMnYxMHoiLz48L3N2Zz4=",
|
||||
DICEWARE_WORD_LIST: readFileSync(join(__dirname, "..", "assets", "diceware.list"), "utf8").split( '\r' ).join( '' ).split( '\n' ),
|
||||
BLACKLISTED_GUILDS: JSON.parse(readFileSync(join(__dirname, "..", "assets", "blacklist.json")))
|
||||
}
|
|
@ -3,8 +3,10 @@
|
|||
*/
|
||||
|
||||
import DOMTools from "./domtools"
|
||||
import Utils from "./utils"
|
||||
|
||||
let selectors
|
||||
const removeDa = Utils.removeDa
|
||||
function getSelectors(){
|
||||
let standardSidebarView = BDModules.get(e => e.standardSidebarView)[0]
|
||||
if(!standardSidebarView)return null
|
||||
|
@ -15,10 +17,6 @@ function getSelectors(){
|
|||
selects.push(`#app-mount .${defaultClassName} .${removeDa(BDModules.get(e => e.userSettingsAccount)[0].userSettingsAccount)} div:nth-child(2)>div:nth-child(2)>.${removeDa(BDModules.get(e => e.viewBody)[0].viewBody)}`)
|
||||
return selects
|
||||
}
|
||||
function removeDa(className){
|
||||
if(!className)return className
|
||||
return className.split(" ").filter(e => !e.startsWith("da-")).join(" ")
|
||||
}
|
||||
|
||||
export default new class BlurPrivate {
|
||||
constructor(){
|
||||
|
|
|
@ -106,7 +106,7 @@ Core.prototype.init = async function() {
|
|||
DataStore.setBDData("version", bbdVersion);
|
||||
}
|
||||
|
||||
await EmojiModule.init()
|
||||
const emojiModule = EmojiModule
|
||||
|
||||
Utils.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
|
||||
Utils.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")();
|
||||
|
|
|
@ -2,6 +2,7 @@ import {bdConfig, settingsCookie} from "../0globals";
|
|||
import DataStore from "./dataStore";
|
||||
import BDV2 from "./v2";
|
||||
import Utils from "./utils";
|
||||
//import DiscordCrypt from "./DiscordCrypt";
|
||||
|
||||
const Constants = {
|
||||
EmojiRegex: /<a?\.(\w+)\.(\d+)>/g
|
||||
|
@ -9,218 +10,222 @@ const Constants = {
|
|||
|
||||
let CustomEmojiModule = BDModules.get(e => e.CustomEmoji)[0]
|
||||
let EmojiModuleApi = BDModules.get(e => e.default && e.default.getCustomEmojiById)[0]
|
||||
let AutocompleteModule = BDModules.get(e => e.default && e.default.displayName === "Autocomplete")
|
||||
let AutocompleteModule = BDModules.get(e => e.default && e.default.displayName === "Autocomplete")[0]
|
||||
let AutoCompletionTemplates = BDModules.get(e => e.getAutocompleteOptions)[0]
|
||||
let EmojiModuleQuery = BDModules.get(e => e.default && e.default.queryEmojiResults)[0]
|
||||
let Messages = BDModules.get(e => e.default && e.default.Messages && e.default.Messages.EMOJI_MATCHING)[0]
|
||||
let guildModule = BDModules.get(e => e.default && e.default.getGuild && e.default.getGuilds && !e.default.isFetching)[0]
|
||||
let emojiSearch = BDModules.get(e => e.default && e.default.getDisambiguatedEmojiContext)
|
||||
|
||||
export default new class EmojiModule {
|
||||
constructor(){}
|
||||
constructor(){
|
||||
this.init()
|
||||
}
|
||||
|
||||
async init(){
|
||||
if(!AutocompleteModule)AutocompleteModule = await window.Lightcord.Api.ensureExported(e => e.default && e.default.displayName === "Autocomplete")
|
||||
if(!AutoCompletionTemplates)AutoCompletionTemplates = await window.Lightcord.Api.ensureExported(e => e.getAutocompleteOptions)
|
||||
if(!EmojiModuleQuery)EmojiModuleQuery = await window.Lightcord.Api.ensureExported(e => e.default && e.default.queryEmojiResults)
|
||||
if(!Messages)Messages = await window.Lightcord.Api.ensureExported(e => e.default && e.default.Messages && e.default.Messages.EMOJI_MATCHING)
|
||||
if(!guildModule)guildModule = await window.Lightcord.Api.ensureExported(e => e.default && e.default.getGuild && e.default.getGuilds && !e.default.isFetching)
|
||||
if(!emojiSearch)emojiSearch = await window.Lightcord.Api.ensureExported(e => e.default && e.default.getDisambiguatedEmojiContext)
|
||||
if(true /** AutocompleteModule && AutoCompletionTemplates && EmojiModuleQuery && Messages && guildModule && emojiSearch */){/*
|
||||
if(!this.cancelAutocompleteRender){
|
||||
this.cancelAutocompleteRender = Utils.monkeyPatch(AutocompleteModule, "default", {
|
||||
|
||||
})
|
||||
}*/
|
||||
console.log(`Patching getAutocompleteOptions of AutoCompletionTemplates`, AutoCompletionTemplates)
|
||||
const getAutocompleteOptions = AutoCompletionTemplates.getAutocompleteOptions
|
||||
AutoCompletionTemplates.getAutocompleteOptions = function(e, t, n, r, a){
|
||||
const value = getAutocompleteOptions.call(this, ...arguments)
|
||||
value.LIGHTCORD_EMOJIS = {
|
||||
matches(arg1, arg2){
|
||||
let condition = arg2.length > 1 && "." === arg1
|
||||
setEmojiUsable(condition)
|
||||
return condition
|
||||
},
|
||||
queryResults(t){
|
||||
let results = EmojiModuleQuery.default.queryEmojiResults(t, e)
|
||||
return results
|
||||
},
|
||||
renderResults(e, t, n, r, a){
|
||||
return D(e, t, a.emojis, n, r, Messages.default.Messages.EMOJI_MATCHING, Messages.default.Messages.EMOJI, AutocompleteModule.default.Emoji, (function(e) {
|
||||
return {
|
||||
emoji: e,
|
||||
key: e.id || e.uniqueName || e.name,
|
||||
sentinel: ".",
|
||||
guild: null != e.guildId ? guildModule.default.getGuild(e.guildId) : null
|
||||
}
|
||||
}), (function(e) {
|
||||
return "." + e + "."
|
||||
}))
|
||||
},
|
||||
getPlainText(id, emojis){
|
||||
var emojis = emojis.emojis;
|
||||
return null == emojis || null == emojis[id] ? "" : "." + emojis[id].name + "."
|
||||
},
|
||||
getRawText(id, guild){
|
||||
var emojis = guild.emojis;
|
||||
if (null == emojis || null == emojis[id]) return "";
|
||||
var emoji = emojis[id],
|
||||
isAnimated = emoji.animated ? "a" : "";
|
||||
return emoji.managed || null == emoji.id ? "." + emoji.name + "." : "<" + isAnimated + "." + (emoji.originalName || emoji.name) + "." + emoji.id + ">"
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
}else{
|
||||
console.error(new Error("Couldn't start autocompletion of Lightcord's emojis."))
|
||||
}
|
||||
|
||||
while (!BDV2.MessageComponent) await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
if (this.cancelEmojiRender) return;
|
||||
this.cancelEmoteRender = Utils.monkeyPatch(BDV2.MessageComponent, "default", {before: (data) => {
|
||||
const message = Utils.getNestedProp(data.methodArguments[0], "childrenMessageContent.props.message")
|
||||
if(!message)return
|
||||
const content = Utils.getNestedProp(data.methodArguments[0], "childrenMessageContent.props.content")
|
||||
if(!content || !content.length)return
|
||||
|
||||
/**
|
||||
* @type {{
|
||||
* raw: string,
|
||||
* name: string,
|
||||
* id: string,
|
||||
* animated: boolean
|
||||
* }[]}
|
||||
*/
|
||||
let emojis = []
|
||||
|
||||
const newContent = []
|
||||
for(let node of content){
|
||||
if (typeof(node) !== "string") {
|
||||
newContent.push(node)
|
||||
continue
|
||||
};
|
||||
let parsed;
|
||||
let hasParsed = false
|
||||
if (!this.cancelEmojiRender){
|
||||
this.cancelEmoteRender = Utils.monkeyPatch(BDV2.MessageComponent, "default", {before: (data) => {
|
||||
const message = Utils.getNestedProp(data.methodArguments[0], "childrenMessageContent.props.message")
|
||||
if(!message)return
|
||||
const content = Utils.getNestedProp(data.methodArguments[0], "childrenMessageContent.props.content")
|
||||
if(!content || !content.length)return
|
||||
|
||||
do {
|
||||
parsed = Constants.EmojiRegex.exec(node);
|
||||
if (parsed) {
|
||||
hasParsed = true
|
||||
if(!EmojiModuleApi)EmojiModuleApi = BDModules.get(e => e.default && e.default.getCustomEmojiById)[0]
|
||||
const emoji = EmojiModuleApi.default.getCustomEmojiById(parsed[2])
|
||||
if(emoji){
|
||||
emojis.push({
|
||||
animated: emoji.animated,
|
||||
name: emoji.name,
|
||||
id: emoji.id,
|
||||
raw: parsed[0]
|
||||
})
|
||||
}else{
|
||||
emojis.push({
|
||||
animated: parsed[0].startsWith("<a"),
|
||||
name: parsed[1],
|
||||
id: parsed[2],
|
||||
raw: parsed[0]
|
||||
})
|
||||
}
|
||||
}
|
||||
} while (parsed);
|
||||
|
||||
if(hasParsed){
|
||||
const words = node.split(" ").map((word, index, arr) => {
|
||||
if(!word)return ""
|
||||
const emoji = emojis.find(e => e.raw == word)
|
||||
if(!emoji)return word
|
||||
if(!CustomEmojiModule)CustomEmojiModule = BDModules.get(e => e.CustomEmoji)[0]
|
||||
return React.createElement(CustomEmojiModule.CustomEmoji, {
|
||||
emoji: {
|
||||
name: `.${emoji.name}.`,
|
||||
emojiId: emoji.id,
|
||||
animated: emoji.animated,
|
||||
jumboable: arr.length === 1 && content.length === 1
|
||||
// content = DiscordCrypt.decryptContent(content)
|
||||
|
||||
/**
|
||||
* @type {{
|
||||
* raw: string,
|
||||
* name: string,
|
||||
* id: string,
|
||||
* animated: boolean
|
||||
* }[]}
|
||||
*/
|
||||
let emojis = []
|
||||
|
||||
const newContent = []
|
||||
for(let node of content){
|
||||
if (typeof(node) !== "string") {
|
||||
newContent.push(node)
|
||||
continue
|
||||
};
|
||||
let parsed;
|
||||
let hasParsed = false
|
||||
|
||||
do {
|
||||
parsed = Constants.EmojiRegex.exec(node);
|
||||
if (parsed) {
|
||||
hasParsed = true
|
||||
if(!EmojiModuleApi)EmojiModuleApi = BDModules.get(e => e.default && e.default.getCustomEmojiById)[0]
|
||||
const emoji = EmojiModuleApi.default.getCustomEmojiById(parsed[2])
|
||||
if(emoji){
|
||||
emojis.push({
|
||||
animated: emoji.animated,
|
||||
name: emoji.name,
|
||||
id: emoji.id,
|
||||
raw: parsed[0]
|
||||
})
|
||||
}else{
|
||||
emojis.push({
|
||||
animated: parsed[0].startsWith("<a"),
|
||||
name: parsed[1],
|
||||
id: parsed[2],
|
||||
raw: parsed[0]
|
||||
})
|
||||
}
|
||||
})
|
||||
}).reduce((previous, current) => {
|
||||
if(previous.length === 0)return [current]
|
||||
if(typeof current === "string"){
|
||||
if(typeof previous[previous.length - 1] === "string"){
|
||||
previous[previous.length - 1] += ` ${current}`
|
||||
}
|
||||
} while (parsed);
|
||||
|
||||
if(hasParsed){
|
||||
const words = node.split(" ").map((word, index, arr) => {
|
||||
if(!word)return ""
|
||||
const emoji = emojis.find(e => e.raw == word)
|
||||
if(!emoji)return word
|
||||
if(!CustomEmojiModule)CustomEmojiModule = BDModules.get(e => e.CustomEmoji)[0]
|
||||
return React.createElement(CustomEmojiModule.CustomEmoji, {
|
||||
emoji: {
|
||||
name: `.${emoji.name}.`,
|
||||
emojiId: emoji.id,
|
||||
animated: emoji.animated,
|
||||
jumboable: arr.length === 1 && content.length === 1
|
||||
}
|
||||
})
|
||||
}).reduce((previous, current) => {
|
||||
if(previous.length === 0)return [current]
|
||||
if(typeof current === "string"){
|
||||
if(typeof previous[previous.length - 1] === "string"){
|
||||
previous[previous.length - 1] += ` ${current}`
|
||||
return previous
|
||||
}
|
||||
previous.push(" "+current)
|
||||
return previous
|
||||
}
|
||||
previous.push(" "+current)
|
||||
previous.push(" ", current)
|
||||
return previous
|
||||
}
|
||||
previous.push(" ", current)
|
||||
return previous
|
||||
}, [])
|
||||
newContent.push(...words)
|
||||
}else{
|
||||
newContent.push(node)
|
||||
}, [])
|
||||
newContent.push(...words)
|
||||
}else{
|
||||
newContent.push(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
while(data.methodArguments[0].childrenMessageContent.props.content[0]){
|
||||
data.methodArguments[0].childrenMessageContent.props.content.shift()
|
||||
}
|
||||
while(newContent[0]){
|
||||
data.methodArguments[0].childrenMessageContent.props.content.push(newContent.shift())
|
||||
}
|
||||
}});
|
||||
|
||||
if(!AutocompleteModule)AutocompleteModule = BDModules.get(e => e.default && e.default.displayName === "Autocomplete")
|
||||
while(data.methodArguments[0].childrenMessageContent.props.content[0]){
|
||||
data.methodArguments[0].childrenMessageContent.props.content.shift()
|
||||
}
|
||||
while(newContent[0]){
|
||||
data.methodArguments[0].childrenMessageContent.props.content.push(newContent.shift())
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
disable(){
|
||||
if (this.cancelEmoteRender) return;
|
||||
if (!this.cancelEmoteRender) return;
|
||||
this.cancelEmoteRender();
|
||||
this.cancelEmoteRender = null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
let loadImageModule = BDModules.get(e => e.loadImage)[0]
|
||||
let getEmojiModule = BDModules.get(e => e.default && e.default.getEmojiURL)[0]
|
||||
|
||||
class Emoji extends React.PureComponent {
|
||||
constructor(props){
|
||||
super(props)
|
||||
this.state = {
|
||||
hover: false
|
||||
}
|
||||
this.key = undefined
|
||||
this.cancelLoadImage = null
|
||||
this.onError = function() {
|
||||
}
|
||||
}
|
||||
|
||||
onError() {
|
||||
var src = this.getSrc();
|
||||
if(src !== null){
|
||||
if(!loadImageModule)loadImageModule = BDModules.get(e => e.loadImage)[0] // lazy load
|
||||
this.cancelLoadImage = loadImageModule.loadImage(src, (e) => {
|
||||
if(!e){
|
||||
this.key = Date.now()
|
||||
this.forceUpdate()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMouseEnter(ev) {
|
||||
this.setState({
|
||||
hover: true
|
||||
});
|
||||
var onMouseEnter = this.props.onMouseEnter;
|
||||
if(onMouseEnter)onMouseEnter(ev)
|
||||
}
|
||||
|
||||
onMouseLeave(ev) {
|
||||
this.setState({
|
||||
hover: false
|
||||
});
|
||||
var onMouseLeave = t.props.onMouseLeave;
|
||||
if(onMouseLeave)onMouseLeave(ev)
|
||||
}
|
||||
|
||||
|
||||
componentWillUnmount() {
|
||||
if(this.cancelLoadImage)this.cancelLoadImage()
|
||||
}
|
||||
|
||||
getSrc(defaultProps) {
|
||||
if(!defaultProps)defaultProps = this.props
|
||||
const props = defaultProps
|
||||
const src = props.src
|
||||
const emojiId = props.emojiId
|
||||
const emojiName = props.emojiName
|
||||
const animated = props.animated
|
||||
const shouldAnimate = props.shouldAnimate
|
||||
const isFocused = props.isFocused
|
||||
const hover = this.state.hover
|
||||
|
||||
if(src)return src
|
||||
if(emojiId){
|
||||
if(!getEmojiModule)getEmojiModule = BDModules.get(e => e.default && e.default.getEmojiURL)[0]
|
||||
return getEmojiModule.default.getEmojiURL({
|
||||
id: emojiId,
|
||||
animated: isFocused && animated && (shouldAnimate || hover)
|
||||
})
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
render() {
|
||||
var props = this.props,
|
||||
emojiName = props.emojiName,
|
||||
animated = props.animated,
|
||||
jumboable = props.jumboable,
|
||||
imgProps = {
|
||||
|
||||
}(props.shouldAnimate, props.isFocused, props.emojiId, props.autoplay, y(props, ["emojiName", "animated", "className", "jumboable", "shouldAnimate", "isFocused", "emojiId", "autoplay"])),
|
||||
src = this.getSrc();
|
||||
if(src){
|
||||
return React.createElement("img", Object.assign({}, imgProps, {
|
||||
key: this.key,
|
||||
src,
|
||||
alt: emojiName || undefined,
|
||||
draggable: false
|
||||
}, animated ? {
|
||||
onMouseEnter: this.onMouseEnter,
|
||||
onMouseLeave: this.onMouseLeave
|
||||
} : {}, {
|
||||
className: `emoji${jumboable ? " jumboable" : ""}`,
|
||||
onError: this.onError
|
||||
}))
|
||||
}
|
||||
return React.createElement("span", {
|
||||
className: "emoji emoji-text"
|
||||
}, undefined, emojiName)
|
||||
}
|
||||
function D(e, t, n, r, o, i, s, u, l, c) {
|
||||
if (null == n || 0 === n.length) return null;
|
||||
var d = n.map((function(e, n) {
|
||||
return React.createElement(u, Object.assign({
|
||||
onClick: o,
|
||||
onHover: r,
|
||||
selected: t === n,
|
||||
index: n
|
||||
}, l(e, n)))
|
||||
}));
|
||||
return [R(i, s, e, c), d]
|
||||
}
|
||||
Emoji.displayName = "Emoji";
|
||||
|
||||
function createEmojiComponent(){
|
||||
return React.createElement(Emoji, Object.assign({}, t, {
|
||||
shouldAnimate: t.animated
|
||||
}))
|
||||
}*/
|
||||
function R(e, t, n, r) {
|
||||
var a = (n.length > 0 ? e.format({
|
||||
prefix: r(n)
|
||||
}) : t)
|
||||
if(Array.isArray(a)){
|
||||
a.unshift(React.createElement("strong", {}, "[Lightcord] "))
|
||||
}else{
|
||||
a = "[LIGHTCORD] "+a
|
||||
}
|
||||
return React.createElement(AutocompleteModule.default.Title, {
|
||||
title: a
|
||||
}, a)
|
||||
}
|
||||
R.displayName = "renderHeader";
|
||||
|
||||
let EmojiFilterModule = BDModules.get(e => e.default && e.default.isEmojiDisabled)[0]
|
||||
let isEmojiDisabled = EmojiFilterModule && EmojiFilterModule.default.isEmojiDisabled
|
||||
let isUsable = false
|
||||
let hasPatched = false
|
||||
|
||||
function setEmojiUsable(usable){
|
||||
isUsable = usable
|
||||
if(hasPatched)return
|
||||
if(!EmojiFilterModule)EmojiFilterModule = BDModules.get(e => e.default && e.default.isEmojiDisabled)[0]
|
||||
if(!EmojiFilterModule)return
|
||||
if(!isEmojiDisabled)isEmojiDisabled = EmojiFilterModule.default.isEmojiDisabled
|
||||
|
||||
hasPatched = true
|
||||
EmojiFilterModule.default.isEmojiDisabled = function(){
|
||||
if(isUsable)return false
|
||||
return isEmojiDisabled.call(this, ...arguments)
|
||||
}
|
||||
}
|
|
@ -348,7 +348,7 @@ export default new class V2_SettingsPanel {
|
|||
BDV2.reactDom.render(this.coreComponent, root);
|
||||
}
|
||||
|
||||
renderLightCordSettings() {
|
||||
renderLightordSettings() {
|
||||
const root = this.root;
|
||||
if (!root) return Utils.err("SettingsPanel", "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i");
|
||||
BDV2.reactDom.render(this.lightcordComponent, root);
|
||||
|
|
|
@ -450,6 +450,11 @@ export default class Utils {
|
|||
onCancel: onCancel
|
||||
}, key);
|
||||
}
|
||||
|
||||
static removeDa(className){
|
||||
if(!className)return className
|
||||
return className.split(" ").filter(e => !e.startsWith("da-")).join(" ")
|
||||
}
|
||||
}
|
||||
|
||||
Utils.showToast = Utils.suppressErrors(Utils.showToast, "Could not show toast.");
|
||||
|
|
|
@ -144,7 +144,7 @@ export default class V2C_PresenceSettings extends React.Component {
|
|||
</button>
|
||||
<button style={{opacity: 0.01}} onclick={() => {
|
||||
remote.shell.openExternal("https://www.youtube.com/watch?v=LkYa7rps_g4", {
|
||||
activate: false
|
||||
activate: true
|
||||
})
|
||||
}}>
|
||||
See ? I pulled a litle sneaky on ya
|
||||
|
@ -293,17 +293,10 @@ class InputChoice extends React.Component {
|
|||
|
||||
class DiscordButton extends React.Component {
|
||||
render(){
|
||||
let setting = this.props.setting
|
||||
|
||||
let rowModule = BDModules.get(e => e.removeKeybind)[0]
|
||||
let marginModule = BDModules.get(e => e.marginBottom20)[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]
|
||||
let flexModule = BDModules.get(e => e._horizontal)[0]
|
||||
let euhModule1 = BDModules.get(e => e.colorTransparent)[0]
|
||||
|
||||
let options = this.props.choices
|
||||
|
||||
return (<div className={rowModule.row+" "+marginModule.marginBottom20}>
|
||||
<div className={`${rowModule.item} ${flexModule.flexChild}`}>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "lightcordapi",
|
||||
"version": "1.0.0",
|
||||
"description": "Lightcord's scripting API",
|
||||
"main": "js/main.js",
|
||||
"scripts": {
|
||||
"build": "webpack --progress --colors",
|
||||
"watch": "webpack --progress --colors --watch",
|
||||
"build-prod": "webpack --progress --colors --mode production -o js/main.min.js --devtool none",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.3.4",
|
||||
"@babel/preset-env": "^7.3.4",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/register": "^7.0.0",
|
||||
"@types/react": "^16.9.36",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"babel-loader": "^8.0.6",
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.5"
|
||||
},
|
||||
"types": "./types/index.ts"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* @name LightcordApiExemple
|
||||
*/
|
||||
|
||||
module.exports = class LightcordApiExemple {
|
||||
getName() {return "Lightcord Api Exemple";} // Name of your plugin to show on the plugins page
|
||||
getDescription() {return "Describe the basic functions. Maybe a support server link.";} // Description to show on the plugins page
|
||||
getVersion() {return "0.0.1";} // Current version. I recommend following semantic versioning <http://semver.org/> (e.g. 0.0.1)
|
||||
getAuthor() {return "Not Thomiz";} // Your name
|
||||
|
||||
load() {} // Called when the plugin is loaded in to memory
|
||||
|
||||
start() {
|
||||
if(!("Lightcord" in window) || !("Api" in window.Lightcord)){
|
||||
bdApi.showToast("This plugin only works in Lightcord.")
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`LightcordAPI is availaible !`)
|
||||
} // Called when the plugin is activated (including after reloads)
|
||||
stop() {} // Called when the plugin is deactivated
|
||||
|
||||
observer(changes) {} // Observer for the `document`. Better documentation than I can provide is found here: <https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver>
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export = window["Reac"+"tDOM"] as typeof import("react-dom")
|
|
@ -0,0 +1 @@
|
|||
export = window.React
|
|
@ -0,0 +1,40 @@
|
|||
import WebpackLoader from "../../modules/WebpackLoader"
|
||||
import { MouseEventHandler } from "react"
|
||||
|
||||
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 : () => {}
|
||||
super(props)
|
||||
}
|
||||
|
||||
render(){
|
||||
let flexModule = WebpackLoader.findByUniqueProperties(["_horizontal"])
|
||||
let euhModule1 = WebpackLoader.findByUniqueProperties(["colorTransparent"])
|
||||
let buttonModule = WebpackLoader.findByUniqueProperties(["buttonWrapper"])
|
||||
let colorsModule = WebpackLoader.findByUniqueProperties(["ButtonColors"])
|
||||
|
||||
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>)
|
||||
}
|
||||
}
|
||||
|
||||
export type ButtonColor = "brand" | "grey" | "red" | "green" | "yellow" | "primary" | "link" | "white" | "black" | "transparent"
|
|
@ -0,0 +1,7 @@
|
|||
import DiscordButton from "./Discord/Button"
|
||||
|
||||
export default {
|
||||
Discord: {
|
||||
Button: DiscordButton
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
import WebpackLoader from "./modules/WebpackLoader"
|
||||
import Components from "./components/components"
|
||||
|
||||
const LightcordApi = {
|
||||
WebpackLoader: WebpackLoader,
|
||||
Components: Components
|
||||
}
|
||||
|
||||
declare global {
|
||||
var React:typeof import("react")
|
||||
interface Window {
|
||||
Lightcord: {
|
||||
DiscordModules: {
|
||||
/**
|
||||
* Internal Discord's dispatcher - can be used to subscribe to gateway events / client events.
|
||||
*/
|
||||
dispatcher: {
|
||||
_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
|
||||
},
|
||||
constants: import("./types/DiscordConstantsTypes").default
|
||||
},
|
||||
Settings: {
|
||||
devMode: boolean,
|
||||
callRingingBeat: boolean
|
||||
},
|
||||
Api: {
|
||||
/**
|
||||
* Lightcord's autorization for lightcord's servers
|
||||
*/
|
||||
Authorization: string,
|
||||
/**
|
||||
* Waits until the first module that match the filter gets exported
|
||||
* @param filter The filter that specifies the module to match.
|
||||
*/
|
||||
ensureExported(filter: (mod:any) => boolean):Promise<any>
|
||||
} & typeof LightcordApi
|
||||
},
|
||||
BDModules: {
|
||||
modules:any[],
|
||||
get(filter:(mod:any)=>boolean, modules?:any[]):any[],
|
||||
get(id:number, modules?:any[]):any,
|
||||
get(ids: [number|((mod:any)=>boolean)], modules?:any[]):any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default LightcordApi
|
||||
|
||||
Object.assign(window.Lightcord.Api, LightcordApi)
|
|
@ -0,0 +1,45 @@
|
|||
const BDModules = window.BDModules
|
||||
|
||||
export default new class WebpackLoader {
|
||||
constructor(){}
|
||||
|
||||
get(id: number):any{
|
||||
return BDModules.get(id)
|
||||
}
|
||||
find(filter: (mod:any) => boolean):any{
|
||||
return BDModules.get(filter)[0]
|
||||
}
|
||||
findByUniqueProperties(props:(string|number)[]):any{
|
||||
return BDModules.get((mod) => {
|
||||
if(mod.__esModule && ("default" in mod)){
|
||||
let doesMatch = true
|
||||
for(let prop of props){
|
||||
if(!Object.prototype.hasOwnProperty.call(mod.default, prop))doesMatch = false
|
||||
}
|
||||
if(doesMatch)return true
|
||||
}
|
||||
for(let prop of props){
|
||||
if(!Object.prototype.hasOwnProperty.call(mod, prop))return false
|
||||
}
|
||||
return true
|
||||
})[0]
|
||||
}
|
||||
filter(filter: (mod:any) => boolean):any[]{
|
||||
return BDModules.get(filter)
|
||||
}
|
||||
filterByUniqueProperties(props:(string|number)[]):any{
|
||||
return BDModules.get((mod) => {
|
||||
if(mod.__esModule && ("default" in mod)){
|
||||
let doesMatch = true
|
||||
for(let prop of props){
|
||||
if(!Object.prototype.hasOwnProperty.call(mod.default, prop))doesMatch = false
|
||||
}
|
||||
if(doesMatch)return true
|
||||
}
|
||||
for(let prop of props){
|
||||
if(!Object.prototype.hasOwnProperty.call(mod, prop))return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": false,
|
||||
"module": "CommonJS",
|
||||
"target": "ES2017",
|
||||
"jsx": "react",
|
||||
"outDir": "./dist",
|
||||
"resolveJsonModule": true,
|
||||
"rootDir": "./src",
|
||||
"sourceMap": true,
|
||||
"declaration": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
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"
|
||||
},
|
||||
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/,
|
||||
}]
|
||||
}
|
||||
};
|
|
@ -31,5 +31,5 @@ Only the freeze at the launch because of the downloading is pretty annoying. So
|
|||
## Plugins & Themes
|
||||
Plugins and themes are not in the standard BetterDiscord folder. They have been moved because betterdiscord supports only stable, ptb and canary release. Using the same directory could cause problems with settings.
|
||||
|
||||
They are located in `%AppData%/LightCord_BD`. This is the main folder for BetterDiscord.
|
||||
They are located in `%AppData%/Lightcord_BD`. This is the main folder for BetterDiscord.
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@ const child_process = require("child_process")
|
|||
const path = require("path")
|
||||
const terser = require("terser")
|
||||
const util = require("util")
|
||||
var rimraf = require("rimraf");
|
||||
|
||||
const production = true
|
||||
|
||||
let electron
|
||||
try{
|
||||
electron = require("electron")
|
||||
|
@ -53,7 +55,7 @@ async function main(){
|
|||
await processNextDir(startDir, {
|
||||
startDir,
|
||||
newDir
|
||||
}, ((filepath) => filepath.endsWith(".js") && !filepath.includes("node_modules")), async (filepath, newpath) => {
|
||||
}, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => {
|
||||
console.info(`Minifying ${filepath} to ${newpath}`)
|
||||
await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8")
|
||||
}).then(() => {
|
||||
|
@ -63,7 +65,7 @@ async function main(){
|
|||
await processNextDir(path.join(__dirname, "modules"), {
|
||||
startDir: path.join(__dirname, "modules"),
|
||||
newDir: path.join(__dirname, "distApp", "modules")
|
||||
}, ((filepath) => filepath.endsWith(".js") && !filepath.includes("node_modules")), async (filepath, newpath) => {
|
||||
}, ((filepath) => filepath.endsWith(".js") && (!production ? !filepath.includes("node_modules") : true)), async (filepath, newpath) => {
|
||||
console.info(`Minifying ${filepath} to ${newpath}`)
|
||||
await fs.promises.writeFile(newpath, terser.minify(await fs.promises.readFile(filepath, "utf8")).code, "utf8")
|
||||
}).then(() => {
|
||||
|
|
|
@ -8,19 +8,20 @@ const fetch = require("node-fetch").default
|
|||
const uuid = require("uuid/v4")
|
||||
|
||||
const events = exports.events = new EventEmitter()
|
||||
const logger = exports.logger = new Logger("LightCord")
|
||||
const logger = exports.logger = new Logger("Lightcord")
|
||||
|
||||
let hasInit = false
|
||||
let tries = 0
|
||||
|
||||
exports.init = function(){
|
||||
if(hasInit == true){
|
||||
console.warn(new Error("LightCord has already inited."))
|
||||
console.warn(new Error("Lightcord has already inited."))
|
||||
return
|
||||
}
|
||||
require("./patchNotifications")
|
||||
hasInit = true
|
||||
let readyInterval = setInterval(()=>{
|
||||
events.emit("debug", `[INIT] try ${tries++} loading LightCord`)
|
||||
events.emit("debug", `[INIT] try ${tries++} loading Lightcord`)
|
||||
try{
|
||||
if(!global.webpackJsonp)return
|
||||
if(!ModuleLoader.get(4))return
|
||||
|
@ -71,7 +72,7 @@ async function privateInit(){
|
|||
return window.Lightcord.Settings.callRingingBeat ? "call_ringing_beat" : "call_ringing"
|
||||
},
|
||||
set(data){
|
||||
console.log("Attempting to set call_ringing value. Canceling "+data)
|
||||
console.log("Attempting to set call_ringing value. Canceling", data)
|
||||
},
|
||||
configurable: false
|
||||
})
|
||||
|
@ -145,7 +146,7 @@ async function privateInit(){
|
|||
*/
|
||||
let DiscordJS
|
||||
try{
|
||||
DiscordJS = require("../../../../../DiscordJS").default
|
||||
//DiscordJS = require("../../../../../DiscordJS").default
|
||||
}catch(err){
|
||||
console.error(err)
|
||||
DiscordJS = null
|
||||
|
@ -178,13 +179,16 @@ async function privateInit(){
|
|||
if(typeof data !== "string" && data !== null)return Authorization
|
||||
appSettings.set("LIGHTCORD_AUTH", Authorization = data)
|
||||
appSettings.save()
|
||||
}
|
||||
},
|
||||
ensureExported
|
||||
},
|
||||
BetterDiscord: { // Global BetterDiscord's exported modules
|
||||
BetterDiscord: { // Global BetterDiscord's exported modules / only for exporting to Lightcord's main script, not for using in plugins
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
require("../../../../../LightcordApi/js/main")
|
||||
|
||||
if(shouldShowPrompt){
|
||||
let onConn = (ev) => {
|
||||
console.log(`Showing auth window.`, ev)
|
||||
|
@ -258,6 +262,7 @@ async function privateInit(){
|
|||
const BetterDiscord = window.BetterDiscord = window.mainCore = new(require("../../../../../BetterDiscordApp/js/main.js").default)(BetterDiscordConfig)
|
||||
|
||||
const Utils = window.Lightcord.BetterDiscord.Utils
|
||||
|
||||
// security delete
|
||||
delete window.Lightcord.BetterDiscord.Utils
|
||||
delete window.Lightcord.BetterDiscord.Utils
|
||||
|
@ -338,9 +343,11 @@ async function privateInit(){
|
|||
logger.log(`Logged in as an user. Skipping`)
|
||||
}
|
||||
}
|
||||
return _handleDispatch.call(this, ...arguments)
|
||||
let returnValue = _handleDispatch.call(this, ...arguments)
|
||||
if(event === "READY" && DiscordJS)DiscordJS.client.emit("ready")
|
||||
return returnValue
|
||||
}
|
||||
function cancelPrototype(methodName){
|
||||
function cancelGatewayPrototype(methodName){
|
||||
if(gatewayModule.default.prototype[methodName]){
|
||||
const original = gatewayModule.default.prototype[methodName]
|
||||
gatewayModule.default.prototype[methodName] = function(){
|
||||
|
@ -348,16 +355,16 @@ async function privateInit(){
|
|||
}
|
||||
}
|
||||
}
|
||||
cancelPrototype("updateGuildSubscriptions")
|
||||
cancelPrototype("callConnect")
|
||||
cancelPrototype("lobbyConnect")
|
||||
cancelPrototype("lobbyDisconnect")
|
||||
cancelPrototype("lobbyVoiceStatesUpdate")
|
||||
cancelPrototype("guildStreamCreate")
|
||||
cancelPrototype("streamWatch")
|
||||
cancelPrototype("streamPing")
|
||||
cancelPrototype("streamDelete")
|
||||
cancelPrototype("streamSetPaused")
|
||||
cancelGatewayPrototype("updateGuildSubscriptions")
|
||||
cancelGatewayPrototype("callConnect")
|
||||
cancelGatewayPrototype("lobbyConnect")
|
||||
cancelGatewayPrototype("lobbyDisconnect")
|
||||
cancelGatewayPrototype("lobbyVoiceStatesUpdate")
|
||||
cancelGatewayPrototype("guildStreamCreate")
|
||||
cancelGatewayPrototype("streamWatch")
|
||||
cancelGatewayPrototype("streamPing")
|
||||
cancelGatewayPrototype("streamDelete")
|
||||
cancelGatewayPrototype("streamSetPaused")
|
||||
const hasUnreadModules = BDModules.get(e => e.default && e.default.hasUnread)
|
||||
hasUnreadModules.forEach((mod) => {
|
||||
const original = mod.default.hasUnread
|
||||
|
@ -778,8 +785,6 @@ async function privateInit(){
|
|||
BetterDiscord.init()
|
||||
|
||||
events.emit("ready")
|
||||
|
||||
if(DiscordJS)DiscordJS.client.emit("ready")
|
||||
}
|
||||
|
||||
require.extensions[".css"] = (m, filename) => {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
const ipcRenderer = require("../discord_native/ipc")
|
||||
|
||||
if(process.platform === "win32"){
|
||||
const originalNotification = window.Notification
|
||||
|
||||
ipcRenderer.send("NOTIFICATIONS_CLEAR")
|
||||
|
||||
const notifications = {}
|
||||
ipcRenderer.on("NOTIFICATION_CLICK", (e, id) => {
|
||||
var notification = notifications[id];
|
||||
if(notification){
|
||||
notification.onclick()
|
||||
notification.close()
|
||||
}
|
||||
})
|
||||
window.Notification = class LightcordNotification {
|
||||
constructor(title, data){
|
||||
this.id = LightcordNotification._id++
|
||||
this.onshow = function() {}
|
||||
this.onclick = function() {}
|
||||
this.onclose = function() {}
|
||||
this.title = title
|
||||
this.body = data.body
|
||||
this.icon = data.icon
|
||||
setTimeout(() => {
|
||||
return this.onshow()
|
||||
}, 0)
|
||||
notifications[this.id] = this
|
||||
ipcRenderer.send("NOTIFICATION_SHOW", {
|
||||
id: this.id,
|
||||
title: this.title,
|
||||
body: this.body,
|
||||
icon: this.icon
|
||||
})
|
||||
}
|
||||
|
||||
static _id = 0
|
||||
|
||||
static requestPermission(callback){
|
||||
callback()
|
||||
}
|
||||
|
||||
static permission = "granted"
|
||||
|
||||
close(){
|
||||
if(!notifications[this.id])return
|
||||
|
||||
delete notifications[this.id]
|
||||
ipcRenderer.send("NOTIFICATION_CLOSE", this.id)
|
||||
this.onclose()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,14 +5,17 @@ const ipcRenderer = electron.ipcRenderer;
|
|||
|
||||
// We prefix events with the `DISCORD_` string to prevent malicious use
|
||||
function send(event, ...args) {
|
||||
console.log(`[DEBUG]: send -> ${event}:`, ...args)
|
||||
ipcRenderer.send(`DISCORD_${event}`, ...args);
|
||||
}
|
||||
|
||||
function on(event, callback) {
|
||||
console.log(`[DEBUG]: on -> ${event}:`, callback)
|
||||
ipcRenderer.on(`DISCORD_${event}`, callback);
|
||||
}
|
||||
|
||||
function removeListener(event, callback) {
|
||||
console.log(`[DEBUG]: removeListener -> ${event}:`, callback)
|
||||
ipcRenderer.removeListener(`DISCORD_${event}`, callback);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,17 @@ Object.defineProperty(exports, "__esModule", {
|
|||
var _electron = require('electron');
|
||||
|
||||
exports.default = {
|
||||
on: (event, callback) => _electron.ipcMain.on(`DISCORD_${event}`, callback),
|
||||
removeListener: (event, callback) => _electron.ipcMain.removeListener(`DISCORD_${event}`, callback),
|
||||
reply: (event, channel, ...args) => event.sender.send(`DISCORD_${channel}`, ...args)
|
||||
on: (event, callback) => {
|
||||
console.log(`[DEBUG]: on -> ${event}:`, callback)
|
||||
_electron.ipcMain.on(`DISCORD_${event}`, callback)
|
||||
},
|
||||
removeListener: (event, callback) => {
|
||||
console.log(`[DEBUG]: removeListener -> ${event}:`, callback)
|
||||
_electron.ipcMain.removeListener(`DISCORD_${event}`, callback)
|
||||
},
|
||||
reply: (event, channel, ...args) => {
|
||||
console.log(`[DEBUG]: reply -> ${event} -> ${channel} :`, callback)
|
||||
event.sender.send(`DISCORD_${channel}`, ...args)
|
||||
}
|
||||
};
|
||||
module.exports = exports.default;
|
|
@ -169,6 +169,7 @@ function setWindowVisible(isVisible, andUnminimize) {
|
|||
if (isVisible) {
|
||||
if (andUnminimize || !mainWindow.isMinimized()) {
|
||||
mainWindow.show();
|
||||
mainWindow.focus()
|
||||
webContentsSend('MAIN_WINDOW_FOCUS');
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,29 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 168 190" enable-background="new 0 0 168 190" xml:space="preserve">
|
||||
viewBox="0 0 168 190" style="enable-background:new 0 0 168 190;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:url(#SVGID_1_);}
|
||||
.st2{fill:url(#SVGID_2_);}
|
||||
.st3{fill:url(#SVGID_3_);}
|
||||
</style>
|
||||
<g>
|
||||
<rect x="14.4" y="46.1" fill="#FFFFFF" width="139.2" height="97.7"/>
|
||||
<rect x="14.9" y="35.3" class="st0" width="139.2" height="97.7"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="66.6616" y1="79.7119" x2="66.6616" y2="100.7434">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="66.7" y1="112.3" x2="66.7" y2="91.2685" gradientTransform="matrix(1 0 0 -1 0 192)">
|
||||
<stop offset="0" style="stop-color:#E30613"/>
|
||||
<stop offset="1" style="stop-color:#731A14"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_1_)" d="M66.7,79.7c-5.4,0-9.8,4.7-9.8,10.5c0,5.8,4.4,10.5,9.8,10.5c5.4,0,9.8-4.7,9.8-10.5
|
||||
C76.5,84.4,72.1,79.7,66.7,79.7z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="101.661" y1="79.7119" x2="101.661" y2="100.7434">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
<path class="st1" d="M66.7,79.7c-5.4,0-9.8,4.7-9.8,10.5s4.4,10.5,9.8,10.5s9.8-4.7,9.8-10.5C76.5,84.4,72.1,79.7,66.7,79.7z"/>
|
||||
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="101.7" y1="112.3" x2="101.7" y2="91.2685" gradientTransform="matrix(1 0 0 -1 0 192)">
|
||||
<stop offset="0" style="stop-color:#E20613"/>
|
||||
<stop offset="1" style="stop-color:#731A13"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_2_)" d="M101.7,79.7c-5.4,0-9.8,4.7-9.8,10.5c0,5.8,4.4,10.5,9.8,10.5c5.4,0,9.8-4.7,9.8-10.5
|
||||
C111.5,84.4,107.1,79.7,101.7,79.7z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="84" y1="-4.545736e-07" x2="84" y2="190">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
<path class="st2" d="M101.7,79.7c-5.4,0-9.8,4.7-9.8,10.5s4.4,10.5,9.8,10.5s9.8-4.7,9.8-10.5C111.5,84.4,107.1,79.7,101.7,79.7z"
|
||||
/>
|
||||
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="84" y1="192" x2="84" y2="2" gradientTransform="matrix(1 0 0 -1 0 192)">
|
||||
<stop offset="0" style="stop-color:#E30613"/>
|
||||
<stop offset="1" style="stop-color:#731A13"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_3_)" d="M148.4,0H19.6C8.8,0,0,8.8,0,19.6v128.4c0,10.8,8.8,19.6,19.6,19.6h108.9l-5.1-17.5l12.3,11.3
|
||||
l11.6,10.7L168,190v-41.9v-9.5V19.6C168,8.8,159.2,0,148.4,0z M111.3,124.1c0,0-3.4-4.1-6.3-7.7c12.6-3.5,17.4-11.3,17.4-11.3
|
||||
<path class="st3" d="M148.4,0H19.6C8.8,0,0,8.8,0,19.6V148c0,10.8,8.8,19.6,19.6,19.6h108.9l-5.1-17.5l12.3,11.3l11.6,10.7
|
||||
L168,190v-41.9v-9.5v-119C168,8.8,159.2,0,148.4,0z M111.3,124.1c0,0-3.4-4.1-6.3-7.7c12.6-3.5,17.4-11.3,17.4-11.3
|
||||
c-4,2.6-7.7,4.4-11.1,5.6c-4.8,2-9.5,3.3-14,4.1c-9.2,1.7-17.6,1.3-24.9-0.1c-5.5-1-10.2-2.5-14.1-4.1c-2.2-0.8-4.6-1.9-7.1-3.3
|
||||
c-0.3-0.2-0.6-0.3-0.9-0.5c-0.1-0.1-0.3-0.2-0.4-0.2c-1.7-1-2.6-1.6-2.6-1.6s4.6,7.6,16.8,11.2c-2.9,3.6-6.4,7.9-6.4,7.9
|
||||
c-21.2-0.6-29.3-14.5-29.3-14.5c0-30.6,13.8-55.4,13.8-55.4c13.8-10.3,26.9-10,26.9-10l1,1.1C52.8,50.3,45,57.9,45,57.9
|
||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.4 KiB |
File diff suppressed because one or more lines are too long
|
@ -6,7 +6,9 @@
|
|||
"scripts": {
|
||||
"test": "tsc && electron .",
|
||||
"run": "electron .",
|
||||
"build": "electron compile.js && electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts)\" --arch=ia32 --win32metadata.ProductName=\"Lightcord\" --win32metadata.CompanyName=\"Discord Inc.\" --protocol=discord --platform=\"win32\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,dll} --overwrite",
|
||||
"build": "npm run build:minify && npm run build:electron",
|
||||
"build:electron": "electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts)\" --arch=ia32 --win32metadata.ProductName=\"Lightcord\" --win32metadata.CompanyName=\"Lightcord Inc.\" --protocol=discord --platform=\"win32\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,dll} --overwrite",
|
||||
"build:minify": "electron compile.js",
|
||||
"devInstall": "npm i -g --arch=ia32 electron@8.3.0 && npm i -g typescript && npm i --save-dev @types/node@12.12.39 && npm i --save-dev --arch=ia32 electron@8.3.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\""
|
||||
},
|
||||
"author": "",
|
||||
|
|
|
@ -52,7 +52,7 @@ function hasArgvFlag(flag) {
|
|||
//Transform main thread into async
|
||||
(async function Main(){
|
||||
await electron.app.whenReady()
|
||||
console.log(`LightCord Init...`)
|
||||
console.log(`Lightcord Init...`)
|
||||
if(!electron.app.commandLine.hasSwitch('enable-transparent-visuals'))electron.app.commandLine.appendSwitch('enable-transparent-visuals');
|
||||
electron.app.setAppUserModelId(Constants.APP_ID);
|
||||
let coreModule
|
||||
|
|
Loading…
Reference in New Issue