Merge pull request #2707 from MartinFournier/feature/theme-browser
Add Theme Browser accessible from GameOptions
@ -8,4 +8,8 @@ module.exports = {
|
||||
'.cypress', 'node_modules', 'dist',
|
||||
],
|
||||
testEnvironment: "jsdom",
|
||||
moduleNameMapper: {
|
||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/__mocks__/fileMock.js",
|
||||
"\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
|
||||
}
|
||||
};
|
||||
|
@ -71,6 +71,7 @@
|
||||
"electron": "^14.0.2",
|
||||
"electron-packager": "^15.4.0",
|
||||
"eslint": "^7.24.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"fork-ts-checker-webpack-plugin": "^6.3.3",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"http-server": "^13.0.1",
|
||||
|
@ -11,6 +11,7 @@ cp index.html .package
|
||||
cp -r electron/* .package
|
||||
cp -r dist/ext .package/dist
|
||||
cp -r dist/icons .package/dist
|
||||
cp -r dist/images .package/dist
|
||||
|
||||
# The css files
|
||||
cp dist/vendor.css .package/dist
|
||||
|
6
src/@types/global.d.ts
vendored
@ -1,2 +1,8 @@
|
||||
// Defined by webpack on startup or compilation
|
||||
declare let __COMMIT_HASH__: string;
|
||||
|
||||
// When using file-loader, we'll get a path to the resource
|
||||
declare module "*.png" {
|
||||
const value: string;
|
||||
export default value;
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { GameInfo, IStyleSettings, UserInterface as IUserInterface, UserInterfaceTheme } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { ThemeEvents } from "../ui/React/Theme";
|
||||
import { defaultTheme } from "../Settings/Themes";
|
||||
import { defaultStyles } from "../Settings/Styles";
|
||||
import { ThemeEvents } from "../Themes/ui/Theme";
|
||||
import { defaultTheme } from "../Themes/Themes";
|
||||
import { defaultStyles } from "../Themes/Styles";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { hash } from "../hash/hash";
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ISelfInitializer, ISelfLoading } from "../types";
|
||||
import { OwnedAugmentationsOrderSetting, PurchaseAugmentationsOrderSetting } from "./SettingEnums";
|
||||
import { defaultTheme, ITheme } from "./Themes";
|
||||
import { defaultStyles } from "./Styles";
|
||||
import { defaultTheme, ITheme } from "../Themes/Themes";
|
||||
import { defaultStyles } from "../Themes/Styles";
|
||||
import { WordWrapOptions } from "../ScriptEditor/ui/Options";
|
||||
import { OverviewSettings } from "../ui/React/Overview";
|
||||
import { IStyleSettings } from "../ScriptEditor/NetscriptDefinitions";
|
||||
|
@ -1,613 +0,0 @@
|
||||
import { IMap } from "../types";
|
||||
|
||||
export interface ITheme {
|
||||
[key: string]: string | undefined;
|
||||
primarylight: string;
|
||||
primary: string;
|
||||
primarydark: string;
|
||||
successlight: string;
|
||||
success: string;
|
||||
successdark: string;
|
||||
errorlight: string;
|
||||
error: string;
|
||||
errordark: string;
|
||||
secondarylight: string;
|
||||
secondary: string;
|
||||
secondarydark: string;
|
||||
warninglight: string;
|
||||
warning: string;
|
||||
warningdark: string;
|
||||
infolight: string;
|
||||
info: string;
|
||||
infodark: string;
|
||||
welllight: string;
|
||||
well: string;
|
||||
white: string;
|
||||
black: string;
|
||||
hp: string;
|
||||
money: string;
|
||||
hack: string;
|
||||
combat: string;
|
||||
cha: string;
|
||||
int: string;
|
||||
rep: string;
|
||||
disabled: string;
|
||||
backgroundprimary: string;
|
||||
backgroundsecondary: string;
|
||||
button: string;
|
||||
}
|
||||
|
||||
export interface IPredefinedTheme {
|
||||
colors: ITheme;
|
||||
name?: string;
|
||||
credit?: string;
|
||||
description?: string;
|
||||
reference?: string;
|
||||
}
|
||||
|
||||
export const defaultTheme: ITheme = {
|
||||
primarylight: "#0f0",
|
||||
primary: "#0c0",
|
||||
primarydark: "#090",
|
||||
successlight: "#0f0",
|
||||
success: "#0c0",
|
||||
successdark: "#090",
|
||||
errorlight: "#f00",
|
||||
error: "#c00",
|
||||
errordark: "#900",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#000",
|
||||
backgroundsecondary: "#000",
|
||||
button: "#333",
|
||||
};
|
||||
|
||||
export const getPredefinedThemes = (): IMap<IPredefinedTheme> => ({
|
||||
Default: {
|
||||
colors: defaultTheme,
|
||||
},
|
||||
Monokai: {
|
||||
description: "Monokai'ish",
|
||||
colors: {
|
||||
primarylight: "#FFF",
|
||||
primary: "#F8F8F2",
|
||||
primarydark: "#FAFAEB",
|
||||
successlight: "#ADE146",
|
||||
success: "#A6E22E",
|
||||
successdark: "#98E104",
|
||||
errorlight: "#FF69A0",
|
||||
error: "#F92672",
|
||||
errordark: "#D10F56",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#E1D992",
|
||||
warning: "#E6DB74",
|
||||
warningdark: "#EDDD54",
|
||||
infolight: "#92E1F1",
|
||||
info: "#66D9EF",
|
||||
infodark: "#31CDED",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#F92672",
|
||||
money: "#E6DB74",
|
||||
hack: "#A6E22E",
|
||||
combat: "#75715E",
|
||||
cha: "#AE81FF",
|
||||
int: "#66D9EF",
|
||||
rep: "#E69F66",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#272822",
|
||||
backgroundsecondary: "#1B1C18",
|
||||
button: "#333",
|
||||
},
|
||||
},
|
||||
|
||||
Warmer: {
|
||||
credit: "hexnaught",
|
||||
description: "Warmer, softer theme",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/921999581020028938",
|
||||
colors: {
|
||||
primarylight: "#EA9062",
|
||||
primary: "#DD7B4A",
|
||||
primarydark: "#D3591C",
|
||||
successlight: "#6ACF6A",
|
||||
success: "#43BF43",
|
||||
successdark: "#3E913E",
|
||||
errorlight: "#C15757",
|
||||
error: "#B34141",
|
||||
errordark: "#752525",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#E6E69D",
|
||||
warning: "#DADA56",
|
||||
warningdark: "#A1A106",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#AD84CF",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#76C6B7",
|
||||
backgroundprimary: "#000",
|
||||
backgroundsecondary: "#000",
|
||||
button: "#333",
|
||||
},
|
||||
},
|
||||
|
||||
"Dark+": {
|
||||
credit: "LoganMD",
|
||||
description: "VSCode Dark+",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/921999975867617310",
|
||||
colors: {
|
||||
primarylight: "#E0E0BC",
|
||||
primary: "#CCCCAE",
|
||||
primarydark: "#B8B89C",
|
||||
successlight: "#00F000",
|
||||
success: "#00D200",
|
||||
successdark: "#00B400",
|
||||
errorlight: "#F00000",
|
||||
error: "#C80000",
|
||||
errordark: "#A00000",
|
||||
secondarylight: "#B4AEAE",
|
||||
secondary: "#969090",
|
||||
secondarydark: "#787272",
|
||||
warninglight: "#F0F000",
|
||||
warning: "#C8C800",
|
||||
warningdark: "#A0A000",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#1E1E1E",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#1E1E1E",
|
||||
backgroundsecondary: "#252525",
|
||||
button: "#333",
|
||||
},
|
||||
},
|
||||
|
||||
"Mayukai Dark": {
|
||||
credit: "Festive Noire",
|
||||
description: "Mayukai Dark-esque",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922037502334889994",
|
||||
colors: {
|
||||
primarylight: "#DDDFC5",
|
||||
primary: "#CDCFB6",
|
||||
primarydark: "#9D9F8C",
|
||||
successlight: "#00EF00",
|
||||
success: "#00A500",
|
||||
successdark: "#007A00",
|
||||
errorlight: "#F92672",
|
||||
error: "#CA1C5C",
|
||||
errordark: "#90274A",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#D3D300",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#00010A",
|
||||
white: "#fff",
|
||||
black: "#020509",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#8CCF27",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#080C11",
|
||||
backgroundsecondary: "#03080F",
|
||||
button: "#00010A",
|
||||
},
|
||||
},
|
||||
|
||||
Purple: {
|
||||
credit: "zer0ney",
|
||||
description: "Essentially all defaults except for purple replacing the main colors",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922091815849570395",
|
||||
colors: {
|
||||
primarylight: "#BA55D3",
|
||||
primary: "#9370DB",
|
||||
primarydark: "#8A2BE2",
|
||||
successlight: "#BA55D3",
|
||||
success: "#9370DB",
|
||||
successdark: "#8A2BE2",
|
||||
errorlight: "#f00",
|
||||
error: "#c00",
|
||||
errordark: "#900",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#000",
|
||||
backgroundsecondary: "#000",
|
||||
button: "#333",
|
||||
},
|
||||
},
|
||||
|
||||
"Smooth Green": {
|
||||
credit: "Swidt",
|
||||
description: "A nice green theme that doesn't hurt your eyes.",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922243957986033725",
|
||||
colors: {
|
||||
primarylight: "#E0E0BC",
|
||||
primary: "#B0D9A3",
|
||||
primarydark: "#B8B89C",
|
||||
successlight: "#00F000",
|
||||
success: "#6BC16B",
|
||||
successdark: "#00B400",
|
||||
errorlight: "#F00000",
|
||||
error: "#3D713D",
|
||||
errordark: "#A00000",
|
||||
secondarylight: "#B4AEAE",
|
||||
secondary: "#8FAF85",
|
||||
secondarydark: "#787272",
|
||||
warninglight: "#F0F000",
|
||||
warning: "#38F100",
|
||||
warningdark: "#A0A000",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#2F3C2B",
|
||||
white: "#fff",
|
||||
black: "#1E1E1E",
|
||||
hp: "#dd3434",
|
||||
money: "#4AA52E",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#35A135",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#1E1E1E",
|
||||
backgroundsecondary: "#252525",
|
||||
button: "#2F3C2B",
|
||||
},
|
||||
},
|
||||
|
||||
Dracula: {
|
||||
credit: "H3draut3r",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922296307836678144",
|
||||
colors: {
|
||||
primarylight: "#7082B8",
|
||||
primary: "#F8F8F2",
|
||||
primarydark: "#FF79C6",
|
||||
successlight: "#0f0",
|
||||
success: "#0c0",
|
||||
successdark: "#090",
|
||||
errorlight: "#FD4545",
|
||||
error: "#FF2D2D",
|
||||
errordark: "#C62424",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#8BE9FD",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#FFC281",
|
||||
warning: "#FFB86C",
|
||||
warningdark: "#E6A055",
|
||||
infolight: "#A0A0FF",
|
||||
info: "#7070FF",
|
||||
infodark: "#4040FF",
|
||||
welllight: "#44475A",
|
||||
well: "#363948",
|
||||
white: "#fff",
|
||||
black: "#282A36",
|
||||
hp: "#D34448",
|
||||
money: "#50FA7B",
|
||||
hack: "#F1FA8C",
|
||||
combat: "#BD93F9",
|
||||
cha: "#FF79C6",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#282A36",
|
||||
backgroundsecondary: "#21222C",
|
||||
button: "#21222C",
|
||||
},
|
||||
},
|
||||
|
||||
"Dark Blue": {
|
||||
credit: "Saynt_Garmo",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/923084732718264340",
|
||||
colors: {
|
||||
primarylight: "#023DDE",
|
||||
primary: "#4A41C8",
|
||||
primarydark: "#005299",
|
||||
successlight: "#00FF00",
|
||||
success: "#D1DAD1",
|
||||
successdark: "#BFCABF",
|
||||
errorlight: "#f00",
|
||||
error: "#c00",
|
||||
errordark: "#900",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#040505",
|
||||
white: "#fff",
|
||||
black: "#000000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#091419",
|
||||
backgroundsecondary: "#000000",
|
||||
button: "#000000",
|
||||
},
|
||||
},
|
||||
|
||||
Discord: {
|
||||
credit: "Thermite",
|
||||
description: "Discord inspired theme",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/924305252017143818",
|
||||
colors: {
|
||||
primarylight: "#7389DC",
|
||||
primary: "#7389DC",
|
||||
primarydark: "#5964F1",
|
||||
successlight: "#00CC00",
|
||||
success: "#20DF20",
|
||||
successdark: "#0CB80C",
|
||||
errorlight: "#EA5558",
|
||||
error: "#EC4145",
|
||||
errordark: "#E82528",
|
||||
secondarylight: "#C3C3C3",
|
||||
secondary: "#9C9C9C",
|
||||
secondarydark: "#4E4E4E",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#1C4FB3",
|
||||
welllight: "#999999",
|
||||
well: "#35383C",
|
||||
white: "#FFFFFF",
|
||||
black: "#202225",
|
||||
hp: "#FF5656",
|
||||
money: "#43FF43",
|
||||
hack: "#FFAB3D",
|
||||
combat: "#8A90FD",
|
||||
cha: "#FF51D9",
|
||||
int: "#6495ed",
|
||||
rep: "#FFFF30",
|
||||
disabled: "#474B51",
|
||||
backgroundprimary: "#2F3136",
|
||||
backgroundsecondary: "#35393E",
|
||||
button: "#333",
|
||||
},
|
||||
},
|
||||
|
||||
"One Dark": {
|
||||
credit: "Dexalt142",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/924650660694208512",
|
||||
colors: {
|
||||
primarylight: "#98C379",
|
||||
primary: "#98C379",
|
||||
primarydark: "#98C379",
|
||||
successlight: "#98C379",
|
||||
success: "#98C379",
|
||||
successdark: "#98C379",
|
||||
errorlight: "#E06C75",
|
||||
error: "#BE5046",
|
||||
errordark: "#BE5046",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#E5C07B",
|
||||
warning: "#E5C07B",
|
||||
warningdark: "#D19A66",
|
||||
infolight: "#61AFEF",
|
||||
info: "#61AFEF",
|
||||
infodark: "#61AFEF",
|
||||
welllight: "#4B5263",
|
||||
well: "#282C34",
|
||||
white: "#ABB2BF",
|
||||
black: "#282C34",
|
||||
hp: "#E06C75",
|
||||
money: "#E5C07B",
|
||||
hack: "#98C379",
|
||||
combat: "#ABB2BF",
|
||||
cha: "#C678DD",
|
||||
int: "#61AFEF",
|
||||
rep: "#ABB2BF",
|
||||
disabled: "#56B6C2",
|
||||
backgroundprimary: "#282C34",
|
||||
backgroundsecondary: "#21252B",
|
||||
button: "#4B5263",
|
||||
},
|
||||
},
|
||||
|
||||
"Muted Gold & Blue": {
|
||||
credit: "Sloth",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/924672660758208563",
|
||||
colors: {
|
||||
primarylight: "#E3B54A",
|
||||
primary: "#CAA243",
|
||||
primarydark: "#7E6937",
|
||||
successlight: "#82FF82",
|
||||
success: "#6FDA6F",
|
||||
successdark: "#64C364",
|
||||
errorlight: "#FD5555",
|
||||
error: "#D84A4A",
|
||||
errordark: "#AC3939",
|
||||
secondarylight: "#D8D0B8",
|
||||
secondary: "#B1AA95",
|
||||
secondarydark: "#736E5E",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#111111",
|
||||
white: "#fff",
|
||||
black: "#070300",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#0A0A0E",
|
||||
backgroundsecondary: "#0E0E10",
|
||||
button: "#222222",
|
||||
},
|
||||
},
|
||||
|
||||
"Default Lite": {
|
||||
credit: "NmuGmu",
|
||||
description: "Less eye-straining default theme",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/925263801564151888",
|
||||
colors: {
|
||||
primarylight: "#28CF28",
|
||||
primary: "#21A821",
|
||||
primarydark: "#177317",
|
||||
successlight: "#1CFF1C",
|
||||
success: "#16CA16",
|
||||
successdark: "#0D910D",
|
||||
errorlight: "#FF3B3B",
|
||||
error: "#C32D2D",
|
||||
errordark: "#8E2121",
|
||||
secondarylight: "#B3B3B3",
|
||||
secondary: "#838383",
|
||||
secondarydark: "#676767",
|
||||
warninglight: "#FFFF3A",
|
||||
warning: "#C3C32A",
|
||||
warningdark: "#8C8C1E",
|
||||
infolight: "#64CBFF",
|
||||
info: "#3399CC",
|
||||
infodark: "#246D91",
|
||||
welllight: "#404040",
|
||||
well: "#1C1C1C",
|
||||
white: "#C3C3C3",
|
||||
black: "#0A0B0B",
|
||||
hp: "#C62E2E",
|
||||
money: "#D6BB27",
|
||||
hack: "#ADFF2F",
|
||||
combat: "#E8EDCD",
|
||||
cha: "#8B5FAF",
|
||||
int: "#537CC8",
|
||||
rep: "#E8EDCD",
|
||||
disabled: "#5AB5A5",
|
||||
backgroundprimary: "#0C0D0E",
|
||||
backgroundsecondary: "#121415",
|
||||
button: "#252829",
|
||||
},
|
||||
},
|
||||
|
||||
Light: {
|
||||
credit: "matt",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/926114005456658432",
|
||||
colors: {
|
||||
primarylight: "#535353",
|
||||
primary: "#1A1A1A",
|
||||
primarydark: "#0d0d0d",
|
||||
successlight: "#63c439",
|
||||
success: "#428226",
|
||||
successdark: "#2E5A1B",
|
||||
errorlight: "#df7051",
|
||||
error: "#C94824",
|
||||
errordark: "#91341B",
|
||||
secondarylight: "#b3b3b3",
|
||||
secondary: "#9B9B9B",
|
||||
secondarydark: "#7A7979",
|
||||
warninglight: "#e8d464",
|
||||
warning: "#C6AD20",
|
||||
warningdark: "#9F8A16",
|
||||
infolight: "#6299cf",
|
||||
info: "#3778B7",
|
||||
infodark: "#30689C",
|
||||
welllight: "#f9f9f9",
|
||||
well: "#eaeaea",
|
||||
white: "#F7F7F7",
|
||||
black: "#F7F7F7",
|
||||
hp: "#BF5C41",
|
||||
money: "#E1B121",
|
||||
hack: "#47BC38",
|
||||
combat: "#656262",
|
||||
cha: "#A568AC",
|
||||
int: "#889BCF",
|
||||
rep: "#656262",
|
||||
disabled: "#70B4BF",
|
||||
backgroundprimary: "#F7F7F7",
|
||||
backgroundsecondary: "#f9f9f9",
|
||||
button: "#eaeaea",
|
||||
},
|
||||
},
|
||||
});
|
18
src/Themes/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Themes
|
||||
|
||||
Feel free to contribute a new theme by submitting a pull request to the game!
|
||||
|
||||
See [CONTRIBUTING.md](/CONTRIBUTING.md) for details.
|
||||
|
||||
## How create a new theme
|
||||
|
||||
1. Duplicate one of the folders in `/src/Themes/data` and give it a new name (keep the hyphenated format)
|
||||
2. Modify the data in the new `/src/Themes/data/new-folder/index.ts` file
|
||||
3. Replace the screenshot.png with one of your theme
|
||||
4. Add the import/export into the `/src/Themes/data/index.ts` file
|
||||
|
||||
The themes are ordered according to the export order in `index.ts`
|
||||
|
||||
## Other resources
|
||||
|
||||
There is an external script called `theme-browser` which may include more themes than those shown here. Head over the [bitpacker](https://github.com/davidsiems/bitpacker) repository for details.
|
56
src/Themes/Themes.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { IMap } from "../types";
|
||||
import * as predefined from "./data";
|
||||
|
||||
export interface ITheme {
|
||||
[key: string]: string | undefined;
|
||||
primarylight: string;
|
||||
primary: string;
|
||||
primarydark: string;
|
||||
successlight: string;
|
||||
success: string;
|
||||
successdark: string;
|
||||
errorlight: string;
|
||||
error: string;
|
||||
errordark: string;
|
||||
secondarylight: string;
|
||||
secondary: string;
|
||||
secondarydark: string;
|
||||
warninglight: string;
|
||||
warning: string;
|
||||
warningdark: string;
|
||||
infolight: string;
|
||||
info: string;
|
||||
infodark: string;
|
||||
welllight: string;
|
||||
well: string;
|
||||
white: string;
|
||||
black: string;
|
||||
hp: string;
|
||||
money: string;
|
||||
hack: string;
|
||||
combat: string;
|
||||
cha: string;
|
||||
int: string;
|
||||
rep: string;
|
||||
disabled: string;
|
||||
backgroundprimary: string;
|
||||
backgroundsecondary: string;
|
||||
button: string;
|
||||
}
|
||||
|
||||
export interface IPredefinedTheme {
|
||||
colors: ITheme;
|
||||
name: string;
|
||||
credit: string;
|
||||
screenshot: string;
|
||||
description: string;
|
||||
reference?: string;
|
||||
}
|
||||
|
||||
export const defaultTheme: ITheme = {
|
||||
...predefined.Default.colors,
|
||||
};
|
||||
|
||||
export const getPredefinedThemes = (): IMap<IPredefinedTheme> => ({
|
||||
...predefined,
|
||||
});
|
45
src/Themes/data/dark-blue/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Dark Blue",
|
||||
description: "Very dark with a blue/purplelly primary",
|
||||
credit: "Saynt_Garmo",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/923084732718264340",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#023DDE",
|
||||
primary: "#4A41C8",
|
||||
primarydark: "#005299",
|
||||
successlight: "#00FF00",
|
||||
success: "#D1DAD1",
|
||||
successdark: "#BFCABF",
|
||||
errorlight: "#f00",
|
||||
error: "#c00",
|
||||
errordark: "#900",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#040505",
|
||||
white: "#fff",
|
||||
black: "#000000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#091419",
|
||||
backgroundsecondary: "#000000",
|
||||
button: "#000000",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/dark-blue/screenshot.png
Normal file
After Width: | Height: | Size: 116 KiB |
45
src/Themes/data/dark-plus/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Dark+",
|
||||
credit: "LoganMD",
|
||||
description: "VSCode Dark+",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/921999975867617310",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#E0E0BC",
|
||||
primary: "#CCCCAE",
|
||||
primarydark: "#B8B89C",
|
||||
successlight: "#00F000",
|
||||
success: "#00D200",
|
||||
successdark: "#00B400",
|
||||
errorlight: "#F00000",
|
||||
error: "#C80000",
|
||||
errordark: "#A00000",
|
||||
secondarylight: "#B4AEAE",
|
||||
secondary: "#969090",
|
||||
secondarydark: "#787272",
|
||||
warninglight: "#F0F000",
|
||||
warning: "#C8C800",
|
||||
warningdark: "#A0A000",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#1E1E1E",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#1E1E1E",
|
||||
backgroundsecondary: "#252525",
|
||||
button: "#333",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/dark-plus/screenshot.png
Normal file
After Width: | Height: | Size: 117 KiB |
45
src/Themes/data/default-lite/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Default-lite",
|
||||
description: "Less eye-straining default theme",
|
||||
credit: "NmuGmu",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/925263801564151888",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#28CF28",
|
||||
primary: "#21A821",
|
||||
primarydark: "#177317",
|
||||
successlight: "#1CFF1C",
|
||||
success: "#16CA16",
|
||||
successdark: "#0D910D",
|
||||
errorlight: "#FF3B3B",
|
||||
error: "#C32D2D",
|
||||
errordark: "#8E2121",
|
||||
secondarylight: "#B3B3B3",
|
||||
secondary: "#838383",
|
||||
secondarydark: "#676767",
|
||||
warninglight: "#FFFF3A",
|
||||
warning: "#C3C32A",
|
||||
warningdark: "#8C8C1E",
|
||||
infolight: "#64CBFF",
|
||||
info: "#3399CC",
|
||||
infodark: "#246D91",
|
||||
welllight: "#404040",
|
||||
well: "#1C1C1C",
|
||||
white: "#C3C3C3",
|
||||
black: "#0A0B0B",
|
||||
hp: "#C62E2E",
|
||||
money: "#D6BB27",
|
||||
hack: "#ADFF2F",
|
||||
combat: "#E8EDCD",
|
||||
cha: "#8B5FAF",
|
||||
int: "#537CC8",
|
||||
rep: "#E8EDCD",
|
||||
disabled: "#5AB5A5",
|
||||
backgroundprimary: "#0C0D0E",
|
||||
backgroundsecondary: "#121415",
|
||||
button: "#252829",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/default-lite/screenshot.png
Normal file
After Width: | Height: | Size: 111 KiB |
44
src/Themes/data/default/index.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: 'Default',
|
||||
description: 'Default game theme, most supported',
|
||||
credit: 'hydroflame',
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#0f0",
|
||||
primary: "#0c0",
|
||||
primarydark: "#090",
|
||||
successlight: "#0f0",
|
||||
success: "#0c0",
|
||||
successdark: "#090",
|
||||
errorlight: "#f00",
|
||||
error: "#c00",
|
||||
errordark: "#900",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#000",
|
||||
backgroundsecondary: "#000",
|
||||
button: "#333",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/default/screenshot.png
Normal file
After Width: | Height: | Size: 112 KiB |
45
src/Themes/data/discord-like/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Discord-like",
|
||||
description: "Discord inspired theme",
|
||||
credit: "Thermite",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/924305252017143818",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#7389DC",
|
||||
primary: "#7389DC",
|
||||
primarydark: "#5964F1",
|
||||
successlight: "#00CC00",
|
||||
success: "#20DF20",
|
||||
successdark: "#0CB80C",
|
||||
errorlight: "#EA5558",
|
||||
error: "#EC4145",
|
||||
errordark: "#E82528",
|
||||
secondarylight: "#C3C3C3",
|
||||
secondary: "#9C9C9C",
|
||||
secondarydark: "#4E4E4E",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#1C4FB3",
|
||||
welllight: "#999999",
|
||||
well: "#35383C",
|
||||
white: "#FFFFFF",
|
||||
black: "#202225",
|
||||
hp: "#FF5656",
|
||||
money: "#43FF43",
|
||||
hack: "#FFAB3D",
|
||||
combat: "#8A90FD",
|
||||
cha: "#FF51D9",
|
||||
int: "#6495ed",
|
||||
rep: "#FFFF30",
|
||||
disabled: "#474B51",
|
||||
backgroundprimary: "#2F3136",
|
||||
backgroundsecondary: "#35393E",
|
||||
button: "#333",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/discord-like/screenshot.png
Normal file
After Width: | Height: | Size: 120 KiB |
45
src/Themes/data/dracula/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Dracula",
|
||||
description: "Dracula Look-alike",
|
||||
credit: "H3draut3r",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922296307836678144",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#7082B8",
|
||||
primary: "#F8F8F2",
|
||||
primarydark: "#FF79C6",
|
||||
successlight: "#0f0",
|
||||
success: "#0c0",
|
||||
successdark: "#090",
|
||||
errorlight: "#FD4545",
|
||||
error: "#FF2D2D",
|
||||
errordark: "#C62424",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#8BE9FD",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#FFC281",
|
||||
warning: "#FFB86C",
|
||||
warningdark: "#E6A055",
|
||||
infolight: "#A0A0FF",
|
||||
info: "#7070FF",
|
||||
infodark: "#4040FF",
|
||||
welllight: "#44475A",
|
||||
well: "#363948",
|
||||
white: "#fff",
|
||||
black: "#282A36",
|
||||
hp: "#D34448",
|
||||
money: "#50FA7B",
|
||||
hack: "#F1FA8C",
|
||||
combat: "#BD93F9",
|
||||
cha: "#FF79C6",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#282A36",
|
||||
backgroundsecondary: "#21222C",
|
||||
button: "#21222C",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/dracula/screenshot.png
Normal file
After Width: | Height: | Size: 121 KiB |
14
src/Themes/data/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export { Theme as Default } from "./default";
|
||||
export { Theme as DefaultLite } from "./default-lite";
|
||||
export { Theme as Monokai } from "./monokai-ish";
|
||||
export { Theme as Warmer } from "./warmer";
|
||||
export { Theme as DarkPlus } from "./dark-plus";
|
||||
export { Theme as MayukaiDark } from "./mayukai-dark";
|
||||
export { Theme as Purple } from "./purple";
|
||||
export { Theme as SmoothGreen } from "./smooth-green";
|
||||
export { Theme as Dracula } from "./dracula";
|
||||
export { Theme as DarkBlue } from "./dark-blue";
|
||||
export { Theme as DiscordLike } from "./discord-like";
|
||||
export { Theme as OneDark } from "./one-dark";
|
||||
export { Theme as MutedGoldBlue } from "./muted-gold-blue";
|
||||
export { Theme as Light } from "./light";
|
45
src/Themes/data/light/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Light",
|
||||
description: "Cobbled Together Light Theme",
|
||||
credit: "matt",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/926114005456658432",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#535353",
|
||||
primary: "#1A1A1A",
|
||||
primarydark: "#0d0d0d",
|
||||
successlight: "#63c439",
|
||||
success: "#428226",
|
||||
successdark: "#2E5A1B",
|
||||
errorlight: "#df7051",
|
||||
error: "#C94824",
|
||||
errordark: "#91341B",
|
||||
secondarylight: "#b3b3b3",
|
||||
secondary: "#9B9B9B",
|
||||
secondarydark: "#7A7979",
|
||||
warninglight: "#e8d464",
|
||||
warning: "#C6AD20",
|
||||
warningdark: "#9F8A16",
|
||||
infolight: "#6299cf",
|
||||
info: "#3778B7",
|
||||
infodark: "#30689C",
|
||||
welllight: "#f9f9f9",
|
||||
well: "#eaeaea",
|
||||
white: "#F7F7F7",
|
||||
black: "#F7F7F7",
|
||||
hp: "#BF5C41",
|
||||
money: "#E1B121",
|
||||
hack: "#47BC38",
|
||||
combat: "#656262",
|
||||
cha: "#A568AC",
|
||||
int: "#889BCF",
|
||||
rep: "#656262",
|
||||
disabled: "#70B4BF",
|
||||
backgroundprimary: "#F7F7F7",
|
||||
backgroundsecondary: "#f9f9f9",
|
||||
button: "#eaeaea",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/light/screenshot.png
Normal file
After Width: | Height: | Size: 120 KiB |
45
src/Themes/data/mayukai-dark/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Mayukai Dark",
|
||||
description: "Mayukai Dark-esque",
|
||||
credit: "Festive Noire",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922037502334889994",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#DDDFC5",
|
||||
primary: "#CDCFB6",
|
||||
primarydark: "#9D9F8C",
|
||||
successlight: "#00EF00",
|
||||
success: "#00A500",
|
||||
successdark: "#007A00",
|
||||
errorlight: "#F92672",
|
||||
error: "#CA1C5C",
|
||||
errordark: "#90274A",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#D3D300",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#00010A",
|
||||
white: "#fff",
|
||||
black: "#020509",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#8CCF27",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#080C11",
|
||||
backgroundsecondary: "#03080F",
|
||||
button: "#00010A",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/mayukai-dark/screenshot.png
Normal file
After Width: | Height: | Size: 118 KiB |
44
src/Themes/data/monokai-ish/index.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Monokai'ish",
|
||||
description: "Monokai'ish",
|
||||
credit: "eltea",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#FFF",
|
||||
primary: "#F8F8F2",
|
||||
primarydark: "#FAFAEB",
|
||||
successlight: "#ADE146",
|
||||
success: "#A6E22E",
|
||||
successdark: "#98E104",
|
||||
errorlight: "#FF69A0",
|
||||
error: "#F92672",
|
||||
errordark: "#D10F56",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#E1D992",
|
||||
warning: "#E6DB74",
|
||||
warningdark: "#EDDD54",
|
||||
infolight: "#92E1F1",
|
||||
info: "#66D9EF",
|
||||
infodark: "#31CDED",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#F92672",
|
||||
money: "#E6DB74",
|
||||
hack: "#A6E22E",
|
||||
combat: "#75715E",
|
||||
cha: "#AE81FF",
|
||||
int: "#66D9EF",
|
||||
rep: "#E69F66",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#272822",
|
||||
backgroundsecondary: "#1B1C18",
|
||||
button: "#333",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/monokai-ish/screenshot.png
Normal file
After Width: | Height: | Size: 118 KiB |
45
src/Themes/data/muted-gold-blue/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Muted Gold & Blue",
|
||||
description: "Muted gold with blue accents.",
|
||||
credit: "Sloth",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/924672660758208563",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#E3B54A",
|
||||
primary: "#CAA243",
|
||||
primarydark: "#7E6937",
|
||||
successlight: "#82FF82",
|
||||
success: "#6FDA6F",
|
||||
successdark: "#64C364",
|
||||
errorlight: "#FD5555",
|
||||
error: "#D84A4A",
|
||||
errordark: "#AC3939",
|
||||
secondarylight: "#D8D0B8",
|
||||
secondary: "#B1AA95",
|
||||
secondarydark: "#736E5E",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#111111",
|
||||
white: "#fff",
|
||||
black: "#070300",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#0A0A0E",
|
||||
backgroundsecondary: "#0E0E10",
|
||||
button: "#222222",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/muted-gold-blue/screenshot.png
Normal file
After Width: | Height: | Size: 118 KiB |
45
src/Themes/data/one-dark/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "One Dark",
|
||||
description: "Dark with a greenish tint",
|
||||
credit: "Dexalt142",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/924650660694208512",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#98C379",
|
||||
primary: "#98C379",
|
||||
primarydark: "#98C379",
|
||||
successlight: "#98C379",
|
||||
success: "#98C379",
|
||||
successdark: "#98C379",
|
||||
errorlight: "#E06C75",
|
||||
error: "#BE5046",
|
||||
errordark: "#BE5046",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#E5C07B",
|
||||
warning: "#E5C07B",
|
||||
warningdark: "#D19A66",
|
||||
infolight: "#61AFEF",
|
||||
info: "#61AFEF",
|
||||
infodark: "#61AFEF",
|
||||
welllight: "#4B5263",
|
||||
well: "#282C34",
|
||||
white: "#ABB2BF",
|
||||
black: "#282C34",
|
||||
hp: "#E06C75",
|
||||
money: "#E5C07B",
|
||||
hack: "#98C379",
|
||||
combat: "#ABB2BF",
|
||||
cha: "#C678DD",
|
||||
int: "#61AFEF",
|
||||
rep: "#ABB2BF",
|
||||
disabled: "#56B6C2",
|
||||
backgroundprimary: "#282C34",
|
||||
backgroundsecondary: "#21252B",
|
||||
button: "#4B5263",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/one-dark/screenshot.png
Normal file
After Width: | Height: | Size: 120 KiB |
45
src/Themes/data/purple/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Purple",
|
||||
credit: "zer0ney",
|
||||
description: "Essentially all defaults except for purple replacing the main colors",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922091815849570395",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#BA55D3",
|
||||
primary: "#9370DB",
|
||||
primarydark: "#8A2BE2",
|
||||
successlight: "#BA55D3",
|
||||
success: "#9370DB",
|
||||
successdark: "#8A2BE2",
|
||||
errorlight: "#f00",
|
||||
error: "#c00",
|
||||
errordark: "#900",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#ff0",
|
||||
warning: "#cc0",
|
||||
warningdark: "#990",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#000",
|
||||
backgroundsecondary: "#000",
|
||||
button: "#333",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/purple/screenshot.png
Normal file
After Width: | Height: | Size: 121 KiB |
45
src/Themes/data/smooth-green/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Smooth Green",
|
||||
description: "A nice green theme that doesn't hurt your eyes.",
|
||||
credit: "Swidt",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922243957986033725",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#E0E0BC",
|
||||
primary: "#B0D9A3",
|
||||
primarydark: "#B8B89C",
|
||||
successlight: "#00F000",
|
||||
success: "#6BC16B",
|
||||
successdark: "#00B400",
|
||||
errorlight: "#F00000",
|
||||
error: "#3D713D",
|
||||
errordark: "#A00000",
|
||||
secondarylight: "#B4AEAE",
|
||||
secondary: "#8FAF85",
|
||||
secondarydark: "#787272",
|
||||
warninglight: "#F0F000",
|
||||
warning: "#38F100",
|
||||
warningdark: "#A0A000",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#2F3C2B",
|
||||
white: "#fff",
|
||||
black: "#1E1E1E",
|
||||
hp: "#dd3434",
|
||||
money: "#4AA52E",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#a671d1",
|
||||
int: "#6495ed",
|
||||
rep: "#35A135",
|
||||
disabled: "#66cfbc",
|
||||
backgroundprimary: "#1E1E1E",
|
||||
backgroundsecondary: "#252525",
|
||||
button: "#2F3C2B",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/smooth-green/screenshot.png
Normal file
After Width: | Height: | Size: 119 KiB |
45
src/Themes/data/warmer/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IPredefinedTheme } from "../../Themes";
|
||||
import img1 from "./screenshot.png";
|
||||
|
||||
export const Theme: IPredefinedTheme = {
|
||||
name: "Warmer",
|
||||
credit: "hexnaught",
|
||||
description: "Warmer, softer theme",
|
||||
reference: "https://discord.com/channels/415207508303544321/921991895230611466/921999581020028938",
|
||||
screenshot: img1,
|
||||
colors: {
|
||||
primarylight: "#EA9062",
|
||||
primary: "#DD7B4A",
|
||||
primarydark: "#D3591C",
|
||||
successlight: "#6ACF6A",
|
||||
success: "#43BF43",
|
||||
successdark: "#3E913E",
|
||||
errorlight: "#C15757",
|
||||
error: "#B34141",
|
||||
errordark: "#752525",
|
||||
secondarylight: "#AAA",
|
||||
secondary: "#888",
|
||||
secondarydark: "#666",
|
||||
warninglight: "#E6E69D",
|
||||
warning: "#DADA56",
|
||||
warningdark: "#A1A106",
|
||||
infolight: "#69f",
|
||||
info: "#36c",
|
||||
infodark: "#039",
|
||||
welllight: "#444",
|
||||
well: "#222",
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
hp: "#dd3434",
|
||||
money: "#ffd700",
|
||||
hack: "#adff2f",
|
||||
combat: "#faffdf",
|
||||
cha: "#AD84CF",
|
||||
int: "#6495ed",
|
||||
rep: "#faffdf",
|
||||
disabled: "#76C6B7",
|
||||
backgroundprimary: "#000",
|
||||
backgroundsecondary: "#000",
|
||||
button: "#333",
|
||||
},
|
||||
};
|
BIN
src/Themes/data/warmer/screenshot.png
Normal file
After Width: | Height: | Size: 118 KiB |
19
src/Themes/ui/StyleEditorButton.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React, { useState } from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import TextFormatIcon from "@mui/icons-material/TextFormat";
|
||||
import { StyleEditorModal } from "./StyleEditorModal";
|
||||
|
||||
export function StyleEditorButton(): React.ReactElement {
|
||||
const [styleEditorOpen, setStyleEditorOpen] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="The style editor allows you to modify certain CSS rules used by the game.">
|
||||
<Button startIcon={<TextFormatIcon />} onClick={() => setStyleEditorOpen(true)}>
|
||||
Style Editor
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<StyleEditorModal open={styleEditorOpen} onClose={() => setStyleEditorOpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Modal } from "./Modal";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
|
||||
import Button from "@mui/material/Button";
|
||||
import ButtonGroup from "@mui/material/ButtonGroup";
|
||||
@ -11,7 +11,7 @@ import SaveIcon from "@mui/icons-material/Save";
|
||||
|
||||
import { ThemeEvents } from "./Theme";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { defaultStyles } from "../../Settings/Styles";
|
||||
import { defaultStyles } from "../Styles";
|
||||
import { Tooltip } from "@mui/material";
|
||||
import { IStyleSettings } from "../../ScriptEditor/NetscriptDefinitions";
|
||||
|
93
src/Themes/ui/ThemeBrowser.tsx
Normal file
@ -0,0 +1,93 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { ThemeEvents } from "./Theme";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { getPredefinedThemes, IPredefinedTheme } from "../Themes";
|
||||
import { Box, ButtonGroup, Button } from "@mui/material";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { ThemeEditorButton } from "./ThemeEditorButton";
|
||||
import { StyleEditorButton } from "./StyleEditorButton";
|
||||
import { ThemeEntry } from "./ThemeEntry";
|
||||
import { ThemeCollaborate } from "./ThemeCollaborate";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { SnackbarEvents } from "../../ui/React/Snackbar";
|
||||
|
||||
interface IProps {
|
||||
router: IRouter;
|
||||
}
|
||||
|
||||
// Everything dies when the theme gets reloaded, so we'll keep the current scroll to not jump around.
|
||||
let previousScrollY = 0;
|
||||
|
||||
export function ThemeBrowser({ router }: IProps): React.ReactElement {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [modalImageSrc, setModalImageSrc] = useState<string | undefined>();
|
||||
const predefinedThemes = getPredefinedThemes();
|
||||
const themes = (predefinedThemes &&
|
||||
Object.entries(predefinedThemes).map(([key, templateTheme]) => (
|
||||
<ThemeEntry
|
||||
key={key}
|
||||
theme={templateTheme}
|
||||
onActivated={() => setTheme(templateTheme)}
|
||||
onImageClick={handleZoom}
|
||||
/>
|
||||
))) || <></>;
|
||||
|
||||
function setTheme(theme: IPredefinedTheme): void {
|
||||
previousScrollY = window.scrollY;
|
||||
const previousColors = { ...Settings.theme };
|
||||
Object.assign(Settings.theme, theme.colors);
|
||||
ThemeEvents.emit();
|
||||
SnackbarEvents.emit(
|
||||
<>
|
||||
Updated theme to "<strong>{theme.name}</strong>"
|
||||
<Button
|
||||
sx={{ ml: 1 }}
|
||||
color="secondary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
Object.assign(Settings.theme, previousColors);
|
||||
ThemeEvents.emit();
|
||||
}}
|
||||
>
|
||||
UNDO
|
||||
</Button>
|
||||
</>,
|
||||
"info",
|
||||
30000,
|
||||
);
|
||||
}
|
||||
|
||||
function handleZoom(src: string): void {
|
||||
previousScrollY = window.scrollY;
|
||||
setModalImageSrc(src);
|
||||
setModalOpen(true);
|
||||
}
|
||||
|
||||
function handleCloseZoom(): void {
|
||||
previousScrollY = window.scrollY;
|
||||
setModalOpen(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
requestAnimationFrame(() => window.scrollTo(0, previousScrollY));
|
||||
});
|
||||
|
||||
return (
|
||||
<Box sx={{ mx: 2 }}>
|
||||
<Typography variant="h4">Theme Browser</Typography>
|
||||
<Paper sx={{ px: 2, py: 1, my: 1 }}>
|
||||
<ThemeCollaborate />
|
||||
<ButtonGroup sx={{ mb: 2, display: "block" }}>
|
||||
<ThemeEditorButton router={router} />
|
||||
<StyleEditorButton />
|
||||
</ButtonGroup>
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap" }}>{themes}</Box>
|
||||
<Modal open={modalOpen} onClose={handleCloseZoom}>
|
||||
<img src={modalImageSrc} style={{ width: "100%" }} />
|
||||
</Modal>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
24
src/Themes/ui/ThemeCollaborate.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Link } from "@mui/material";
|
||||
|
||||
export function ThemeCollaborate(): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<Typography sx={{ my: 1 }}>
|
||||
If you've created a theme that you believe should be added in game's theme browser, feel free to{" "}
|
||||
<Link href="https://github.com/danielyxie/bitburner/tree/dev/src/Themes/README.md" target="_blank">
|
||||
create a pull request
|
||||
</Link>
|
||||
.
|
||||
</Typography>
|
||||
<Typography sx={{ my: 1 }}>
|
||||
Head over to the{" "}
|
||||
<Link href="https://discord.com/channels/415207508303544321/921991895230611466" target="_blank">
|
||||
theme-sharing
|
||||
</Link>{" "}
|
||||
discord channel for more.
|
||||
</Typography>
|
||||
</>
|
||||
);
|
||||
}
|
24
src/Themes/ui/ThemeEditorButton.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React, { useState } from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { ThemeEditorModal } from "./ThemeEditorModal";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import ColorizeIcon from "@mui/icons-material/Colorize";
|
||||
|
||||
interface IProps {
|
||||
router: IRouter;
|
||||
}
|
||||
|
||||
export function ThemeEditorButton({ router }: IProps): React.ReactElement {
|
||||
const [themeEditorOpen, setThemeEditorOpen] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="The theme editor allows you to modify the colors the game uses.">
|
||||
<Button id="bb-theme-editor-button" startIcon={<ColorizeIcon />} onClick={() => setThemeEditorOpen(true)}>
|
||||
Theme Editor
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<ThemeEditorModal open={themeEditorOpen} onClose={() => setThemeEditorOpen(false)} router={router} />
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { Modal } from "./Modal";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import Button from "@mui/material/Button";
|
||||
import ButtonGroup from "@mui/material/ButtonGroup";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Paper from "@mui/material/Paper";
|
||||
@ -8,15 +9,19 @@ import TextField from "@mui/material/TextField";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import ReplyIcon from "@mui/icons-material/Reply";
|
||||
import PaletteSharpIcon from "@mui/icons-material/PaletteSharp";
|
||||
import HistoryIcon from '@mui/icons-material/History';
|
||||
import { Color, ColorPicker } from "material-ui-color";
|
||||
import { ThemeEvents } from "./Theme";
|
||||
import { Settings, defaultSettings } from "../../Settings/Settings";
|
||||
import { getPredefinedThemes } from "../../Settings/Themes";
|
||||
import { defaultTheme } from "../Themes";
|
||||
import { UserInterfaceTheme } from "../../ScriptEditor/NetscriptDefinitions";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { ThemeCollaborate } from "./ThemeCollaborate";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
router: IRouter;
|
||||
}
|
||||
|
||||
interface IColorEditorProps {
|
||||
@ -68,28 +73,6 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
|
||||
...Settings.theme,
|
||||
});
|
||||
|
||||
const predefinedThemes = getPredefinedThemes();
|
||||
const themes = predefinedThemes && Object.entries(predefinedThemes)
|
||||
.map(([key, templateTheme]) => {
|
||||
const name = templateTheme.name || key;
|
||||
let inner = <Typography>{name}</Typography>;
|
||||
let toolTipTitle;
|
||||
if (templateTheme.credit) {
|
||||
toolTipTitle = <Typography>{templateTheme.description || name} <em>by {templateTheme.credit}</em></Typography>;
|
||||
} else if (templateTheme.description) {
|
||||
toolTipTitle = <Typography>{templateTheme.description}</Typography>;
|
||||
}
|
||||
if (toolTipTitle) {
|
||||
inner = <Tooltip title={toolTipTitle}>{inner}</Tooltip>
|
||||
}
|
||||
return (
|
||||
<Button onClick={() => setTemplateTheme(templateTheme.colors)}
|
||||
startIcon={<PaletteSharpIcon />} key={key} sx={{ mr: 1, mb: 1 }}>
|
||||
{inner}
|
||||
</Button>
|
||||
);
|
||||
}) || <></>;
|
||||
|
||||
function setTheme(theme: UserInterfaceTheme): void {
|
||||
setCustomTheme(theme);
|
||||
Object.assign(Settings.theme, theme);
|
||||
@ -372,8 +355,18 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
|
||||
/>
|
||||
<>
|
||||
<Typography sx={{ my: 1 }}>Backup your theme or share it with others by copying the string above.</Typography>
|
||||
<Typography sx={{ my: 1 }}>Replace the current theme with a pre-built template using the buttons below.</Typography>
|
||||
{themes}
|
||||
<ThemeCollaborate />
|
||||
<ButtonGroup>
|
||||
<Tooltip title="Reverts all modification back to the default theme. This is permanent.">
|
||||
<Button onClick={() => setTemplateTheme(defaultTheme)}
|
||||
startIcon={<HistoryIcon />}>
|
||||
Revert to Default
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Move over to the theme browser's page to use one of our predefined themes.">
|
||||
<Button startIcon={<PaletteSharpIcon />} onClick={() => props.router.toThemeBrowser()}>See more themes</Button>
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
</>
|
||||
</Paper>
|
||||
</Modal>
|
77
src/Themes/ui/ThemeEntry.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import React from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import PaletteSharpIcon from "@mui/icons-material/PaletteSharp";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { IPredefinedTheme } from "../Themes";
|
||||
import { Link, Card, CardHeader, CardContent, CardMedia, Button } from "@mui/material";
|
||||
|
||||
interface IProps {
|
||||
theme: IPredefinedTheme;
|
||||
onActivated: () => void;
|
||||
onImageClick: (src: string) => void;
|
||||
}
|
||||
|
||||
export function ThemeEntry({ theme, onActivated, onImageClick }: IProps): React.ReactElement {
|
||||
if (!theme) return <></>;
|
||||
return (
|
||||
<Card key={theme.screenshot} sx={{ width: 400, mr: 1, mb: 1 }}>
|
||||
<CardHeader
|
||||
action={
|
||||
<Tooltip title="Use this theme">
|
||||
<Button startIcon={<PaletteSharpIcon />} onClick={onActivated} variant="outlined">
|
||||
Use
|
||||
</Button>
|
||||
</Tooltip>
|
||||
}
|
||||
title={theme.name}
|
||||
subheader={
|
||||
<>
|
||||
by {theme.credit}{" "}
|
||||
{theme.reference && (
|
||||
<>
|
||||
(
|
||||
<Link href={theme.reference} target="_blank">
|
||||
ref
|
||||
</Link>
|
||||
)
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
sx={{
|
||||
color: Settings.theme.primary,
|
||||
"& .MuiCardHeader-subheader": {
|
||||
color: Settings.theme.secondarydark,
|
||||
},
|
||||
"& .MuiButton-outlined": {
|
||||
backgroundColor: "transparent",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<CardMedia
|
||||
component="img"
|
||||
width="400"
|
||||
image={theme.screenshot}
|
||||
alt={`Theme Screenshot of "${theme.name}"`}
|
||||
sx={{
|
||||
borderTop: `1px solid ${Settings.theme.welllight}`,
|
||||
borderBottom: `1px solid ${Settings.theme.welllight}`,
|
||||
cursor: "zoom-in",
|
||||
}}
|
||||
onClick={() => onImageClick(theme.screenshot)}
|
||||
/>
|
||||
<CardContent>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
sx={{
|
||||
color: Settings.theme.primarydark,
|
||||
}}
|
||||
>
|
||||
{theme.description}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
@ -30,7 +30,7 @@ import { Player } from "./Player";
|
||||
import { saveObject, loadGame } from "./SaveObject";
|
||||
import { initForeignServers } from "./Server/AllServers";
|
||||
import { Settings } from "./Settings/Settings";
|
||||
import { ThemeEvents } from "./ui/React/Theme";
|
||||
import { ThemeEvents } from "./Themes/ui/Theme";
|
||||
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
|
||||
import { Terminal } from "./Terminal";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import { TTheme as Theme, ThemeEvents, refreshTheme } from "./ui/React/Theme";
|
||||
import { TTheme as Theme, ThemeEvents, refreshTheme } from "./Themes/ui/Theme";
|
||||
import { LoadingScreen } from "./ui/LoadingScreen";
|
||||
import { initElectron } from "./Electron";
|
||||
initElectron();
|
||||
|
@ -79,6 +79,7 @@ import { RecoveryMode, RecoveryRoot } from "./React/RecoveryRoot";
|
||||
import { AchievementsRoot } from "../Achievements/AchievementsRoot";
|
||||
import { ErrorBoundary } from "./ErrorBoundary";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { ThemeBrowser } from "../Themes/ui/ThemeBrowser";
|
||||
|
||||
const htmlLocation = location;
|
||||
|
||||
@ -194,6 +195,9 @@ export let Router: IRouter = {
|
||||
toAchievements: () => {
|
||||
throw new Error("Router called before initialization");
|
||||
},
|
||||
toThemeBrowser: () => {
|
||||
throw new Error("Router called before initialization");
|
||||
},
|
||||
};
|
||||
|
||||
function determineStartPage(player: IPlayer): Page {
|
||||
@ -307,6 +311,9 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
|
||||
toAchievements: () => {
|
||||
setPage(Page.Achievements);
|
||||
},
|
||||
toThemeBrowser: () => {
|
||||
setPage(Page.ThemeBrowser);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -471,6 +478,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
|
||||
mainPage = (
|
||||
<GameOptionsRoot
|
||||
player={player}
|
||||
router={Router}
|
||||
save={() => saveObject.saveGame()}
|
||||
export={() => {
|
||||
// Apply the export bonus before saving the game
|
||||
@ -503,6 +511,10 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
|
||||
mainPage = <AchievementsRoot />;
|
||||
break;
|
||||
}
|
||||
case Page.ThemeBrowser: {
|
||||
mainPage = <ThemeBrowser router={Router} />;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -22,12 +22,11 @@ import TextField from "@mui/material/TextField";
|
||||
import DownloadIcon from "@mui/icons-material/Download";
|
||||
import UploadIcon from "@mui/icons-material/Upload";
|
||||
import SaveIcon from "@mui/icons-material/Save";
|
||||
import PaletteIcon from '@mui/icons-material/Palette';
|
||||
|
||||
import { FileDiagnosticModal } from "../../Diagnostic/FileDiagnosticModal";
|
||||
import { dialogBoxCreate } from "./DialogBox";
|
||||
import { ConfirmationModal } from "./ConfirmationModal";
|
||||
import { ThemeEditorModal } from "./ThemeEditorModal";
|
||||
import { StyleEditorModal } from "./StyleEditorModal";
|
||||
|
||||
import { SnackbarEvents } from "./Snackbar";
|
||||
|
||||
@ -37,6 +36,9 @@ import { formatTime } from "../../utils/helpers/formatTime";
|
||||
import { OptionSwitch } from "./OptionSwitch";
|
||||
import { DeleteGameButton } from "./DeleteGameButton";
|
||||
import { SoftResetButton } from "./SoftResetButton";
|
||||
import { IRouter } from "../Router";
|
||||
import { ThemeEditorButton } from "../../Themes/ui/ThemeEditorButton";
|
||||
import { StyleEditorButton } from "../../Themes/ui/StyleEditorButton";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
@ -50,6 +52,7 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
|
||||
interface IProps {
|
||||
player: IPlayer;
|
||||
router: IRouter;
|
||||
save: () => void;
|
||||
export: () => void;
|
||||
forceKill: () => void;
|
||||
@ -74,8 +77,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
||||
const [timestampFormat, setTimestampFormat] = useState(Settings.TimestampsFormat);
|
||||
const [locale, setLocale] = useState(Settings.Locale);
|
||||
const [diagnosticOpen, setDiagnosticOpen] = useState(false);
|
||||
const [themeEditorOpen, setThemeEditorOpen] = useState(false);
|
||||
const [styleEditorOpen, setStyleEditorOpen] = useState(false);
|
||||
const [importSaveOpen, setImportSaveOpen] = useState(false);
|
||||
const [importData, setImportData] = useState<ImportData | null>(null);
|
||||
|
||||
@ -636,9 +637,14 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
||||
<Button onClick={() => setDiagnosticOpen(true)}>Diagnose files</Button>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
|
||||
<Button onClick={() => setThemeEditorOpen(true)}>Theme editor</Button>
|
||||
<Button onClick={() => setStyleEditorOpen(true)}>Style editor</Button>
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr" }}>
|
||||
<Tooltip title="Head to the theme browser to see a collection of prebuilt themes.">
|
||||
<Button startIcon={<PaletteIcon />} onClick={() => props.router.toThemeBrowser()}>
|
||||
Theme Browser
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<ThemeEditorButton router={props.router} />
|
||||
<StyleEditorButton />
|
||||
</Box>
|
||||
<Box>
|
||||
<Link href="https://github.com/danielyxie/bitburner/issues/new" target="_blank">
|
||||
@ -663,8 +669,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
||||
</Box>
|
||||
</Grid>
|
||||
<FileDiagnosticModal open={diagnosticOpen} onClose={() => setDiagnosticOpen(false)} />
|
||||
<ThemeEditorModal open={themeEditorOpen} onClose={() => setThemeEditorOpen(false)} />
|
||||
<StyleEditorModal open={styleEditorOpen} onClose={() => setStyleEditorOpen(false)} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -14,6 +14,10 @@ const useStyles = makeStyles(() => ({
|
||||
snackbar: {
|
||||
// Log popup z-index increments, so let's add a padding to be well above them.
|
||||
zIndex: `${logBoxBaseZIndex + 1000} !important` as any,
|
||||
|
||||
"& .MuiAlert-icon": {
|
||||
alignSelf: 'center',
|
||||
},
|
||||
}
|
||||
}));
|
||||
|
||||
@ -27,7 +31,7 @@ export function SnackbarProvider(props: IProps): React.ReactElement {
|
||||
);
|
||||
}
|
||||
|
||||
export const SnackbarEvents = new EventEmitter<[string, "success" | "warning" | "error" | "info", number]>();
|
||||
export const SnackbarEvents = new EventEmitter<[string | React.ReactNode, "success" | "warning" | "error" | "info", number]>();
|
||||
|
||||
export function Snackbar(): React.ReactElement {
|
||||
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
|
||||
|
@ -37,6 +37,7 @@ export enum Page {
|
||||
StaneksGift,
|
||||
Recovery,
|
||||
Achievements,
|
||||
ThemeBrowser,
|
||||
}
|
||||
|
||||
export interface ScriptEditorRouteOptions {
|
||||
@ -82,4 +83,5 @@ export interface IRouter {
|
||||
toLocation(location: Location): void;
|
||||
toStaneksGift(): void;
|
||||
toAchievements(): void;
|
||||
toThemeBrowser(): void;
|
||||
}
|
||||
|
1
test/__mocks__/fileMock.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'test-file-stub';
|
0
test/__mocks__/styleMock.js
Normal file
@ -156,6 +156,14 @@ module.exports = (env, argv) => {
|
||||
test: /\.s?css$/,
|
||||
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|jp2|webp)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[contenthash].[ext]',
|
||||
outputPath: 'dist/images',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
|