multiple fixes, click to show
- run from source fixes - bot useragent fixes - electron version upgrade - pluginCertifier - build shit. working on it.
This commit is contained in:
parent
970c24dbbd
commit
5ea67d33c9
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,29 +1,20 @@
|
||||||
const CleanCSS = require("clean-css")
|
const CleanCSS = require("clean-css")
|
||||||
const fs = require("fs")
|
const fs = require("fs")
|
||||||
const path = require("path")
|
const path = require("path")
|
||||||
const child_process = require("child_process")
|
|
||||||
|
|
||||||
let commit = child_process.execSync("git rev-parse HEAD").toString().split("\n")[0].trim()
|
|
||||||
|
|
||||||
function minify(){
|
function minify(){
|
||||||
let start = Date.now()
|
let start = Date.now()
|
||||||
console.log(`\x1b[33mMinifying...\x1b[0m`)
|
console.log(`\x1b[33mMinifying...\x1b[0m`)
|
||||||
const css = fs.readFileSync(path.join(__dirname, "./src/styles/index.css"), "utf-8")
|
const css = fs.readFileSync(path.join(__dirname, "./src/styles/index.css"), "utf-8")
|
||||||
fs.writeFileSync(path.join(__dirname, "./dist/style.css"), css)
|
fs.writeFileSync(path.join(__dirname, "./dist/style.css"), css)
|
||||||
const output = new CleanCSS({
|
const output = new CleanCSS().minify(css)
|
||||||
sourceMap: true,
|
|
||||||
sourceMapInlineSources: true
|
|
||||||
}).minify(css)
|
|
||||||
if(output.errors.length > 0){
|
if(output.errors.length > 0){
|
||||||
console.error("\x1b[31m"+output.errors.join("\n")+"\x1b[0m")
|
console.error("\x1b[31m"+output.errors.join("\n")+"\x1b[0m")
|
||||||
}
|
}
|
||||||
if(output.warnings.length > 0){
|
if(output.warnings.length > 0){
|
||||||
console.warn("\x1b[33m"+output.warnings.join("\n")+"\x1b[0m")
|
console.warn("\x1b[33m"+output.warnings.join("\n")+"\x1b[0m")
|
||||||
}
|
}
|
||||||
let outputCSS = output.styles + "\n" +
|
fs.writeFileSync(path.join(__dirname, "./dist/style.min.css"), output.styles)
|
||||||
"/*# sourceMappingURL=https://rawcdn.githack.com/Lightcord/Lightcord/"+commit+"/BetterDiscordApp/dist/style.min.css.map*/"
|
|
||||||
fs.writeFileSync(path.join(__dirname, "./dist/style.min.css"), outputCSS)
|
|
||||||
fs.writeFileSync(path.join(__dirname, "./dist/style.min.css.map"), output.sourceMap)
|
|
||||||
console.log(`\x1b[32mMinified in ${(Date.now() - start)}ms. Minified by ${Math.floor(output.stats.efficiency*100)}%\x1b[0m`)
|
console.log(`\x1b[32mMinified in ${(Date.now() - start)}ms. Minified by ${Math.floor(output.stats.efficiency*100)}%\x1b[0m`)
|
||||||
}
|
}
|
||||||
module.exports.minify = minify
|
module.exports.minify = minify
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
const config = require("./webpack.config.js")
|
const config = require("./webpack.config.js")
|
||||||
const { SourceMapDevToolPlugin } = require("webpack")
|
|
||||||
|
|
||||||
config.mode = "production"
|
config.mode = "production"
|
||||||
delete config.devtool
|
config.devtool = "source-map"
|
||||||
config.output.filename = "index.min.js"
|
config.output.filename = "index.min.js"
|
||||||
config.plugins.push(new SourceMapDevToolPlugin({
|
|
||||||
test: /\.(js|jsx|)/,
|
|
||||||
filename: "[name].js.map",
|
|
||||||
publicPath: config.output.publicPath,
|
|
||||||
}))
|
|
||||||
|
|
||||||
module.exports = config
|
module.exports = config
|
|
@ -32,53 +32,53 @@ export default new class PluginCertifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tests = [
|
||||||
|
[/token/gi, 0],
|
||||||
|
[/email/gi, 0],
|
||||||
|
[/mfa/gi, 0],
|
||||||
|
[/2fa/gi, 0],
|
||||||
|
[/phone/gi, 0],
|
||||||
|
[/child_process/gi, 0],
|
||||||
|
[/localStorage/gi, 0],
|
||||||
|
[/getGlobal/gi, 0],
|
||||||
|
[/BrowserWindow/gi, 0],
|
||||||
|
[/\.exe/gi, 0],
|
||||||
|
[/eval/gi, 0],
|
||||||
|
[/WebAssembly/gi, 0],
|
||||||
|
[/XMLHttpRequest(\.|\[["'`])prototype/gi, 0],
|
||||||
|
[/window\.fetch( +)?=/gi, 0],
|
||||||
|
/** Obfuscation / hidden / workarounds */
|
||||||
|
[/(["'`]\+)["'`]\w["'`]/gi, 1],
|
||||||
|
[/["'`]\w["'`](\+["'`])/gi, 1],
|
||||||
|
[/\${["'`]\w+["'`]}/gi, 1],
|
||||||
|
/** hexadecimal */
|
||||||
|
[/_0x\w{4}\('0x[\dabcdef]+'\)/g, 1],
|
||||||
|
[/_0x\w{4}\('0x[\dabcdef]+'( +)?,( +)?'[^']{4}'\)/g, 1], // _0x8db7('0x0', 'x1]f')
|
||||||
|
/** mangled */
|
||||||
|
[/\w+\('0x[\dabcdef]+'\)/g, 1], // b('0x0')
|
||||||
|
[/\w+\('0x[\dabcdef]+'( +)?,( +)?'[^']{4}'\)/g, 1], // b('0x0', 'x1]f')
|
||||||
|
/** string array at start */
|
||||||
|
[/^var [\w\d_$]+=\["/gi, 1]
|
||||||
|
]
|
||||||
|
|
||||||
|
const threats = [
|
||||||
|
"Account Stealer/Virus",
|
||||||
|
"Obfuscation/Hidden code"
|
||||||
|
]
|
||||||
|
|
||||||
export function checkViruses(hash, data, resultCallback, removeCallback, filename){
|
export function checkViruses(hash, data, resultCallback, removeCallback, filename){
|
||||||
data = data.toString("utf8")
|
data = data.toString("utf8")
|
||||||
let isHarmful = false
|
let isHarmful = false
|
||||||
for(let keyword of data.split(/[^\w\d]+/g)){
|
|
||||||
for(let oof of [
|
|
||||||
"token",
|
|
||||||
"email",
|
|
||||||
"phone",
|
|
||||||
"MFA",
|
|
||||||
"2fa",
|
|
||||||
"child_process",
|
|
||||||
"localStorage",
|
|
||||||
"eval",
|
|
||||||
"getGlobal",
|
|
||||||
"BrowserWindow"
|
|
||||||
]){
|
|
||||||
if(keyword.toLowerCase().includes(oof.toLowerCase()) && !keyword.toLowerCase() === "domtokenlist"){
|
|
||||||
console.log(oof, keyword)
|
|
||||||
isHarmful = "token stealer/virus"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(isHarmful)break
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isHarmful){
|
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
const no_comments = data.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "").trim()// removing the META comment from plugins
|
const no_comments = data.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "").trim()// removing all comments from plugins (remove meta and other.)
|
||||||
if((/var [\w\d_$]+=\["/gi).test(no_comments)){
|
|
||||||
isHarmful = "obfuscation/hidden code"
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isHarmful){
|
for(const [test, type] of tests){
|
||||||
const regexps = [
|
const scrpt = type === 1 ? no_comments : data
|
||||||
/** hexadecimal */
|
if(test.exec(scrpt)){
|
||||||
/_0x\w{4}\('0x[\dabcdef]+'\)/g,
|
isHarmful = threats[type]
|
||||||
/_0x\w{4}\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // _0x8db7('0x0', 'x1]f')
|
break
|
||||||
/** mangled */
|
|
||||||
/\w+\('0x[\dabcdef]+'\)/g, // b('0x0')
|
|
||||||
/\w+\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // b('0x0', 'x1]f')
|
|
||||||
]
|
|
||||||
for(let regex of regexps){
|
|
||||||
if(isHarmful)break
|
|
||||||
if(regex.test(no_comments))isHarmful = "obfuscation/hidden code"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,12 @@ export function checkHash(hash, data, filename, resultCallback, removeCallback){
|
||||||
}).then(async res => {
|
}).then(async res => {
|
||||||
if(res.status !== 200){
|
if(res.status !== 200){
|
||||||
if(filename.endsWith(".theme.css"))return removeCallback(hash)
|
if(filename.endsWith(".theme.css"))return removeCallback(hash)
|
||||||
|
try{
|
||||||
checkViruses(hash, data, resultCallback, removeCallback, filename)
|
checkViruses(hash, data, resultCallback, removeCallback, filename)
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
removeCallback()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const result = await res.json()
|
const result = await res.json()
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class V2C_Scroller extends BDV2.reactComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
//scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d scrollerFade-1Ijw5y
|
//scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d scrollerFade-1Ijw5y
|
||||||
let scrollerModule1 = BDModules.get(e => e.scrollerHorizontal)[0]
|
let scrollerModule1 = BDModules.get(e => e.scrollerWrap)[0]
|
||||||
let scrollerModule2 = BDModules.get(e => e.sidebarRegionScroller)[0]
|
let scrollerModule2 = BDModules.get(e => e.sidebarRegionScroller)[0]
|
||||||
let wrapperClass = `${scrollerModule1.scrollerWrap} ${scrollerModule1.scrollerThemed} ${scrollerModule1.themeGhostHairline}${this.props.fade ? " "+scrollerModule1.scrollerFade : ""}`;
|
let wrapperClass = `${scrollerModule1.scrollerWrap} ${scrollerModule1.scrollerThemed} ${scrollerModule1.themeGhostHairline}${this.props.fade ? " "+scrollerModule1.scrollerFade : ""}`;
|
||||||
let scrollerClass = scrollerModule1.scroller+" scroller"; /* fuck */
|
let scrollerClass = scrollerModule1.scroller+" scroller"; /* fuck */
|
||||||
|
|
|
@ -3,10 +3,6 @@ const CircularDependencyPlugin = require("circular-dependency-plugin");
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
const child_process = require("child_process")
|
const child_process = require("child_process")
|
||||||
|
|
||||||
const commit = child_process.execSync("git rev-parse HEAD", {
|
|
||||||
cwd: __dirname
|
|
||||||
}).toString("utf-8").replace(/[^\w\d]/g, "")
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "development",
|
mode: "development",
|
||||||
target: "node",
|
target: "node",
|
||||||
|
@ -16,8 +12,7 @@ module.exports = {
|
||||||
filename: "index.js",
|
filename: "index.js",
|
||||||
path: path.resolve(__dirname, "dist"),
|
path: path.resolve(__dirname, "dist"),
|
||||||
library: "BetterDiscord",
|
library: "BetterDiscord",
|
||||||
libraryTarget: "commonjs2",
|
libraryTarget: "commonjs2"
|
||||||
publicPath: "https://rawcdn.githack.com/Lightcord/Lightcord/"+commit+"/LightcordApi/dist/"
|
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
electron: `electron`,
|
electron: `electron`,
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -6,8 +6,8 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --progress --colors",
|
"build": "webpack --progress --colors",
|
||||||
"watch": "webpack --progress --colors --watch",
|
"watch": "webpack --progress --colors --watch",
|
||||||
"build-prod": "webpack --progress --colors --mode production -o js/main.min.js --devtool source-map",
|
"build-prod": "webpack --progress --colors --config prod.config.js",
|
||||||
"watch-prod": "webpack --progress --colors --watch --mode production -o js/main.min.js --devtool source-map",
|
"watch-prod": "webpack --progress --colors --watch --config prod.config.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"docs": "typedoc --out ../../LightcordApiDocs ./src"
|
"docs": "typedoc --out ../../LightcordApiDocs ./src"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
const config = require("./webpack.config.js")
|
const config = require("./webpack.config.js")
|
||||||
|
|
||||||
config.mode = "production"
|
config.mode = "production"
|
||||||
delete config.devtool
|
config.devtool = "source-map"
|
||||||
config.output.filename = "main.min.js"
|
config.output.filename = "main.min.js"
|
||||||
config.plugins.push(new SourceMapDevToolPlugin({
|
|
||||||
test: /\.(js|jsx|)/,
|
|
||||||
filename: "[name].js.map",
|
|
||||||
publicPath: config.output.publicPath,
|
|
||||||
}))
|
|
||||||
|
|
||||||
module.exports = config
|
module.exports = config
|
|
@ -2,10 +2,6 @@ const path = require("path");
|
||||||
const TerserPlugin = require("terser-webpack-plugin")
|
const TerserPlugin = require("terser-webpack-plugin")
|
||||||
const child_process = require("child_process")
|
const child_process = require("child_process")
|
||||||
|
|
||||||
const commit = child_process.execSync("git rev-parse --short HEAD", {
|
|
||||||
cwd: __dirname
|
|
||||||
}).toString("utf-8")
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "development",
|
mode: "development",
|
||||||
target: "node",
|
target: "node",
|
||||||
|
@ -15,8 +11,7 @@ module.exports = {
|
||||||
filename: "main.js",
|
filename: "main.js",
|
||||||
path: path.resolve(__dirname, "js"),
|
path: path.resolve(__dirname, "js"),
|
||||||
library: "LightcordApi",
|
library: "LightcordApi",
|
||||||
libraryTarget: "commonjs2",
|
libraryTarget: "commonjs2"
|
||||||
publicPath: "https://rawcdn.githack.com/Lightcord/Lightcord/"+commit+"/LightcordApi/js/"
|
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
electron: `electron`,
|
electron: `electron`,
|
||||||
|
|
|
@ -30,7 +30,7 @@ To run from source, follow these instructions:
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/Lightcord/Lightcord
|
git clone https://github.com/Lightcord/Lightcord
|
||||||
cd Lightcord
|
cd Lightcord
|
||||||
npm run devInstall
|
npm run devInstall # Mac/Linux, run "npm run devInstall:64"
|
||||||
npm test
|
npm test
|
||||||
```
|
```
|
||||||
*You will have to do that everytime you pull/clone*
|
*You will have to do that everytime you pull/clone*
|
||||||
|
|
|
@ -26,7 +26,7 @@ fs.readdirSync(MODULES_DIRNAME, {withFileTypes: true})
|
||||||
|
|
||||||
const MODULE_DIRNAME = path.join(__dirname, "modules", "discord_desktop_core", "core")
|
const MODULE_DIRNAME = path.join(__dirname, "modules", "discord_desktop_core", "core")
|
||||||
const BETTERDISCORD_DIRNAME = path.join(__dirname, "BetterDiscordApp")
|
const BETTERDISCORD_DIRNAME = path.join(__dirname, "BetterDiscordApp")
|
||||||
const DISCORDJS_DIRNAME = path.join(__dirname, "BetterDiscordApp")
|
const DISCORDJS_DIRNAME = path.join(__dirname, "DiscordJS")
|
||||||
|
|
||||||
child_process.spawn((process.platform === "win32" ? "npm.cmd" : "npm"), ["i"], {
|
child_process.spawn((process.platform === "win32" ? "npm.cmd" : "npm"), ["i"], {
|
||||||
cwd: MODULE_DIRNAME,
|
cwd: MODULE_DIRNAME,
|
||||||
|
|
|
@ -17,7 +17,7 @@ let hasInit = false
|
||||||
let tries = 0
|
let tries = 0
|
||||||
|
|
||||||
const browserWindow = electron.remote.getCurrentWindow()
|
const browserWindow = electron.remote.getCurrentWindow()
|
||||||
const UserAgent = browserWindow.webContents.userAgent.replace(/lightcord\/[^ ]+/g, "discord/"+require("../discord_native/renderer/app").getVersion())
|
const UserAgent = electron.ipcRenderer.sendSync("LIGHTCORD_GET_USER_AGENT").replace(/lightcord\/[^ ]+/g, "discord/"+require("../discord_native/renderer/app").getVersion())
|
||||||
browserWindow.webContents.userAgent = UserAgent
|
browserWindow.webContents.userAgent = UserAgent
|
||||||
|
|
||||||
exports.init = function(){
|
exports.init = function(){
|
||||||
|
@ -376,6 +376,9 @@ async function privateInit(){
|
||||||
const DOMTools = window.Lightcord.BetterDiscord.DOM
|
const DOMTools = window.Lightcord.BetterDiscord.DOM
|
||||||
|
|
||||||
let isBot = false
|
let isBot = false
|
||||||
|
dispatcher.subscribe("LOGOUT", () => {
|
||||||
|
isBot = false
|
||||||
|
})
|
||||||
;(async function(){
|
;(async function(){
|
||||||
const gatewayModule = await ensureExported(e => e.default && e.default.prototype && e.default.prototype._handleDispatch)
|
const gatewayModule = await ensureExported(e => e.default && e.default.prototype && e.default.prototype._handleDispatch)
|
||||||
if(!gatewayModule)return
|
if(!gatewayModule)return
|
||||||
|
|
|
@ -56,6 +56,7 @@ function startup(bootstrapModules) {
|
||||||
settings.injectSettingsBackend(appSettings.getSettings());
|
settings.injectSettingsBackend(appSettings.getSettings());
|
||||||
require('./discord_native/browser/spellCheck');
|
require('./discord_native/browser/spellCheck');
|
||||||
const windowNative = require('./discord_native/browser/window');
|
const windowNative = require('./discord_native/browser/window');
|
||||||
|
require("./lightcordMainProcess")
|
||||||
|
|
||||||
// expose globals that will be imported by the webapp
|
// expose globals that will be imported by the webapp
|
||||||
// global.releaseChannel is set in bootstrap
|
// global.releaseChannel is set in bootstrap
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* This file is for injections other than already present modules. mostly ipc thing
|
||||||
|
*/
|
||||||
|
|
||||||
|
const electron = require("electron")
|
||||||
|
|
||||||
|
const UserAgent = electron.session.defaultSession.getUserAgent()
|
||||||
|
electron.ipcMain.on("LIGHTCORD_GET_USER_AGENT", (event) => {
|
||||||
|
event.returnValue = UserAgent
|
||||||
|
})
|
|
@ -13,8 +13,8 @@
|
||||||
"build:electron_linux": "electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts|\\.dll)\" --arch=x64 --protocol=discord --platform=\"linux\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,so.4} --overwrite",
|
"build:electron_linux": "electron-packager ./distApp --ignore=\"(distApp|builds|\\.ts|\\.dll)\" --arch=x64 --protocol=discord --platform=\"linux\" --out=builds --icon=app.ico --executable-name=\"Lightcord\" --asar.unpack=*.{node,so.4} --overwrite",
|
||||||
"build:minify": "node build.js",
|
"build:minify": "node build.js",
|
||||||
"build:after": "node afterbuild.js",
|
"build:after": "node afterbuild.js",
|
||||||
"devInstall": "npm i --save-dev --arch=ia32 electron@8.4.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"",
|
"devInstall": "npm i --save-dev --arch=ia32 electron@8.5.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"",
|
||||||
"devInstall:64": "npm i --save-dev --arch=x64 electron@8.4.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"",
|
"devInstall:64": "npm i --save-dev --arch=x64 electron@8.5.0 && node installSubModules.js && echo \"Everything is installed. You should be able to do `npm run test` to compile everything and launch.\"",
|
||||||
"versions": "echo Electron: && electron -v && echo Typescript: && tsc -v"
|
"versions": "echo Electron: && electron -v && echo Typescript: && tsc -v"
|
||||||
},
|
},
|
||||||
"author": "JeanOUINA",
|
"author": "JeanOUINA",
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"auto-launch": "^5.0.5",
|
"auto-launch": "^5.0.5",
|
||||||
"custom-electron-titlebar": "^3.2.2-hotfix62",
|
"custom-electron-titlebar": "^3.2.2-hotfix62",
|
||||||
"electron": "^8.4.0",
|
|
||||||
"glasstron": "0.0.3",
|
"glasstron": "0.0.3",
|
||||||
"mkdirp": "^1.0.4",
|
"mkdirp": "^1.0.4",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^2.6.0",
|
||||||
|
@ -43,6 +42,7 @@
|
||||||
"cross-spawn": "^7.0.3",
|
"cross-spawn": "^7.0.3",
|
||||||
"terser": "^4.7.0",
|
"terser": "^4.7.0",
|
||||||
"typescript": "^3.9.7",
|
"typescript": "^3.9.7",
|
||||||
|
"electron": "8.5.0",
|
||||||
"yazl": "^2.5.1"
|
"yazl": "^2.5.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Todo list
|
# Todo list
|
||||||
Yes, this list is here because I can't remember what to do when I have the time.
|
Yes, this list is here because I can't remember what to do when I have the time.
|
||||||
|
|
||||||
|
\# are issues/pr on github
|
||||||
|
discord links are on [Lightcord's support server](https://discord.gg/7eFff2A)
|
||||||
|
|
||||||
- [x] Fixing #11
|
- [x] Fixing #11
|
||||||
- [x] Fixing #10
|
- [x] Fixing #10
|
||||||
- [ ] Transition from WebViews to BrowserView in tabs
|
- [ ] Transition from WebViews to BrowserView in tabs
|
||||||
|
@ -8,3 +11,7 @@ Yes, this list is here because I can't remember what to do when I have the time.
|
||||||
- [x] Fixing #14
|
- [x] Fixing #14
|
||||||
- [ ] Fixing #15
|
- [ ] Fixing #15
|
||||||
- [x] LazyLoader in LightcordApi.
|
- [x] LazyLoader in LightcordApi.
|
||||||
|
- [ ] Emojis and markdown in notifications.
|
||||||
|
- [ ] https://discord.com/channels/705908350218666117/712993712426450946/745332266594729984
|
||||||
|
- [ ] https://discord.com/channels/705908350218666117/711334559521833110/745411834160611500
|
||||||
|
- [ ] Fixing #21
|
Loading…
Reference in New Issue