obsidian#WorkspaceLeaf TypeScript Examples
The following examples show how to use
obsidian#WorkspaceLeaf.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utility.ts From quickadd with MIT License | 7 votes |
export async function openFile(app: App, file: TFile, optional?: {openInNewTab?: boolean, direction?: NewTabDirection, mode?: FileViewMode, focus?: boolean}) {
let leaf: WorkspaceLeaf;
if (optional?.openInNewTab && optional?.direction) {
leaf = app.workspace.splitActiveLeaf(optional.direction);
} else {
leaf = app.workspace.getUnpinnedLeaf();
}
await leaf.openFile(file)
if (optional?.mode || optional?.focus) {
await leaf.setViewState({
...leaf.getViewState(),
state: optional.mode && optional.mode !== 'default' ? {...leaf.view.getState(), mode: optional.mode} : leaf.view.getState(),
popstate: true,
} as ViewState, { focus: optional?.focus });
}
}
Example #2
Source File: utils.ts From obsidian-map-view with GNU General Public License v3.0 | 7 votes |
export async function getEditor(
app: App,
leafToUse?: WorkspaceLeaf
): Promise<Editor> {
let view =
leafToUse && leafToUse.view instanceof MarkdownView
? leafToUse.view
: app.workspace.getActiveViewOfType(MarkdownView);
if (view) return view.editor;
return null;
}
Example #3
Source File: handler.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 6 votes |
/**
* Reveals and optionally bring into focus a WorkspaceLeaf, including leaves
* from the side panels.
* @param {WorkspaceLeaf} leaf
* @param {boolean} pushHistory?
* @param {Record<string} eState?
* @param {} unknown>
* @returns void
*/
activateLeaf(
leaf: WorkspaceLeaf,
pushHistory?: boolean,
eState?: Record<string, unknown>,
): void {
const { workspace } = this.app;
const isInSidePanel = !this.isMainPanelLeaf(leaf);
const state = { focus: true, ...eState };
if (isInSidePanel) {
workspace.revealLeaf(leaf);
}
workspace.setActiveLeaf(leaf, pushHistory);
leaf.view.setEphemeralState(state);
}
Example #4
Source File: active-folder.ts From alx-folder-note with MIT License | 6 votes |
private handleActiveLeafChange(leaf: WorkspaceLeaf | null) {
let folder;
if (
leaf &&
leaf.view instanceof MarkdownView &&
(folder = this.fncApi.getFolderFromNote(leaf.view.file))
) {
this.activeFolder = folder;
} else {
this.activeFolder = null;
}
}
Example #5
Source File: PumlView.ts From obsidian-plantuml with MIT License | 6 votes |
constructor(leaf: WorkspaceLeaf, plugin: PlantumlPlugin) {
super(leaf);
this.plugin = plugin;
this.debounced = debounce(this.plugin.getProcessor().png, this.plugin.settings.debounce * 1000, true);
this.sourceEl = this.contentEl.createDiv({cls: 'plantuml-source-view', attr: {'style': 'display: block'}});
this.previewEl = this.contentEl.createDiv({cls: 'plantuml-preview-view', attr: {'style': 'display: none'}});
const vault = (this.app.vault as any);
if (vault.getConfig("showLineNumber")) {
this.extensions.push(lineNumbers());
}
if(vault.getConfig("lineWrap")) {
this.extensions.push(EditorView.lineWrapping);
}
this.editor = new EditorView({
state: EditorState.create({
extensions: this.extensions,
doc: this.data,
}),
parent: this.sourceEl,
dispatch: syncDispatch(views.length),
});
this.dispatchId = views.push(this.editor) - 1;
}
Example #6
Source File: modeHandler.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 6 votes |
determineRunMode(
query: string,
activeSugg: AnySuggestion,
activeLeaf: WorkspaceLeaf,
): InputInfo {
const input = query ?? '';
const info = new InputInfo(input);
if (input.length === 0) {
this.reset();
}
this.validatePrefixCommands(info, activeSugg, activeLeaf);
this.validateSourcedCommands(info, activeSugg, activeLeaf);
return info;
}
Example #7
Source File: main.tsx From obsidian-annotator with GNU Affero General Public License v3.0 | 6 votes |
public async openAnnotationTarget(annotationTargetFile: TFile, onNewPane: boolean, annotationId: string) {
const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_PDF_ANNOTATOR);
let leaf: WorkspaceLeaf = null;
if (leaves?.length > 0) {
leaf = leaves[0];
}
if (!leaf) {
leaf = this.app.workspace.activeLeaf;
}
if (!leaf) {
leaf = this.app.workspace.getLeaf();
}
if (onNewPane) {
leaf = this.app.workspace.createLeafBySplit(leaf);
}
await leaf.setViewState({
type: VIEW_TYPE_PDF_ANNOTATOR,
state: { file: annotationTargetFile.path }
});
this.scrollToAnnotation(annotationId);
}
Example #8
Source File: fixtureUtils.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 6 votes |
export function makeLeaf(sourceFile?: TFile): MockProxy<WorkspaceLeaf> {
const mockView = mock<MarkdownView>({
file: sourceFile ?? new TFile(),
editor: mock<Editor>(),
});
mockView.getViewType.mockReturnValue('markdown');
return mock<WorkspaceLeaf>({
view: mockView,
});
}
Example #9
Source File: customContextMenu.ts From obsidian-dictionary with GNU Affero General Public License v3.0 | 6 votes |
export default function handleContextMenu(menu: Menu, instance: Editor, plugin: DictionaryPlugin): void {
if (!plugin.settings.shouldShowCustomContextMenu) {
return;
}
const selection = instance.getSelection();
if (selection && selection.trim().split(" ").length === 1) {
if (!plugin.settings.shouldShowSynonymPopover) {
menu.addItem((item) => {
item.setTitle(t('Show Synonyms'))
.setIcon('synonyms')
.onClick(async (_) => {
plugin.handlePointerUp();
});
});
}
menu.addItem((item) => {
item.setTitle(t('Look up'))
.setIcon('quote-glyph')
.onClick(async (_) => {
let leaf: WorkspaceLeaf = plugin.app.workspace.getLeavesOfType(VIEW_TYPE).first();
if(!leaf){
leaf = plugin.app.workspace.getRightLeaf(false);
await leaf.setViewState({
type: VIEW_TYPE,
});
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
leaf.view.query(selection.trim());
plugin.app.workspace.revealLeaf(leaf);
});
});
}
}
Example #10
Source File: handler.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 6 votes |
protected getSourceInfoFromSuggestion(suggestion: AnySuggestion): SourceInfo {
let file: TFile = null;
let leaf: WorkspaceLeaf = null;
// Can't use a symbol, workspace, unresolved (non-existent file) suggestions as
// the target for another symbol command, because they don't point to a file
const isFileBasedSuggestion =
suggestion &&
!isSymbolSuggestion(suggestion) &&
!isUnresolvedSuggestion(suggestion) &&
!isWorkspaceSuggestion(suggestion) &&
!isCommandSuggestion(suggestion);
if (isFileBasedSuggestion) {
file = suggestion.file;
}
if (isEditorSuggestion(suggestion)) {
leaf = suggestion.item;
}
const isValidSource = !!file;
return { isValidSource, leaf, file, suggestion };
}
Example #11
Source File: view.ts From obsidian-fantasy-calendar with MIT License | 6 votes |
constructor(
public plugin: FantasyCalendar,
public leaf: WorkspaceLeaf,
public options: { calendar?: Calendar; full?: boolean } = {}
) {
super(leaf);
this.containerEl.addClass("fantasy-calendar-view");
this.contentEl.addClass("fantasy-calendar-view-content");
this.registerEvent(
this.plugin.app.workspace.on("fantasy-calendars-updated", () => {
this.plugin.onSettingsLoad(() => this.updateCalendars());
})
);
this.registerEvent(
this.plugin.app.workspace.on("layout-change", () => {
if (!this._app) return;
this._app.$set({
fullView: this.full,
...(this.full ? { dayView: false } : {})
});
})
);
/* window.view = this; */
}
Example #12
Source File: main.tsx From obsidian-annotator with GNU Affero General Public License v3.0 | 6 votes |
public async setMarkdownView(leaf: WorkspaceLeaf) {
await leaf.setViewState(
{
type: 'markdown',
state: leaf.view.getState(),
popstate: true
} as ViewState,
{ focus: true }
);
}
Example #13
Source File: main.ts From obsidian-map-view with GNU General Public License v3.0 | 6 votes |
private async openMapWithState(
state: MapState,
ctrlKey: boolean,
forceAutoFit?: boolean
) {
// Find the best candidate for a leaf to open the map view on.
// If there's an open map view, use that, otherwise use the current leaf.
// If Ctrl is pressed, override that behavior and always use the current leaf.
const maps = this.app.workspace.getLeavesOfType(consts.MAP_VIEW_NAME);
let chosenLeaf: WorkspaceLeaf = null;
if (maps && !ctrlKey) chosenLeaf = maps[0];
else chosenLeaf = this.app.workspace.getLeaf();
if (!chosenLeaf) chosenLeaf = this.app.workspace.activeLeaf;
await chosenLeaf.setViewState({
type: consts.MAP_VIEW_NAME,
state: state,
});
if (forceAutoFit) {
if (chosenLeaf.view instanceof MapView)
chosenLeaf.view.autoFitMapToMarkers();
}
}
Example #14
Source File: ViewLoader.ts From obsidian-rss with GNU General Public License v3.0 | 5 votes |
constructor(leaf: WorkspaceLeaf, plugin: RssReaderPlugin) {
super(leaf);
this.plugin = plugin;
}
Example #15
Source File: view.ts From obsidian-checklist-plugin with MIT License | 5 votes |
constructor(leaf: WorkspaceLeaf, private plugin: TodoPlugin) {
super(leaf)
}
Example #16
Source File: main.ts From obsidian-calendar-plugin with MIT License | 5 votes |
async onload(): Promise<void> {
this.register(
settings.subscribe((value) => {
this.options = value;
})
);
this.registerView(
VIEW_TYPE_CALENDAR,
(leaf: WorkspaceLeaf) => (this.view = new CalendarView(leaf))
);
this.addCommand({
id: "show-calendar-view",
name: "Open view",
checkCallback: (checking: boolean) => {
if (checking) {
return (
this.app.workspace.getLeavesOfType(VIEW_TYPE_CALENDAR).length === 0
);
}
this.initLeaf();
},
});
this.addCommand({
id: "open-weekly-note",
name: "Open Weekly Note",
checkCallback: (checking) => {
if (checking) {
return !appHasPeriodicNotesPluginLoaded();
}
this.view.openOrCreateWeeklyNote(window.moment(), false);
},
});
this.addCommand({
id: "reveal-active-note",
name: "Reveal active note",
callback: () => this.view.revealActiveNote(),
});
await this.loadOptions();
this.addSettingTab(new CalendarSettingsTab(this.app, this));
if (this.app.workspace.layoutReady) {
this.initLeaf();
} else {
this.registerEvent(
this.app.workspace.on("layout-ready", this.initLeaf.bind(this))
);
}
}
Example #17
Source File: view.ts From better-word-count with MIT License | 5 votes |
constructor(leaf: WorkspaceLeaf) {
super(leaf);
}
Example #18
Source File: dictionaryView.ts From obsidian-dictionary with GNU Affero General Public License v3.0 | 5 votes |
constructor(leaf: WorkspaceLeaf, plugin: DictionaryPlugin) {
super(leaf);
this.plugin = plugin;
}
Example #19
Source File: sidebar.ts From obsidian-spaced-repetition with MIT License | 5 votes |
constructor(leaf: WorkspaceLeaf, plugin: SRPlugin) {
super(leaf);
this.plugin = plugin;
this.registerEvent(this.app.workspace.on("file-open", () => this.redraw()));
this.registerEvent(this.app.vault.on("rename", () => this.redraw()));
}
Example #20
Source File: main.ts From obsidian-jupyter with MIT License | 5 votes |
constructor(leaf: WorkspaceLeaf, interpreter: string) {
super(leaf);
// Show a placeholder before we've converted the notebook.
this.contentEl.innerHTML = 'Converting notebook...';
this.interpreter = interpreter;
}
Example #21
Source File: view.ts From obsidian-initiative-tracker with GNU General Public License v3.0 | 5 votes |
constructor(public leaf: WorkspaceLeaf, public plugin: InitiativeTracker) {
super(leaf);
if (this.plugin.data.state?.creatures?.length) {
this.newEncounterFromState(this.plugin.data.state);
} else {
this.newEncounter();
}
}
Example #22
Source File: modeHandler.test.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 5 votes |
function makeLeaf(): MockProxy<WorkspaceLeaf> {
const view = mock<View>({ file: new TFile() });
return mock<WorkspaceLeaf>({ view });
}
Example #23
Source File: misc.ts From alx-folder-note with MIT License | 5 votes |
getViewOfType = <V extends View = View>(
type: string,
app: App,
): V | null => {
const vc = app.viewRegistry.getViewCreatorByType(type);
return vc ? (vc(new (WorkspaceLeaf as any)(app)) as V) : null;
}
Example #24
Source File: editorHandler.test.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 5 votes |
function makeLeafWithRoot(text: string, root: WorkspaceItem): MockProxy<WorkspaceLeaf> {
const mockLeaf = makeLeaf();
mockLeaf.getDisplayText.mockImplementation(() => text);
mockLeaf.getRoot.mockImplementation(() => root);
return mockLeaf;
}
Example #25
Source File: mapView.ts From obsidian-map-view with GNU General Public License v3.0 | 5 votes |
/**
* Construct a new map instance
* @param leaf The leaf the map should be put in
* @param settings The plugin settings
* @param plugin The plugin instance
*/
constructor(
leaf: WorkspaceLeaf,
settings: PluginSettings,
plugin: MapViewPlugin
) {
super(leaf);
this.navigation = true;
this.settings = settings;
this.plugin = plugin;
// Create the default state by the configuration
this.defaultState = this.settings.defaultState;
// Listen to file changes so we can update markers accordingly
this.app.vault.on('delete', (file) =>
this.updateMarkersWithRelationToFile(file.path, null, true)
);
this.app.metadataCache.on('changed', (file) =>
this.updateMarkersWithRelationToFile(file.path, file, false)
);
// On rename we don't need to do anything because the markers hold a TFile, and the TFile object doesn't change
// when the file name changes. Only its internal path field changes accordingly.
// this.app.vault.on('rename', (file, oldPath) => this.updateMarkersWithRelationToFile(oldPath, file, true));
this.app.workspace.on('css-change', () => {
console.log('Map view: map refresh due to CSS change');
this.refreshMap();
});
this.app.workspace.on('file-open', async (file: TFile) => {
if (this.getState().followActiveNote && file) {
let viewState = this.leaf?.getViewState();
if (viewState) {
let mapState = viewState.state as MapState;
const newQuery = `path:"${file.path}"`;
// Change the map state only if the file has actually changed. If the user just went back
// and forth and the map is still focused on the same file, don't ruin the user's possible
// zoom and pan
if (mapState.query != newQuery) {
mapState.query = newQuery;
await this.setViewState(mapState, true, true);
}
}
}
});
}
Example #26
Source File: modeHandler.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 5 votes |
private validatePrefixCommands(
inputInfo: InputInfo,
activeSugg: AnySuggestion,
activeLeaf: WorkspaceLeaf,
): void {
const { inputText } = inputInfo;
const {
editorListCommand,
workspaceListCommand,
headingsListCommand,
starredListCommand,
commandListCommand,
} = this.settings;
const escEditorCmd = escapeRegExp(editorListCommand);
const escWorkspaceCmd = escapeRegExp(workspaceListCommand);
const escHeadingsCmd = escapeRegExp(headingsListCommand);
const escStarredCmd = escapeRegExp(starredListCommand);
const escCommandListCmd = escapeRegExp(commandListCommand);
// account for potential overlapping command strings
const prefixCmds = [
`(?<ep>${escEditorCmd})`,
`(?<wp>${escWorkspaceCmd})`,
`(?<hp>${escHeadingsCmd})`,
`(?<sp>${escStarredCmd})`,
`(?<cp>${escCommandListCmd})`,
].sort((a, b) => b.length - a.length);
// regex that matches editor, workspace, headings prefixes, and extract filter text
// ^(?:(?<ep>edt )|(?<wp>+)|(?<hp>#)|(?<sp>*))(?<ft>.*)$
const match = new RegExp(
`^(?:${prefixCmds[0]}|${prefixCmds[1]}|${prefixCmds[2]}|${prefixCmds[3]}|${prefixCmds[4]})(?<ft>.*)$`,
).exec(inputText);
if (match?.groups) {
let mode: Mode = null;
const {
index,
groups: { ep, wp, hp, sp, cp, ft },
} = match;
if (ep) {
mode = Mode.EditorList;
} else if (wp) {
mode = Mode.WorkspaceList;
} else if (hp) {
mode = Mode.HeadingsList;
} else if (sp) {
mode = Mode.StarredList;
} else if (cp) {
mode = Mode.CommandList;
}
if (mode) {
this.getHandler(mode).validateCommand(
inputInfo,
index,
ft,
activeSugg,
activeLeaf,
);
}
}
}
Example #27
Source File: annotatorView.tsx From obsidian-annotator with GNU Affero General Public License v3.0 | 5 votes |
constructor(leaf: WorkspaceLeaf, plugin: AnnotatorPlugin) {
super(leaf);
this.useDarkMode = plugin.settings.deafultDarkMode;
this.plugin = plugin;
this.plugin.views.add(this);
}
Example #28
Source File: main.ts From obsidian-rss with GNU General Public License v3.0 | 4 votes |
async onload(): Promise<void> {
console.log('loading plugin rss reader');
//update settings object whenever store contents change.
this.register(
settingsStore.subscribe((value: RssReaderSettings) => {
this.settings = value;
})
);
await this.loadSettings();
this.addCommand({
id: "rss-open",
name: t("open"),
checkCallback: (checking: boolean) => {
if (checking) {
return (this.app.workspace.getLeavesOfType(VIEW_ID).length === 0);
}
this.initLeaf();
}
});
this.addCommand({
id: 'rss-refresh',
name: t("refresh_feeds"),
callback: async () => {
await this.updateFeeds();
}
});
this.addCommand({
id: 'rss-cleanup',
name: t("cleanup"),
callback: async () => {
new CleanupModal(this).open();
}
});
this.addCommand({
id: 'rss-open-feed',
name: "Open Feed from URL",
callback: async () => {
const input = new TextInputPrompt(this.app, "URL", "URL", "", "", t("open"));
await input.openAndGetValue(async (text) => {
const items = await getFeedItems({name: "", folder: "", url: text.getValue()});
if (!items || items.items.length === 0) {
input.setValidationError(text, t("invalid_feed"));
return;
}
input.close();
new ArticleSuggestModal(this, items.items).open();
});
}
});
this.registerView(VIEW_ID, (leaf: WorkspaceLeaf) => new ViewLoader(leaf, this));
this.addSettingTab(new RSSReaderSettingsTab(this.app, this));
let interval: number;
if (this.settings.updateTime !== 0) {
interval = window.setInterval(async () => {
await this.updateFeeds();
}, this.settings.updateTime * 60 * 1000);
this.registerInterval(interval);
}
if (this.settings.autoSync) {
this.registerInterval(window.setInterval(async () => {
await this.loadSettings();
}, 1000 * 60));
}
//reset update timer on settings change.
settingsStore.subscribe((settings: RssReaderSettings) => {
if (interval !== undefined)
clearInterval(interval);
if (settings.updateTime != 0) {
interval = window.setInterval(async () => {
await this.updateFeeds();
}, settings.updateTime * 60 * 1000);
this.registerInterval(interval);
}
this.settings = settings;
this.saveSettings();
});
this.app.workspace.onLayoutReady(async () => {
await this.migrateData();
await this.initLeaf();
await this.updateFeeds();
feedsStore.subscribe((feeds: RssFeedContent[]) => {
//keep sorted store sorted when the items change.
const sorted = groupBy(feeds, "folder");
sortedFeedsStore.update(() => sorted);
let items: RssFeedItem[] = [];
for (const feed in Object.keys(feeds)) {
//@ts-ignore
const feedItems = feeds[feed].items;
items = items.concat(feedItems);
}
//collect wallabag.xml tags for auto completion
const tags: string[] = [];
for (const item of items) {
if (item !== undefined)
tags.push(...item.tags);
}
//@ts-ignore
const fileTags = this.app.metadataCache.getTags();
for (const tag of Object.keys(fileTags)) {
tags.push(tag.replace('#', ''));
}
tagsStore.update(() => new Set<string>(tags.filter(tag => tag.length > 0)));
//collect wallabag.xml folders for auto-completion
const folders: string[] = [];
for (const item of items) {
if (item !== undefined)
folders.push(item.folder);
}
folderStore.update(() => new Set<string>(folders.filter(folder => folder !== undefined && folder.length > 0)));
this.filterItems(items);
});
});
}
Example #29
Source File: main.ts From obsidian-dictionary with GNU Affero General Public License v3.0 | 4 votes |
async onload(): Promise<void> {
console.log('loading dictionary');
await Promise.all([this.loadSettings(), this.loadCache()]);
addIcons();
this.addSettingTab(new SettingsTab(this.app, this));
this.manager = new APIManager(this);
this.registerView(VIEW_TYPE, (leaf) => {
return new DictionaryView(leaf, this);
});
this.addCommand({
id: 'dictionary-open-view',
name: t('Open Dictionary View'),
callback: async () => {
if (this.app.workspace.getLeavesOfType(VIEW_TYPE).length == 0) {
await this.app.workspace.getRightLeaf(false).setViewState({
type: VIEW_TYPE,
});
}
this.app.workspace.revealLeaf(this.app.workspace.getLeavesOfType(VIEW_TYPE).first());
dispatchEvent(new Event("dictionary-focus-on-search"));
},
});
this.addCommand({
id: 'dictionary-open-language-switcher',
name: t('Open Language Switcher'),
callback: () => {
new LanguageChooser(this.app, this).open();
},
});
this.registerDomEvent(document.body, "pointerup", () => {
if (!this.settings.shouldShowSynonymPopover) {
return;
}
this.handlePointerUp();
});
this.registerDomEvent(window, "keydown", () => {
// Destroy the popover if it's open
if (this.synonymPopover) {
this.synonymPopover.destroy();
this.synonymPopover = null;
}
});
this.registerDomEvent(document.body, "contextmenu", (event) => {
//@ts-ignore
if (this.settings.shouldShowCustomContextMenu && event.path.find((el: HTMLElement) => {
try {
return el.hasClass("markdown-preview-view");
} catch (error) {
return false;
}
})) {
const selection = window.getSelection().toString();
if (selection && this.app.workspace.activeLeaf?.getViewState()?.state.mode === "preview") {
event.preventDefault();
const fileMenu = new Menu(this.app);
fileMenu.addItem((item) => {
item.setTitle(t('Copy'))
.setIcon('copy')
.onClick((_) => {
copy(selection);
});
});
if (selection.trim().split(" ").length === 1) {
fileMenu.addItem((item) => {
item.setTitle(t('Look up'))
.setIcon('quote-glyph')
.onClick(async (_) => {
let leaf: WorkspaceLeaf = this.app.workspace.getLeavesOfType(VIEW_TYPE).first();
if (!leaf) {
leaf = this.app.workspace.getRightLeaf(false);
await leaf.setViewState({
type: VIEW_TYPE,
});
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
leaf.view.query(selection.trim());
this.app.workspace.revealLeaf(leaf);
});
});
}
fileMenu.showAtPosition({ x: event.clientX, y: event.clientY });
}
}
});
this.localDictionary = new LocalDictionaryBuilder(this);
this.registerEvent(this.app.workspace.on('editor-menu', this.handleContextMenuHelper));
this.registerEvent(this.app.workspace.on('file-open', (file) => {
if (file && this.settings.getLangFromFile) {
let lang = this.app.metadataCache.getFileCache(file).frontmatter?.lang ?? null;
if (!lang) {
lang = this.app.metadataCache.getFileCache(file).frontmatter?.language ?? null;
}
if (lang && Object.values(RFC).contains(lang)) {
this.settings.defaultLanguage = Object.keys(RFC)[Object.values(RFC).indexOf(lang)] as keyof APISettings;
} else {
this.settings.defaultLanguage = this.settings.normalLang;
}
this.saveSettings();
}
}));
}