obsidian#Modal TypeScript Examples
The following examples show how to use
obsidian#Modal.
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: FileClassAttributeSelectModal.ts From obsidian_supercharged_links with MIT License | 7 votes |
export default class FileClassAttributeSelectModal extends Modal{
plugin: SuperchargedLinks
file: TFile
constructor(plugin: SuperchargedLinks, file: TFile){
super(plugin.app)
this.file = file
this.plugin = plugin
}
onOpen(){
this.titleEl.setText(`Select the field to update`)
createFileClass(this.plugin, this.file.basename).then(fileClass => {
this.titleEl.setText(`Select the field to update in ${fileClass.name}`)
const selectContainer = this.contentEl.createDiv()
const select = new DropdownComponent(selectContainer)
select.addOption("select an attribute", "--select an attribute--")
fileClass.attributes.forEach(attr => {
select.addOption(attr.name, attr.name)
})
select.addOption("++newAttr++", "++Add a new attribute++")
select.onChange((attrName) => {
if(attrName == "++newAttr"){
const modal = new FileClassAttributeModal(this.plugin.app, fileClass)
modal.open()
this.close()
} else {
const modal = new FileClassAttributeModal(this.plugin.app, fileClass, fileClass.attributes.filter(attr => attr.name == attrName)[0])
modal.open()
this.close()
}
})
})
}
}
Example #2
Source File: switcherPlusSettingTab.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 6 votes |
private validateExcludeFolderList(settingName: string, excludes: string[]) {
let isValid = true;
let failedMsg = '';
for (const str of excludes) {
try {
new RegExp(str);
} catch (err) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
failedMsg += `<span class="qsp-warning">${str}</span><br/>${err}<br/><br/>`;
isValid = false;
}
}
if (!isValid) {
const popup = new Modal(this.app);
popup.titleEl.setText(settingName);
popup.contentEl.innerHTML = `Changes not saved. The following regex contain errors:<br/><br/>${failedMsg}`;
popup.open();
}
return isValid;
}
Example #3
Source File: modal.ts From obsidian-calendar-plugin with MIT License | 6 votes |
export class ConfirmationModal extends Modal {
constructor(app: App, config: IConfirmationDialogParams) {
super(app);
const { cta, onAccept, text, title } = config;
this.contentEl.createEl("h2", { text: title });
this.contentEl.createEl("p", { text });
this.contentEl.createDiv("modal-button-container", (buttonsEl) => {
buttonsEl
.createEl("button", { text: "Never mind" })
.addEventListener("click", () => this.close());
buttonsEl
.createEl("button", {
cls: "mod-cta",
text: cta,
})
.addEventListener("click", async (e) => {
await onAccept(e);
this.close();
});
});
}
}
Example #4
Source File: MessageModal.ts From obsidian-rss with GNU General Public License v3.0 | 6 votes |
export class MessageModal extends Modal {
message: string;
constructor(plugin: RssReaderPlugin, message: string) {
super(plugin.app);
this.message = message;
}
onOpen() : void {
this.display();
}
display() : void {
const {contentEl} = this;
contentEl.empty();
contentEl.createEl("h1", {text: this.message});
contentEl.createEl("p", {text: t("do_not_close")});
}
setMessage(message: string) : void {
this.message = message;
this.display();
}
}
Example #5
Source File: valueToggleModal.ts From obsidian_supercharged_links with MIT License | 6 votes |
export default class valueToggleModal extends Modal {
app: App
file: TFile
name: string
value: boolean
constructor(app: App, file: TFile, name: string, value: boolean){
super(app)
this.app = app
this.file = file
this.name = name
this.value = value
}
onOpen(){
const inputDiv = this.contentEl.createDiv({
cls: "frontmatter-toggler"
})
this.buildInputEl(inputDiv)
}
buildInputEl(inputDiv: HTMLDivElement): void{
const inputEl = new ToggleComponent(inputDiv)
inputEl.setValue(this.value)
inputEl.onChange(v => {
replaceValues(this.app, this.file, this.name, v ? "true" : "false")
})
}
}
Example #6
Source File: enterTokenModal.ts From obsidian-todoist-plugin with MIT License | 6 votes |
export default class TodoistApiTokenModal extends Modal {
public token: string;
public waitForClose: Promise<void>;
private resolvePromise: () => void;
private modalContent: EnterTokenModalContent;
constructor(app: App) {
super(app);
this.token = "";
this.waitForClose = new Promise(
(resolve) => (this.resolvePromise = resolve)
);
this.titleEl.innerText = "Setup Todoist API token";
this.modalContent = new EnterTokenModalContent({
target: this.contentEl,
props: {
onSubmit: (value: string) => {
this.token = value;
this.close();
},
},
});
this.open();
}
onClose() {
super.onClose();
this.modalContent.$destroy();
this.resolvePromise();
}
}
Example #7
Source File: NoteFieldsCommandsModal.ts From obsidian_supercharged_links with MIT License | 6 votes |
export default class NoteFieldsCommandsModal extends Modal {
public app: App;
private plugin: SuperchargedLinks;
private file: TFile
private select: SelectModal
optionsList: OptionsList
constructor(app: App, plugin: SuperchargedLinks, file: TFile) {
super(app);
this.app = app;
this.plugin = plugin;
this.file = file
}
onOpen(){
this.titleEl.setText(`Select the field to manage`)
const optionsListContainer = this.contentEl.createDiv()
this.select = new SelectModal(optionsListContainer)
this.select.addOption("---", "Choose Field")
this.optionsList = new OptionsList(this.plugin, this.file, this.select)
this.optionsList.createExtraOptionList()
this.select.onChange((value) => {
this.select.modals[value]()
this.close()
})
this.select.selectEl.focus()
}
}
Example #8
Source File: creationHelperModal.ts From obsidian-charts with GNU Affero General Public License v3.0 | 6 votes |
export class CreationHelperModal extends Modal {
view: MarkdownView;
settings: ChartPluginSettings;
renderer: Renderer;
constructor(app: App, view: MarkdownView, settings: ChartPluginSettings, renderer: Renderer) {
super(app);
this.settings = settings;
this.view = view;
this.renderer = renderer;
}
onOpen() {
let { contentEl, view, settings, renderer} = this;
contentEl.empty();
const modal = new HelperModal({target: contentEl, props: {editor: view.editor, renderer}});
modal.$on('close', () => this.close());
}
onClose() {
let { contentEl } = this;
contentEl.empty();
}
}
Example #9
Source File: localDictionaryBuilder.ts From obsidian-dictionary with GNU Affero General Public License v3.0 | 6 votes |
class OverwriteModal extends Modal {
path: string;
content: string;
openNote: boolean;
constructor(plugin: DictionaryPlugin, path: string, content: string, openNote: boolean) {
super(plugin.app);
this.path = path;
this.content = content;
this.openNote = openNote;
}
onOpen() {
this.contentEl.appendChild(createEl("p", { text: t("A existing File with the same Name was found, do you want to overwrite it?"), cls: "dictionarycenter" }));
const buttonDiv = this.contentEl.appendChild(createDiv({ cls: "dictionarybuttons" }))
buttonDiv.appendChild(createEl("button", { text: t("Yes, overwrite the old File."), cls: "mod-cta" })).onClickEvent(async () => {
this.app.vault.modify(this.app.vault.getAbstractFileByPath(this.path) as TFile, this.content);
let oldPaneOpen = false;
this.app.workspace.iterateAllLeaves((leaf) => {
if (leaf.view instanceof MarkdownView) {
if ((leaf.getViewState().state.file as string).endsWith(this.path)) {
oldPaneOpen = true;
this.app.workspace.setActiveLeaf(leaf);
}
}
});
if (!oldPaneOpen && this.openNote) {
const leaf = this.app.workspace.splitActiveLeaf();
await leaf.openFile(this.app.vault.getAbstractFileByPath(this.path) as TFile);
this.app.workspace.setActiveLeaf(leaf);
}
this.close();
});
buttonDiv.appendChild(createEl("button", { text: t("No, keep the old File."), cls: "mod-cta" })).onClickEvent(() => {
this.close();
});
}
}
Example #10
Source File: main.ts From obsidian-linter with MIT License | 6 votes |
// https://github.com/nothingislost/obsidian-workspaces-plus/blob/bbba928ec64b30b8dec7fe8fc9e5d2d96543f1f3/src/modal.ts#L68
class LintConfirmationModal extends Modal {
constructor(app: App, startModalMessageText: string, submitBtnText: string,
submitBtnNoticeText: string, btnSubmitAction: () => Promise<void>) {
super(app);
this.modalEl.addClass('confirm-modal');
this.contentEl.createEl('h3', {text: 'Warning'});
const e: HTMLParagraphElement = this.contentEl.createEl('p',
{text: startModalMessageText + ' Make sure you have backed up your files.'});
e.id = 'confirm-dialog';
this.contentEl.createDiv('modal-button-container', (buttonsEl) => {
buttonsEl.createEl('button', {text: 'Cancel'}).addEventListener('click', () => this.close());
const btnSumbit = buttonsEl.createEl('button', {
attr: {type: 'submit'},
cls: 'mod-cta',
text: submitBtnText,
});
btnSumbit.addEventListener('click', async (e) => {
new Notice(submitBtnNoticeText);
this.close();
await btnSubmitAction();
});
setTimeout(() => {
btnSumbit.focus();
}, 50);
});
}
}
Example #11
Source File: apiTokenModal.ts From obsidian-hypothesis-plugin with MIT License | 6 votes |
export default class ApiTokenModal extends Modal {
public waitForClose: Promise<void>;
private resolvePromise: () => void;
private modalContent: ApiTokenModalContent;
private tokenManager: TokenManager;
constructor(app: App, tokenManager: TokenManager) {
super(app);
this.tokenManager = tokenManager;
this.waitForClose = new Promise(
(resolve) => (this.resolvePromise = resolve)
);
this.titleEl.innerText = "Enter Hypothesis API token";
this.modalContent = new ApiTokenModalContent({
target: this.contentEl,
props: {
onSubmit: async (value: string) => {
await this.tokenManager.setToken(value);
this.close();
},
},
});
this.open();
}
onClose() {
super.onClose();
this.modalContent.$destroy();
this.resolvePromise();
}
}
Example #12
Source File: confirm.ts From obsidian-admonition with MIT License | 6 votes |
export class ConfirmModal extends Modal {
constructor(
app: App,
public text: string,
public buttons: { cta: string; secondary: string }
) {
super(app);
}
confirmed: boolean = false;
async display() {
this.contentEl.empty();
this.contentEl.addClass("confirm-modal");
this.contentEl.createEl("p", {
text: this.text
});
const buttonEl = this.contentEl.createDiv(
"fantasy-calendar-confirm-buttons"
);
new ButtonComponent(buttonEl)
.setButtonText(this.buttons.cta)
.setCta()
.onClick(() => {
this.confirmed = true;
this.close();
});
new ButtonComponent(buttonEl)
.setButtonText(this.buttons.secondary)
.onClick(() => {
this.close();
});
}
onOpen() {
this.display();
}
}
Example #13
Source File: settings.ts From obsidian-initiative-tracker with GNU General Public License v3.0 | 6 votes |
export class ConfirmModal extends Modal {
constructor(
app: App,
public text: string,
public buttons: { cta: string; secondary: string }
) {
super(app);
}
confirmed: boolean = false;
async display() {
new Promise((resolve) => {
this.contentEl.empty();
this.contentEl.addClass("confirm-modal");
this.contentEl.createEl("p", {
text: this.text
});
const buttonEl = this.contentEl.createDiv(
"fantasy-calendar-confirm-buttons"
);
new ButtonComponent(buttonEl)
.setButtonText(this.buttons.cta)
.setCta()
.onClick(() => {
this.confirmed = true;
this.close();
});
new ButtonComponent(buttonEl)
.setButtonText(this.buttons.secondary)
.onClick(() => {
this.close();
});
});
}
onOpen() {
this.display();
}
}
Example #14
Source File: resyncDelFileModal.ts From obsidian-hypothesis-plugin with MIT License | 5 votes |
export default class ResyncDelFileModal extends Modal {
private syncHypothesis!: SyncHypothesis;
public waitForClose: Promise<void>;
private resolvePromise: () => void;
private modalContent: ResyncDelFileModalContent;
private vault: Vault;
private fileManager: FileManager
constructor(app: App) {
super(app);
this.vault = app.vault;
this.fileManager = new FileManager(this.vault, this.app.metadataCache);
this.waitForClose = new Promise(
(resolve) => (this.resolvePromise = resolve)
);
this.open();
}
async onOpen() {
super.onOpen()
this.syncHypothesis = new SyncHypothesis(this.fileManager);
const deletedFiles = await this.retrieveDeletedFiles();
this.titleEl.innerText = "Hypothes.is: Resync deleted file(s)";
this.modalContent = new ResyncDelFileModalContent({
target: this.contentEl,
props: {
deletedFiles: deletedFiles,
onSubmit: async (value: { selected }) => {
if((!!value.selected) && value.selected.length > 0 ){
this.startResync(value.selected)
} else{
console.log('No files selected')
}
this.close();
},
},
});
}
onClose() {
super.onClose();
this.modalContent.$destroy();
this.resolvePromise();
}
async retrieveDeletedFiles(): Promise<SyncedFile[]> {
const token = get(settingsStore).token;
const userid = get(settingsStore).user;
const apiManager = new ApiManager(token, userid);
// Fetch all annotated articles that *should* be present
const allAnnotations = await apiManager.getHighlights()
const allArticles: [] = Object.values(await parseSyncResponse(allAnnotations));
// Check which files are actually present
const deletedArticles = await Promise.all(allArticles.filter(async article => !(await this.fileManager.isArticleSaved(article))));
return deletedArticles.map((article: Article) =>
({ uri: article.metadata.url, filename: this.fileManager.getNewArticleFilePath(article)})
);
}
async startResync(selectedFiles: SyncedFile[]): Promise<void> {
selectedFiles.forEach(async selected => {
console.log(`Start resync deleted file - ${selected.filename}`)
await this.syncHypothesis.startSync(selected.uri);
})
}
}
Example #15
Source File: chooseSectionModal.ts From obsidian_supercharged_links with MIT License | 5 votes |
export default class chooseSectionModal extends Modal {
plugin: SuperchargedLinks
file: TFile
constructor(plugin: SuperchargedLinks, file:TFile){
super(plugin.app)
this.file = file
this.plugin = plugin
}
onOpen(){
this.titleEl.setText("Add a field in this note after:")
const inputDiv = this.contentEl.createDiv({
cls: "frontmatter-modal-value"
})
const selectEl = new DropdownComponent(inputDiv)
selectEl.selectEl.addClass("frontmatter-select")
selectEl.addOption("","Select line")
selectEl.addOption("top_0","top")
this.app.vault.read(this.file).then(result => {
let foreHeadText = false
let frontmatterStart = false
let frontmatterEnd = false
let inFrontmatter = false
result.split("\n").forEach((line, lineNumber) => {
if(line!="---" && !foreHeadText && !frontmatterStart){
foreHeadText = true
}
if(line == "---" && !foreHeadText){
if(!frontmatterStart){
frontmatterStart = true
inFrontmatter = true
} else if(!frontmatterEnd){
frontmatterEnd = true
inFrontmatter = false
}
}
if(inFrontmatter){
selectEl.addOption(`frontmatter_${lineNumber}`, `${line.substring(0, 30)}${line.length > 30 ? "..." : ""}`)
}else{
selectEl.addOption(`body_${lineNumber}`, `${line.substring(0, 30)}${line.length > 30 ? "..." : ""}`)
}
})
selectEl.onChange(value => {
const valueArray = selectEl.getValue().match(/(\w+)_(\d+)/)
const position = valueArray[1]
const lineNumber = Number(valueArray[2])
const inFrontmatter = position == "frontmatter" ? true : false
const top = position == "top" ? true : false
const modal = new fieldSelectModal(this.plugin, this.file, lineNumber, result.split('\n')[lineNumber], inFrontmatter, top)
this.close()
modal.open()
})
})
}
}
Example #16
Source File: main.ts From luhman-obsidian-plugin with GNU General Public License v3.0 | 5 votes |
class NewZettelModal extends Modal {
public completion: (text: string) => void;
private textBox: HTMLInputElement;
constructor(app: App, completion: (title: string) => void) {
super(app);
this.completion = completion;
let { contentEl } = this;
contentEl.parentElement!.addClass("zettel-modal");
this.titleEl.setText("New zettel title...");
let container = contentEl.createEl("div", {
cls: "zettel-modal-container",
});
this.textBox = contentEl.createEl("input", {
type: "text",
cls: "zettel-modal-textbox",
});
this.textBox.id = "zettel-modal-textbox";
this.textBox.addEventListener("keydown", (event) => {
if (event.key == "Enter") {
event.preventDefault();
this.goTapped();
}
});
container.append(this.textBox);
let button = contentEl.createEl("input", {
type: "button",
value: "GO",
cls: "zettel-modal-button",
});
button.addEventListener("click", (e: Event) => this.goTapped());
container.append(button);
contentEl.append(container);
}
onOpen() {
window.setTimeout(() => {
this.textBox.focus();
}, 0);
}
goTapped() {
let title = this.textBox.value;
this.completion(title);
this.close();
}
}
Example #17
Source File: manageGroupsModal.ts From obsidian-hypothesis-plugin with MIT License | 5 votes |
export default class ManageGroupsModal extends Modal {
public waitForClose: Promise<void>;
private resolvePromise: () => void;
private modalContent: ManageGroupsModalContent;
vault: Vault;
constructor(app: App) {
super(app);
this.waitForClose = new Promise(
(resolve) => (this.resolvePromise = resolve)
);
this.open();
}
async onOpen() {
super.onOpen()
const groups = get(settingsStore).groups;
this.titleEl.innerText = "Hypothes.is: Manage groups to be synced";
this.modalContent = new ManageGroupsModalContent({
target: this.contentEl,
props: {
groups: groups,
onSubmit: async (value: { selectedGroups }) => {
this.setGroupsSettings(value.selectedGroups);
this.close();
},
},
});
}
onClose() {
super.onClose();
this.modalContent.$destroy();
this.resolvePromise();
}
async setGroupsSettings(selectedGroups) {
const groups = get(settingsStore).groups;
groups.forEach(group => {
group.selected = selectedGroups.some((selectedGroup) => selectedGroup.id === group.id);
})
await settingsStore.actions.setGroups(groups);
}
}
Example #18
Source File: valueSelectModal.ts From obsidian_supercharged_links with MIT License | 5 votes |
export default class valueToggleModal extends Modal {
app: App
file: TFile
name: string
value: string
settings: Field
newValue: string
lineNumber: number
inFrontmatter: boolean
top: boolean
constructor(app: App, file: TFile, name: string, value: string, settings: Field, lineNumber: number = -1, inFrontMatter: boolean = false, top: boolean = false){
super(app)
this.app = app
this.file = file
this.name = name
this.value = value
this.settings = settings
this.newValue = null
this.lineNumber = lineNumber
this.inFrontmatter = inFrontMatter
this.top = top
}
onOpen(){
const inputDiv = this.contentEl.createDiv({
cls: "frontmatter-modal-value"
})
this.buildInputEl(inputDiv)
}
buildInputEl(inputDiv: HTMLDivElement): void{
const selectEl = new DropdownComponent(inputDiv)
selectEl.selectEl.addClass("frontmatter-select")
const values = this.settings.values
selectEl.addOption("","--Empty--")
Object.keys(values).forEach(key => {
selectEl.addOption(values[key], values[key])
});
if(Object.values(values).includes(this.value)){
selectEl.setValue(this.value)
}
FieldSetting.getValuesListFromNote(this.settings.valuesListNotePath, this.app).then(listNoteValues => {
listNoteValues.forEach(value => selectEl.addOption(value, value))
if(listNoteValues.includes(this.value)){
selectEl.setValue(this.value)
}
selectEl.onChange(value => this.newValue = value != "--Empty--" ? value : "")
const submitButton = new ButtonComponent(inputDiv)
submitButton.setTooltip("Save")
.setIcon("checkmark")
.onClick(async () => {
if(this.lineNumber == -1){
if(this.newValue || this.newValue == ""){
replaceValues(this.app, this.file, this.name, this.newValue)
}
} else {
this.app.vault.read(this.file).then(result => {
let newContent: string[] = []
if(this.top){
newContent.push(`${this.name}${this.inFrontmatter ? ":" : "::"} ${selectEl.getValue()}`)
result.split("\n").forEach((line, _lineNumber) => newContent.push(line))
} else {
result.split("\n").forEach((line, _lineNumber) => {
newContent.push(line)
if(_lineNumber == this.lineNumber){
newContent.push(`${this.name}${this.inFrontmatter ? ":" : "::"} ${selectEl.getValue()}`)
}
})
}
this.app.vault.modify(this.file, newContent.join('\n'))
this.close()
})
}
this.close()
})
})
}
}
Example #19
Source File: settings.ts From remotely-save with Apache License 2.0 | 5 votes |
export class OnedriveAuthModal extends Modal {
readonly plugin: RemotelySavePlugin;
readonly authDiv: HTMLDivElement;
readonly revokeAuthDiv: HTMLDivElement;
readonly revokeAuthSetting: Setting;
constructor(
app: App,
plugin: RemotelySavePlugin,
authDiv: HTMLDivElement,
revokeAuthDiv: HTMLDivElement,
revokeAuthSetting: Setting
) {
super(app);
this.plugin = plugin;
this.authDiv = authDiv;
this.revokeAuthDiv = revokeAuthDiv;
this.revokeAuthSetting = revokeAuthSetting;
}
async onOpen() {
let { contentEl } = this;
const { authUrl, verifier } = await getAuthUrlAndVerifierOnedrive(
this.plugin.settings.onedrive.clientID,
this.plugin.settings.onedrive.authority
);
this.plugin.oauth2Info.verifier = verifier;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
};
t("modal_onedriveauth_shortdesc")
.split("\n")
.forEach((val) => {
contentEl.createEl("p", {
text: val,
});
});
const div2 = contentEl.createDiv();
div2.createEl(
"button",
{
text: t("modal_onedriveauth_copybutton"),
},
(el) => {
el.onclick = async () => {
await navigator.clipboard.writeText(authUrl);
new Notice(t("modal_onedriveauth_copynotice"));
};
}
);
contentEl.createEl("p").createEl("a", {
href: authUrl,
text: authUrl,
});
}
onClose() {
let { contentEl } = this;
contentEl.empty();
}
}
Example #20
Source File: sectionContentModal.ts From obsidian_supercharged_links with MIT License | 5 votes |
export default class sectionContentModal extends Modal {
file: TFile
startLine: number
endLine: number
constructor(app: App, file: TFile,startLine: number, endLine: number){
super(app)
this.file = file
this.startLine = startLine
this.endLine = endLine
}
onOpen(){
this.titleEl.setText('Select the line before the field to add')
const contentDiv = this.contentEl.createDiv()
const inputDiv = contentDiv.createDiv()
const inputEl = new TextAreaComponent(inputDiv)
inputEl.inputEl.setAttr("cols", "50")
inputEl.inputEl.setAttr("rows", "5")
const footerDiv = contentDiv.createDiv({
cls: "frontmatter-textarea-buttons"
})
const positionSelectorContainer = footerDiv.createDiv({
cls: "position-selector-container"
})
const positionDropdown = new DropdownComponent(positionSelectorContainer)
positionDropdown.addOption("1", "begining")
positionDropdown.addOption("2", "end")
positionDropdown.setValue("2")
const saveButton = new ButtonComponent(footerDiv)
saveButton
.setIcon("checkmark")
.onClick(() => {
this.app.vault.read(this.file).then(result => {
let newContent: string[] = []
result.split("\n").forEach((line, lineNumber) =>{
newContent.push(line)
if(lineNumber == this.startLine && positionDropdown.getValue() == "1"){
newContent.push(inputEl.getValue())
}
if(lineNumber == this.startLine && positionDropdown.getValue() == "1"){
newContent.push(inputEl.getValue())
}
})
})
})
const cancelButton = new ExtraButtonComponent(footerDiv)
cancelButton
.setIcon("cross")
.onClick(() => this.close())
}
}
Example #21
Source File: settings.ts From remotely-save with Apache License 2.0 | 5 votes |
export class OnedriveRevokeAuthModal extends Modal {
readonly plugin: RemotelySavePlugin;
readonly authDiv: HTMLDivElement;
readonly revokeAuthDiv: HTMLDivElement;
constructor(
app: App,
plugin: RemotelySavePlugin,
authDiv: HTMLDivElement,
revokeAuthDiv: HTMLDivElement
) {
super(app);
this.plugin = plugin;
this.authDiv = authDiv;
this.revokeAuthDiv = revokeAuthDiv;
}
async onOpen() {
let { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
};
contentEl.createEl("p", {
text: t("modal_onedriverevokeauth_step1"),
});
const consentUrl = "https://microsoft.com/consent";
contentEl.createEl("p").createEl("a", {
href: consentUrl,
text: consentUrl,
});
contentEl.createEl("p", {
text: t("modal_onedriverevokeauth_step2"),
});
new Setting(contentEl)
.setName(t("modal_onedriverevokeauth_clean"))
.setDesc(t("modal_onedriverevokeauth_clean_desc"))
.addButton(async (button) => {
button.setButtonText(t("modal_onedriverevokeauth_clean_button"));
button.onClick(async () => {
try {
this.plugin.settings.onedrive = JSON.parse(
JSON.stringify(DEFAULT_ONEDRIVE_CONFIG)
);
await this.plugin.saveSettings();
this.authDiv.toggleClass(
"onedrive-auth-button-hide",
this.plugin.settings.onedrive.username !== ""
);
this.revokeAuthDiv.toggleClass(
"onedrive-revoke-auth-button-hide",
this.plugin.settings.onedrive.username === ""
);
new Notice(t("modal_onedriverevokeauth_clean_notice"));
this.close();
} catch (err) {
console.error(err);
new Notice(t("modal_onedriverevokeauth_clean_fail"));
}
});
});
}
onClose() {
let { contentEl } = this;
contentEl.empty();
}
}
Example #22
Source File: PromptModal.ts From Templater with GNU Affero General Public License v3.0 | 5 votes |
export class PromptModal extends Modal {
private promptEl: HTMLInputElement;
private resolve: (value: string) => void;
private reject: (reason?: TemplaterError) => void;
private submitted = false;
constructor(
app: App,
private prompt_text: string,
private default_value: string
) {
super(app);
}
onOpen(): void {
this.titleEl.setText(this.prompt_text);
this.createForm();
}
onClose(): void {
this.contentEl.empty();
if (!this.submitted) {
this.reject(new TemplaterError("Cancelled prompt"));
}
}
createForm(): void {
const div = this.contentEl.createDiv();
div.addClass("templater-prompt-div");
const form = div.createEl("form");
form.addClass("templater-prompt-form");
form.type = "submit";
form.onsubmit = (e: Event) => {
this.submitted = true;
e.preventDefault();
this.resolve(this.promptEl.value);
this.close();
};
this.promptEl = form.createEl("input");
this.promptEl.type = "text";
this.promptEl.placeholder = "Type text here...";
this.promptEl.value = this.default_value ?? "";
this.promptEl.addClass("templater-prompt-input");
this.promptEl.select();
}
async openAndGetValue(
resolve: (value: string) => void,
reject: (reason?: TemplaterError) => void
): Promise<void> {
this.resolve = resolve;
this.reject = reject;
this.open();
}
}
Example #23
Source File: GenericYesNoPrompt.ts From quickadd with MIT License | 5 votes |
export default class GenericYesNoPrompt extends Modal {
private resolvePromise: (input: boolean) => void;
private rejectPromise: (reason?: any) => void;
private input: boolean;
public waitForClose: Promise<boolean>;
private didSubmit: boolean = false;
public static Prompt(app: App, header: string, text?: string): Promise<boolean> {
const newPromptModal = new GenericYesNoPrompt(app, header, text);
return newPromptModal.waitForClose;
}
private constructor(app: App, private header: string, private text?: string) {
super(app);
this.waitForClose = new Promise<boolean>(
(resolve, reject) => {
this.resolvePromise = resolve;
this.rejectPromise = reject;
}
);
this.open();
this.display();
}
private display() {
this.containerEl.addClass('quickAddModal', 'qaYesNoPrompt')
this.contentEl.empty();
this.titleEl.textContent = this.header;
this.contentEl.createEl('p', {text: this.text});
const buttonsDiv = this.contentEl.createDiv({cls: 'yesNoPromptButtonContainer'})
const noButton = new ButtonComponent(buttonsDiv)
.setButtonText('No')
.onClick(() => this.submit(false));
const yesButton = new ButtonComponent(buttonsDiv)
.setButtonText('Yes')
.onClick(() => this.submit(true))
.setWarning();
yesButton.buttonEl.focus();
}
private submit(input: boolean) {
this.input = input;
this.didSubmit = true;
this.close();
}
onClose() {
super.onClose();
if(!this.didSubmit) this.rejectPromise("No answer given.");
else this.resolvePromise(this.input);
}
}
Example #24
Source File: addNewFieldModal.ts From obsidian_supercharged_links with MIT License | 5 votes |
export default class addNewFieldModal extends Modal {
plugin: SuperchargedLinks
lineNumber: number
file: TFile
inFrontmatter: boolean
top: boolean
constructor(plugin: SuperchargedLinks, lineNumber: number, file: TFile, inFrontmatter: boolean, top: boolean){
super(plugin.app)
this.lineNumber = lineNumber
this.inFrontmatter = inFrontmatter
this.file = file
this.top = top
}
onOpen(){
this.titleEl.setText("Insert new field")
const addNewFieldContainer = this.contentEl.createDiv()
const nameInputContainer = addNewFieldContainer.createDiv()
nameInputContainer.setText("Field Name: ")
const nameInputEl = new TextComponent(nameInputContainer)
nameInputEl.setPlaceholder("Field name")
const valueInputContainer = addNewFieldContainer.createDiv()
valueInputContainer.setText("Field value: ")
const valueInputEl = new TextComponent(valueInputContainer)
valueInputEl.setPlaceholder("Field value")
const footerButtons = this.contentEl.createDiv({
cls: 'frontmatter-textarea-buttons'
})
const saveButton = new ButtonComponent(footerButtons)
saveButton.setIcon("checkmark")
saveButton.onClick(() => {
this.app.vault.read(this.file).then(result => {
let newContent: string[] = []
if(this.top){
newContent.push(`${nameInputEl.getValue()}${this.inFrontmatter ? ":" : "::"} ${valueInputEl.getValue()}`)
result.split("\n").forEach((line, _lineNumber) => newContent.push(line))
} else {
result.split("\n").forEach((line, _lineNumber) => {
newContent.push(line)
if(_lineNumber == this.lineNumber){
newContent.push(`${nameInputEl.getValue()}${this.inFrontmatter ? ":" : "::"} ${valueInputEl.getValue()}`)
}
})
}
this.app.vault.modify(this.file, newContent.join('\n'))
this.close()
})
})
const cancelButton = new ExtraButtonComponent(footerButtons)
cancelButton.setIcon("cross")
cancelButton.onClick(() => {
this.close()
})
}
}
Example #25
Source File: genericCheckboxPrompt.ts From quickadd with MIT License | 5 votes |
export default class GenericCheckboxPrompt extends Modal{
private resolvePromise: (value: string[]) => void;
private rejectPromise: (reason?: any) => void;
public promise: Promise<string[]>;
private resolved: boolean;
private _selectedItems: string[];
public static Open(app: App, items: string[], selectedItems?: string[]) {
const newSuggester = new GenericCheckboxPrompt(app, items, selectedItems);
return newSuggester.promise;
}
public constructor(app: App, private items: string[], readonly selectedItems: string[] = []) {
super(app);
// This clones the item so that we don't get any unexpected modifications of the
// arguments
this._selectedItems = [...selectedItems];
this.promise = new Promise<string[]>(
(resolve, reject) => {(this.resolvePromise = resolve); (this.rejectPromise = reject)}
);
this.display();
this.open();
}
private display() {
this.contentEl.empty();
this.containerEl.addClass('quickAddModal', 'checkboxPrompt')
this.addCheckboxRows();
this.addSubmitButton();
}
onClose() {
super.onClose();
if (!this.resolved)
this.rejectPromise("no input given.");
}
private addCheckboxRows() {
const rowContainer: HTMLDivElement = this.contentEl.createDiv('checkboxRowContainer');
this.items.forEach(item => this.addCheckboxRow(item, rowContainer));
}
private addCheckboxRow(item: string, container: HTMLDivElement) {
const checkboxRow: HTMLDivElement = container.createDiv('checkboxRow');
const text: HTMLSpanElement = checkboxRow.createEl('span', {text: item});
const checkbox: ToggleComponent = new ToggleComponent(checkboxRow);
checkbox
.setTooltip(`Toggle ${item}`)
.setValue(this._selectedItems.contains(item))
.onChange(value => {
if (value)
this._selectedItems.push(item);
else {
const index = this._selectedItems.findIndex(value => item === value);
this._selectedItems.splice(index, 1);
}
});
}
private addSubmitButton() {
const submitButtonContainer: HTMLDivElement = this.contentEl.createDiv('submitButtonContainer');
const submitButton: ButtonComponent = new ButtonComponent(submitButtonContainer);
submitButton.setButtonText("Submit").setCta().onClick(evt => {
this.resolved = true;
this.resolvePromise(this._selectedItems);
this.close();
});
}
}
Example #26
Source File: newPresetDialog.ts From obsidian-map-view with GNU General Public License v3.0 | 5 votes |
export class NewPresetDialog extends Modal {
private plugin: MapViewPlugin;
private settings: PluginSettings;
private stateToSave: MapState;
private callback: (index: string) => void;
constructor(
app: App,
stateToSave: MapState,
plugin: MapViewPlugin,
settings: PluginSettings,
callback: (index: string) => void
) {
super(app);
this.plugin = plugin;
this.settings = settings;
this.stateToSave = stateToSave;
this.callback = callback;
}
onOpen() {
let statusLabel: HTMLDivElement = null;
const grid = this.contentEl.createDiv({ cls: 'newPresetDialogGrid' });
const row1 = grid.createDiv({ cls: 'newPresetDialogLine' });
const row2 = grid.createDiv({ cls: 'newPresetDialogLine' });
const row3 = grid.createDiv({ cls: 'newPresetDialogLine' });
let name = new TextComponent(row1).onChange((value) => {
if (value == 'Default' || value.length === 0)
saveButton.disabled = true;
else saveButton.disabled = false;
if (this.findPresetByName(value))
statusLabel.setText(
"Clicking 'Save' will overwrite an existing preset."
);
else statusLabel.setText('');
});
name.inputEl.style.width = '100%';
name.inputEl.addEventListener('keypress', (ev: KeyboardEvent) => {
if (ev.key == 'Enter') saveButton.buttonEl.click();
});
const includeMapSource = row2.createEl('input', { type: 'checkbox' });
includeMapSource.id = 'includeMapSource';
const includeMapSourceLabel = row2.createEl('label');
includeMapSourceLabel.setAttribute('for', 'includeMapSource');
includeMapSourceLabel.textContent = 'Include chosen map source';
let saveButton = new ButtonComponent(row3)
.setButtonText('Save')
.onClick(async () => {
let existingPreset = this.findPresetByName(name.getValue());
let newState = { ...this.stateToSave, name: name.getValue() };
if (!(includeMapSource as HTMLInputElement).checked)
newState.chosenMapSource = undefined;
if (existingPreset) {
Object.assign(existingPreset, newState);
newState = existingPreset;
} else {
this.settings.savedStates.push(newState);
}
await this.plugin.saveSettings();
// Update the presets list
const presetIndex = this.settings.savedStates.indexOf(newState);
// Select the new preset in the view's controls
this.callback((presetIndex + 1).toString());
this.close();
});
new ButtonComponent(row3).setButtonText('Cancel').onClick(() => {
this.close();
});
statusLabel = row3.createDiv();
name.onChanged();
name.inputEl.focus();
}
findPresetByName(name: string) {
return this.settings.savedStates?.find(
(preset) => preset.name === name
);
}
}
Example #27
Source File: modal.ts From obsidian-fantasy-calendar with MIT License | 5 votes |
export abstract class FantasyCalendarModal extends Modal {
constructor(public app: App) {
super(app);
this.containerEl.addClass("fantasy-calendar-modal")
}
}
Example #28
Source File: ImgurAuthModal.ts From obsidian-imgur-plugin with MIT License | 5 votes |
export default class ImgurAuthModal extends Modal {
secondsLeft = OPEN_BROWSER_IN_SECONDS;
private opened = false;
get isOpen(): boolean {
return this.opened;
}
private timerDiv: HTMLDivElement;
private readonly authLink: string;
private intervalId: NodeJS.Timeout | null = null;
constructor(
clientId: string,
app: App,
private readonly afterClose?: () => Promise<void>
) {
super(app);
this.authLink = `https://api.imgur.com/oauth2/authorize?client_id=${clientId}&response_type=token`;
}
onOpen(): void {
this.opened = true;
this.timerDiv = this.modalEl.createDiv();
this.updateText();
this.intervalId = setInterval(() => {
this.secondsLeft -= 1;
this.updateText();
if (this.secondsLeft === 0) {
window.open(this.authLink);
clearInterval(this.intervalId);
}
}, ONE_SECOND_MILLIS);
this.addNoWaitDiv(this.intervalId);
new ButtonComponent(this.modalEl.createDiv())
.setButtonText("Cancel")
.setCta()
.onClick(() => this.close());
}
async onClose(): Promise<void> {
clearInterval(this.intervalId);
this.opened = false;
// console.log(this.afterClose);
if (this.afterClose) await this.afterClose();
}
private addNoWaitDiv(interval: NodeJS.Timeout) {
const linkEl = createEl("a", { href: this.authLink, text: "here" });
const noWaitDiv = this.modalEl.createDiv();
noWaitDiv.appendText("If you do not want to wait, click ");
noWaitDiv.append(linkEl);
linkEl.onclick = () => {
clearInterval(interval);
this.secondsLeft = 0;
this.updateText();
};
return noWaitDiv;
}
private updateText() {
this.timerDiv.setText(
`Please complete authentication at imgur.com; Opening browser in ${this.secondsLeft} seconds...`
);
}
}
Example #29
Source File: choiceBuilder.ts From quickadd with MIT License | 5 votes |
export abstract class ChoiceBuilder extends Modal {
private resolvePromise: (input: IChoice) => void;
private rejectPromise: (reason?: any) => void;
private input: IChoice;
public waitForClose: Promise<IChoice>;
abstract choice: IChoice;
private didSubmit: boolean = false;
protected svelteElements: SvelteComponent[] = [];
protected constructor(app: App) {
super(app);
this.waitForClose = new Promise<IChoice>(
(resolve, reject) => {
this.resolvePromise = resolve;
this.rejectPromise = reject;
}
);
this.containerEl.addClass('quickAddModal');
this.open();
}
protected abstract display();
protected reload() {
this.contentEl.empty();
this.display();
}
protected addFileSearchInputToSetting(setting: Setting, value: string, onChangeCallback: (value: string) => void): SearchComponent {
let component: SearchComponent;
setting.addSearch(searchComponent => {
component = searchComponent;
searchComponent.setValue(value);
searchComponent.setPlaceholder("File path");
const markdownFiles: string[] = this.app.vault.getMarkdownFiles().map(f => f.path);
new GenericTextSuggester(this.app, searchComponent.inputEl, markdownFiles);
searchComponent.onChange(onChangeCallback);
});
return component;
}
protected addCenteredChoiceNameHeader(choice: IChoice): void {
const headerEl: HTMLHeadingElement = this.contentEl.createEl('h2', {cls: "choiceNameHeader"});
headerEl.setText(choice.name);
headerEl.addEventListener('click', async ev => {
try {
const newName: string = await GenericInputPrompt.Prompt(this.app, choice.name, "Choice name", choice.name);
if (newName !== choice.name) {
choice.name = newName;
headerEl.setText(newName);
}
}
catch (e) {
log.logMessage(`No new name given for ${choice.name}`);
}
});
}
onClose() {
super.onClose();
this.resolvePromise(this.choice);
this.svelteElements.forEach(el => {
if (el && el.$destroy) el.$destroy();
})
if(!this.didSubmit) this.rejectPromise("No answer given.");
else this.resolvePromise(this.input);
}
}