Discord's css is minified, with it's classes following the format name-hash. When they pushed a new asset to the canary build, the classes got renamed:
This means the classes on the themes don't relate to any discord class anymore.
Luckily, thanks to Davri1, we were able to extract the css classes from the assets in both the stable build and the canary build. This means we can create a dictionary for the old and new classes
This is done in a 3 step proccess:
- The classes are grouped in the js asset. We can then find perfect matches between groups
- Sometimes some classes are deprecated, added or moved around in the new asset. We then need to find the best pairs of grouped classes. In other words, groups with high similarity
- The few unmatched classes get matched with the first unused class (usually the only one left of their kind)
With this information we can do a simple search and replace for all the classes.
Tool | link |
---|---|
Update-Classes - replace classes of single css and scss files |
website |
Discor-Theme-Updater - replace classes of single css and scss files |
website |
Class Finder v2 - find pairs of classes using the url's of the js assets |
py script |
canary-broke-themes-again.py - automaticaly find theme files and replace classes* |
py script |
If a theme doesn't work after patching with the site or the script, check if it uses a remote file, something like this:
@import url("https://github.com/user/repo/raw/master/filename.scss");
If there is an import like this, download the file, place it in that theme's folder, change the extentions to scss
, and change the import to something like:
@import "./filename.scss"
- CSS replacer (source)
Use Console (Ctrl+Shift+i
)
Find and replace classes from a link (replaceRAW_LINK_TO_THEME
with the link to the css file you want to convert)
output = await Promise.all([
fetch("https://cdn.discordapp.com/attachments/126228856477712384/930142142595211344/classes.json").then(res => res.json()),
fetch("RAW_LINK_TO_THEME").then(res => res.text())
]).then(([classes, theme]) => {
for (let i = 0; i < classes.length; i++) {
const [ptb, canary] = classes[i];
for (let i = 0; i < ptb.length; i++) {
const ptbClass = ptb[i];
const canaryClass = canary[i];
theme = theme.replaceAll(ptbClass, canaryClass);
}
}
return theme;
})
After that, copy output
to a file
- Theme fixer (source)
Use Simple Eval's.eval_async
command
Automaticaly find theme files and replace classes.
const path = require('path');
const fs = require("fs");
const glob = require('glob');
const { get } = require('powercord/http');
const homedir = require("os").homedir();
let keep_old = true;
let use_old = true;
let fix_quickcss = true;
let default_path = true;
let powercorddir = "";
if (default_path) powercorddir = path.join(homedir,"powercord");
else powercorddir = ""; // replace with custom powercord folder location
const buf = await get("https://gist.githubusercontent.com/D-Brox/5ea0d9cec29c4921a9e397163f447646/raw/classes2.txt").then(r => r.body);
let classes = buf.toString().split("\n").map( r => r.split(" = "));
let themesdir = path.join(powercorddir,"src","Powercord","themes"); // change this if you want to run in other places
let files = glob.sync("**/*.*css",{ cwd: themesdir});
let exists = s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
let replace_classes = (file_path) => {
let css = "";
if (use_old && exists(file_path+".old")) css = fs.readFileSync(file_path+".old").toString();
else {css = fs.readFileSync(file_path).toString();
if (keep_old && !exists(file_path+".old")) fs.copyFileSync(file_path,file_path+".old");}
if (css.includes("@import url")) console.log("%s contains remote imports", file_path);
for (let i in classes) css = css.replace(new RegExp(classes[i][0], 'g'),classes[i][1]);
fs.writeFileSync(file_path,css);
}
files.map(f => replace_classes(path.join(themesdir,f)));
if (fix_quickcss) replace_classes(path.join(powercorddir,"/src/Powercord/plugins/pc-moduleManager/quickcss.css"));
- Class list (source)
Use Console (Ctrl+Shift+i
), useful for theme devs
List all (div) classnames matching your input
Array.from(document.getElementsByTagName('*')).forEach((keys) => {
if (keys.getAttribute('class') && keys.getAttribute('class').includes('YOUR_CLASSNAME'))
console.log(keys.getAttribute('class'));
})
We now have the tools necessary to fix themes in the future by using just the js assets. That way we could fix themes in a couple of minutes, if this ever happens again.
laynetheepic has changed his name to
lanye74
, so thePC-Theme-Converter
is at https://lanye74.github.io/projects/pc-theme-converter/