2019-06-10 05:40:35 +02:00
|
|
|
import Builtin from "../structs/builtin";
|
2019-06-25 22:36:34 +02:00
|
|
|
import {Settings, DataStore, React, WebpackModules, Events, DOMManager, Strings} from "modules";
|
2019-06-12 06:28:18 +02:00
|
|
|
import CSSEditor from "../ui/customcss/csseditor";
|
2019-06-15 04:11:19 +02:00
|
|
|
import FloatingWindowContainer from "../ui/floating/container";
|
2019-06-11 22:24:57 +02:00
|
|
|
import SettingsTitle from "../ui/settings/title";
|
2019-06-10 05:40:35 +02:00
|
|
|
|
2019-06-15 04:11:19 +02:00
|
|
|
const fs = require("fs");
|
2019-06-10 22:37:50 +02:00
|
|
|
const electron = require("electron");
|
2019-06-15 04:11:19 +02:00
|
|
|
const UserSettings = WebpackModules.getByProps("updateAccount");
|
|
|
|
const Dispatcher = WebpackModules.getByProps("dirtyDispatch");
|
|
|
|
const ActionTypes = WebpackModules.getByProps("ActionTypes").ActionTypes;
|
2019-06-10 22:37:50 +02:00
|
|
|
|
2019-06-10 05:40:35 +02:00
|
|
|
export default new class CustomCSS extends Builtin {
|
|
|
|
get name() {return "Custom CSS";}
|
|
|
|
get category() {return "customcss";}
|
|
|
|
get id() {return "customcss";}
|
2019-06-10 22:37:50 +02:00
|
|
|
get startDetached() {return Settings.get(this.collection, this.category, "startDetached");}
|
|
|
|
get nativeOpen() {return Settings.get(this.collection, this.category, "nativeOpen");}
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super();
|
2019-06-12 06:28:18 +02:00
|
|
|
this.savedCss = "";
|
|
|
|
this.insertedCss = "";
|
2019-06-15 04:11:19 +02:00
|
|
|
this.isDetached = false;
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
2019-06-10 05:40:35 +02:00
|
|
|
|
2019-06-11 04:33:45 +02:00
|
|
|
async enabled() {
|
|
|
|
if (!window.ace) {
|
2019-06-20 04:19:34 +02:00
|
|
|
DOMManager.injectScript("ace-script", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js").then(() => {
|
2019-06-11 04:33:45 +02:00
|
|
|
if (window.require.original) window.require = window.require.original;
|
|
|
|
});
|
|
|
|
}
|
2019-06-25 22:36:34 +02:00
|
|
|
Settings.registerPanel(this.id, Strings.Panels.customcss, {
|
2019-06-10 22:37:50 +02:00
|
|
|
order: 2,
|
2019-06-25 22:36:34 +02:00
|
|
|
element: () => [<SettingsTitle text={Strings.CustomCSS.editorTitle} />, React.createElement(CSSEditor, {
|
2019-06-12 06:28:18 +02:00
|
|
|
css: this.savedCss,
|
2019-06-10 22:37:50 +02:00
|
|
|
save: this.saveCSS.bind(this),
|
|
|
|
update: this.insertCSS.bind(this),
|
2019-06-11 22:24:57 +02:00
|
|
|
openNative: this.openNative.bind(this),
|
2019-06-15 04:11:19 +02:00
|
|
|
openDetached: this.openDetached.bind(this),
|
|
|
|
onChange: this.onChange.bind(this)
|
2019-06-11 22:24:57 +02:00
|
|
|
})],
|
2019-06-10 22:37:50 +02:00
|
|
|
onClick: (thisObject) => {
|
2019-06-15 04:11:19 +02:00
|
|
|
if (this.isDetached) return;
|
2019-06-10 22:37:50 +02:00
|
|
|
if (this.nativeOpen) this.openNative();
|
|
|
|
else if (this.startDetached) this.openDetached();
|
2019-06-26 05:17:16 +02:00
|
|
|
else thisObject._reactInternalFiber.child.memoizedProps.children.props.onSetSection(Strings.Panels.customcss);
|
2019-06-15 04:11:19 +02:00
|
|
|
this.setSection = thisObject._reactInternalFiber.child.memoizedProps.children.props.onSetSection;
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
2019-06-10 05:40:35 +02:00
|
|
|
});
|
2019-06-10 22:37:50 +02:00
|
|
|
this.loadCSS();
|
2019-06-12 06:28:18 +02:00
|
|
|
this.insertCSS(this.savedCss);
|
2019-06-15 04:11:19 +02:00
|
|
|
this.watchContent();
|
2019-06-10 05:40:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
disabled() {
|
|
|
|
Settings.removePanel(this.id);
|
2019-06-15 04:11:19 +02:00
|
|
|
this.unwatchContent();
|
|
|
|
}
|
2019-06-19 05:09:49 +02:00
|
|
|
|
2019-06-15 04:11:19 +02:00
|
|
|
watchContent() {
|
|
|
|
if (this.watcher) return this.error("Already watching content.");
|
|
|
|
const timeCache = {};
|
|
|
|
this.log("Starting to watch content.");
|
|
|
|
this.watcher = fs.watch(DataStore.customCSS, {persistent: false}, async (eventType, filename) => {
|
|
|
|
if (!eventType || !filename) return;
|
|
|
|
await new Promise(r => setTimeout(r, 50));
|
|
|
|
try {fs.statSync(DataStore.customCSS);}
|
|
|
|
catch (err) {
|
|
|
|
if (err.code !== "ENOENT") return;
|
|
|
|
delete timeCache[filename];
|
|
|
|
this.saveCSS("");
|
|
|
|
}
|
|
|
|
const stats = fs.statSync(DataStore.customCSS);
|
|
|
|
if (!stats || !stats.mtime || !stats.mtime.getTime()) return;
|
|
|
|
if (typeof(stats.mtime.getTime()) !== "number") return;
|
|
|
|
if (timeCache[filename] == stats.mtime.getTime()) return;
|
|
|
|
timeCache[filename] = stats.mtime.getTime();
|
|
|
|
if (eventType == "change") {
|
|
|
|
const newCSS = DataStore.loadCustomCSS();
|
|
|
|
if (newCSS == this.savedCss) return;
|
|
|
|
this.savedCss = newCSS;
|
|
|
|
this.insertCSS(this.savedCss);
|
|
|
|
Events.emit("customcss-updated", this.savedCss);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
unwatchContent() {
|
|
|
|
if (!this.watcher) return this.error("Was not watching content.");
|
|
|
|
this.watcher.close();
|
|
|
|
delete this.watcher;
|
|
|
|
this.log("No longer watching content.");
|
|
|
|
}
|
|
|
|
|
|
|
|
onChange(value) {
|
|
|
|
if (!Settings.get("settings", "customcss", "liveUpdate")) return;
|
|
|
|
this.insertCSS(value);
|
|
|
|
this.saveCSS(value);
|
2019-06-10 05:40:35 +02:00
|
|
|
}
|
2019-06-10 22:37:50 +02:00
|
|
|
|
|
|
|
loadCSS() {
|
2019-06-12 06:28:18 +02:00
|
|
|
this.savedCss = DataStore.loadCustomCSS();
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
insertCSS(newCss) {
|
2019-06-12 06:28:18 +02:00
|
|
|
if (typeof(newCss) === "undefined") newCss = this.insertedCss;
|
|
|
|
else this.insertedCss = newCss;
|
2019-06-19 05:09:49 +02:00
|
|
|
DOMManager.updateCustomCSS(newCss);
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
saveCSS(newCss) {
|
2019-06-12 06:28:18 +02:00
|
|
|
if (typeof(newCss) !== "undefined") this.savedCss = newCss;
|
|
|
|
DataStore.saveCustomCSS(this.savedCss);
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
openNative() {
|
|
|
|
electron.shell.openExternal(`file://${DataStore.customCSS}`);
|
|
|
|
}
|
|
|
|
|
2019-06-15 04:11:19 +02:00
|
|
|
openDetached(currentCSS) {
|
|
|
|
const editorRef = React.createRef();
|
|
|
|
const editor = React.createElement(CSSEditor, {
|
|
|
|
id: "bd-floating-editor",
|
2019-06-19 05:09:49 +02:00
|
|
|
ref: editorRef,
|
2019-06-15 04:11:19 +02:00
|
|
|
css: currentCSS,
|
|
|
|
save: this.saveCSS.bind(this),
|
|
|
|
update: this.insertCSS.bind(this),
|
|
|
|
openNative: this.openNative.bind(this),
|
|
|
|
onChange: this.onChange.bind(this)
|
|
|
|
});
|
2019-06-19 21:24:05 +02:00
|
|
|
|
2019-06-15 04:11:19 +02:00
|
|
|
FloatingWindowContainer.open({
|
2019-06-19 05:09:49 +02:00
|
|
|
onClose: () => {
|
|
|
|
this.isDetached = false;
|
|
|
|
},
|
2019-06-15 04:11:19 +02:00
|
|
|
onResize: () => {
|
|
|
|
if (!editorRef || !editorRef.current || !editorRef.current.resize) return;
|
|
|
|
editorRef.current.resize();
|
2019-06-11 22:24:57 +02:00
|
|
|
},
|
2019-06-25 22:36:34 +02:00
|
|
|
title: Strings.CustomCSS.editorTitle,
|
2019-06-15 04:11:19 +02:00
|
|
|
id: "floating-editor-window",
|
|
|
|
height: 470,
|
|
|
|
width: 410,
|
|
|
|
center: true,
|
|
|
|
resizable: true,
|
2019-06-19 05:09:49 +02:00
|
|
|
children: editor,
|
|
|
|
confirmClose: () => {
|
|
|
|
if (!editorRef || !editorRef.current) return false;
|
|
|
|
return editorRef.current.hasUnsavedChanges;
|
|
|
|
},
|
2019-06-25 22:36:34 +02:00
|
|
|
confirmationText: Strings.CustomCSS.confirmationText
|
2019-06-11 04:33:45 +02:00
|
|
|
});
|
2019-06-15 04:11:19 +02:00
|
|
|
this.isDetached = true;
|
|
|
|
UserSettings.close();
|
|
|
|
Dispatcher.dirtyDispatch({type: ActionTypes.LAYER_POP});
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
2019-06-15 04:11:19 +02:00
|
|
|
};
|