1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { definePluginSettings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { parseUrl } from "@utils/misc";
import { wordsFromPascal, wordsToTitle } from "@utils/text";
import { OptionType } from "@utils/types";
import { shiki } from "./api/shiki";
import { themes } from "./api/themes";
import deviconStyle from "./devicon.css?managed";
import { DeviconSetting, HljsSetting } from "./types";
const themeNames = Object.keys(themes) as (keyof typeof themes)[];
export type ShikiSettings = typeof settings.store;
export const settings = definePluginSettings({
theme: {
type: OptionType.SELECT,
description: "Default themes",
options: themeNames.map(themeName => ({
label: wordsToTitle(wordsFromPascal(themeName)),
value: themes[themeName],
default: themes[themeName] === themes.DarkPlus,
})),
onChange: shiki.setTheme,
},
customTheme: {
type: OptionType.STRING,
description: "A link to a custom vscode theme",
placeholder: themes.MaterialCandy,
onChange: value => {
shiki.setTheme(value || settings.store.theme);
},
},
tryHljs: {
type: OptionType.SELECT,
description: "Use the more lightweight default Discord highlighter and theme.",
options: [
{
label: "Never",
value: HljsSetting.Never,
},
{
label: "Prefer Shiki instead of Highlight.js",
value: HljsSetting.Secondary,
default: true,
},
{
label: "Prefer Highlight.js instead of Shiki",
value: HljsSetting.Primary,
},
{
label: "Always",
value: HljsSetting.Always,
},
],
},
useDevIcon: {
type: OptionType.SELECT,
description: "How to show language icons on codeblocks",
options: [
{
label: "Disabled",
value: DeviconSetting.Disabled,
},
{
label: "Colorless",
value: DeviconSetting.Greyscale,
default: true,
},
{
label: "Colored",
value: DeviconSetting.Color,
},
],
onChange: (newValue: DeviconSetting) => {
if (newValue === DeviconSetting.Disabled) disableStyle(deviconStyle);
else enableStyle(deviconStyle);
},
},
bgOpacity: {
type: OptionType.SLIDER,
description: "Background opacity",
markers: [0, 20, 40, 60, 80, 100],
default: 100,
componentProps: {
stickToMarkers: false,
onValueRender: null, // Defaults to percentage
},
},
}, {
theme: {
disabled() { return !!this.store.customTheme; },
},
customTheme: {
isValid(value) {
if (!value) return true;
const url = parseUrl(value);
if (!url) return "Must be a valid URL";
if (!url.pathname.endsWith(".json")) return "Must be a json file";
return true;
},
}
});
|