generated from obsidianmd/obsidian-sample-plugin
-
-
Notifications
You must be signed in to change notification settings - Fork 143
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from chhoumann/choices
- Loading branch information
Showing
73 changed files
with
3,163 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github: chhoumann | ||
custom: https://www.buymeacoffee.com/chhoumann |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# From https://github.com/st3v3nmw/obsidian-spaced-repetition/blob/master/.github/workflows/release.yml | ||
name: Build obsidian plugin | ||
|
||
on: | ||
push: | ||
# Sequence of patterns matched against refs/tags | ||
tags: | ||
- '*' # Push events to matching any tag format, i.e. 1.0, 20.15.10 | ||
|
||
env: | ||
PLUGIN_NAME: quickadd # plugin id | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Use Node.js | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: '14.x' # You might need to adjust this value to your own version | ||
- name: Build | ||
id: build | ||
run: | | ||
npm install | ||
npm run build --if-present | ||
mkdir ${{ env.PLUGIN_NAME }} | ||
cp main.js manifest.json styles.css ${{ env.PLUGIN_NAME }} | ||
zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} | ||
ls | ||
echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" | ||
- name: Create Release | ||
id: create_release | ||
uses: actions/create-release@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
VERSION: ${{ github.ref }} | ||
with: | ||
tag_name: ${{ github.ref }} | ||
release_name: ${{ github.ref }} | ||
draft: false | ||
prerelease: false | ||
- name: Upload zip file | ||
id: upload-zip | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: ./${{ env.PLUGIN_NAME }}.zip | ||
asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip | ||
asset_content_type: application/zip | ||
- name: Upload main.js | ||
id: upload-main | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: ./main.js | ||
asset_name: main.js | ||
asset_content_type: text/javascript | ||
- name: Upload manifest.json | ||
id: upload-manifest | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: ./manifest.json | ||
asset_name: manifest.json | ||
asset_content_type: application/json | ||
- name: Upload styles.css | ||
id: upload-css | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: ./styles.css | ||
asset_name: styles.css | ||
asset_content_type: text/css |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import type {IMacro} from "./types/macros/IMacro"; | ||
import {App, ButtonComponent, Modal, Setting, TextComponent, ToggleComponent} from "obsidian"; | ||
import {MacroBuilder} from "./gui/MacroBuilder"; | ||
import {QuickAddMacro} from "./types/macros/QuickAddMacro"; | ||
|
||
export class MacrosManager extends Modal { | ||
public waitForClose: Promise<IMacro[]>; | ||
private resolvePromise: (macros: IMacro[]) => void; | ||
private rejectPromise: (reason?: any) => void; | ||
private updateMacroContainer: () => void; | ||
|
||
constructor(public app: App, private macros: IMacro[]) { | ||
super(app) | ||
|
||
this.waitForClose = new Promise<IMacro[]>( | ||
((resolve, reject) => { | ||
this.rejectPromise = reject; | ||
this.resolvePromise = resolve; | ||
}) | ||
); | ||
|
||
this.open(); | ||
this.display(); | ||
} | ||
|
||
private display(): void { | ||
this.contentEl.createEl('h2', {text: 'Macro Manager'}).style.textAlign = "center"; | ||
this.addMacroSettings(); | ||
this.addAddMacroBar(); | ||
} | ||
|
||
private addMacroSettings() { | ||
const macroContainer: HTMLDivElement = this.contentEl.createDiv(); | ||
this.updateMacroContainer = () => { | ||
if (this.macros.length <= 1) | ||
macroContainer.className = "macroContainer macroContainer1"; | ||
if (this.macros.length === 2) | ||
macroContainer.className = "macroContainer macroContainer2"; | ||
if (this.macros.length > 2) | ||
macroContainer.className = "macroContainer macroContainer3"; | ||
} | ||
|
||
this.macros.forEach(macro => this.addMacroSetting(macro, macroContainer)); | ||
|
||
this.updateMacroContainer(); | ||
} | ||
|
||
private addMacroSetting(macro: IMacro, container: HTMLDivElement) { | ||
const configureMacroContainer = container.createDiv(); | ||
|
||
const macroSetting: Setting = new Setting(configureMacroContainer); | ||
macroSetting.setName(macro.name); | ||
macroSetting.infoEl.style.fontWeight = "bold"; | ||
|
||
this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => { | ||
this.addSpanWithText(itemContainerEl, "Run on plugin load"); | ||
|
||
const toggle: ToggleComponent = new ToggleComponent(itemContainerEl); | ||
toggle.setValue(macro.runOnStartup); | ||
|
||
toggle.onChange(value => { | ||
macro.runOnStartup = value; | ||
|
||
this.updateMacro(macro); | ||
}); | ||
}); | ||
|
||
configureMacroContainer.addClass("configureMacroDiv"); | ||
this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => { | ||
const deleteButton: ButtonComponent = new ButtonComponent(itemContainerEl); | ||
deleteButton.setClass('mod-warning'); | ||
deleteButton.buttonEl.style.marginRight = "0"; | ||
|
||
deleteButton.setButtonText("Delete").onClick(evt => { | ||
this.macros = this.macros.filter(m => m.id !== macro.id); | ||
this.reload(); | ||
}); | ||
|
||
const configureButton: ButtonComponent = new ButtonComponent(itemContainerEl); | ||
configureButton.setClass('mod-cta'); | ||
configureButton.buttonEl.style.marginRight = "0"; | ||
|
||
configureButton.setButtonText("Configure").onClick(async evt => { | ||
const newMacro = await new MacroBuilder(this.app, macro).waitForClose; | ||
|
||
if (newMacro) { | ||
this.updateMacro(newMacro); | ||
this.reload(); | ||
} | ||
}); | ||
}); | ||
|
||
} | ||
|
||
private addMacroConfigurationItem(container: HTMLDivElement, callback: (itemContainerEl) => void, classString: string = "configureMacroDivItem") { | ||
const item: HTMLDivElement = container.createDiv(); | ||
item.addClass(classString); | ||
|
||
callback(item); | ||
} | ||
|
||
private addSpanWithText(container: HTMLDivElement, text: string) { | ||
const configureText: HTMLSpanElement = container.createEl('span'); | ||
configureText.setText(text); | ||
} | ||
|
||
private updateMacro(macro: IMacro) { | ||
const index = this.macros.findIndex(v => v.id === macro.id); | ||
this.macros[index] = macro; | ||
|
||
if (this.updateMacroContainer) | ||
this.updateMacroContainer(); | ||
|
||
this.reload(); | ||
} | ||
|
||
private reload(): void { | ||
this.contentEl.empty(); | ||
this.display(); | ||
} | ||
|
||
private addAddMacroBar() { | ||
const addMacroBarContainer: HTMLDivElement = this.contentEl.createDiv(); | ||
addMacroBarContainer.addClass("addMacroBarContainer"); | ||
|
||
const nameInput: TextComponent = new TextComponent(addMacroBarContainer); | ||
nameInput.setPlaceholder("Macro name"); | ||
|
||
const addMacroButton: ButtonComponent = new ButtonComponent(addMacroBarContainer); | ||
addMacroButton.setButtonText("Add macro") | ||
.setClass("mod-cta") | ||
.onClick(() => { | ||
const inputValue = nameInput.getValue(); | ||
|
||
if (inputValue !== "" && !this.macros.find(m => m.name === inputValue)) { | ||
this.macros.push(new QuickAddMacro(inputValue)); | ||
this.reload(); | ||
} | ||
}) | ||
} | ||
|
||
onClose() { | ||
super.onClose(); | ||
this.resolvePromise(this.macros); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export const FORMAT_SYNTAX: string[] = [ | ||
"{{DATE}}", "{{DATE:<DATEFORMAT>}}", "{{VDATE:<VARIABLE NAME>, <DATE FORMAT>}}", | ||
"{{VALUE}}", "{{NAME}}", "{{VALUE:<VARIABLE NAME>}}", "{{LINKCURRENT}}" | ||
]; | ||
|
||
export const FILE_NAME_FORMAT_SYNTAX: string[] = [ | ||
"{{DATE}}", "{{DATE:<DATEFORMAT>}}", "{{VDATE:<VARIABLE NAME>, <DATE FORMAT>}}", | ||
"{{VALUE}}", "{{NAME}}", "{{VALUE:<VARIABLE NAME>}}", | ||
] | ||
|
||
export const FILE_NUMBER_REGEX: RegExp = new RegExp(/([0-9]*)\.md$/); | ||
export const DATE_REGEX: RegExp = new RegExp(/{{DATE(\+[0-9]*)?}}/); | ||
export const DATE_REGEX_FORMATTED: RegExp = new RegExp(/{{DATE:([^}\n\r+]*)(\+[0-9]*)?}}/); | ||
export const NAME_VALUE_REGEX: RegExp = new RegExp(/{{NAME}}|{{VALUE}}/); | ||
export const VARIABLE_REGEX: RegExp = new RegExp(/{{VALUE:([^\n\r}]*)}}/); | ||
export const DATE_VARIABLE_REGEX: RegExp = new RegExp(/{{VDATE:([^\n\r},]*),\s*([^\n\r},]*)}}/); | ||
export const LINK_TO_CURRENT_FILE_REGEX: RegExp = new RegExp(/{{LINKCURRENT}}/); | ||
export const MARKDOWN_FILE_EXTENSION_REGEX: RegExp = new RegExp(/\.md$/); | ||
export const JAVASCRIPT_FILE_EXTENSION_REGEX: RegExp = new RegExp(/\.js$/); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import {QuickAddEngine} from "./QuickAddEngine"; | ||
import type ICaptureChoice from "../types/choices/ICaptureChoice"; | ||
import type {App, TFile} from "obsidian"; | ||
import {log} from "../logger/logManager"; | ||
import GenericInputPrompt from "../gui/GenericInputPrompt/genericInputPrompt"; | ||
import {CaptureChoiceFormatter} from "../formatters/captureChoiceFormatter"; | ||
import {appendToCurrentLine} from "../utility"; | ||
import {MARKDOWN_FILE_EXTENSION_REGEX} from "../constants"; | ||
|
||
export class CaptureChoiceEngine extends QuickAddEngine { | ||
choice: ICaptureChoice; | ||
private formatter: CaptureChoiceFormatter; | ||
|
||
constructor(app: App, choice: ICaptureChoice) { | ||
super(app); | ||
this.choice = choice; | ||
this.formatter = new CaptureChoiceFormatter(app); | ||
} | ||
|
||
async run(): Promise<void> { | ||
const captureTo = this.choice.captureTo; | ||
if (!captureTo) { | ||
log.logError(`Invalid capture to for ${this.choice.name}`); | ||
return; | ||
} | ||
|
||
const filePath = await this.getFilePath(captureTo); | ||
let content: string; | ||
|
||
if (!this.choice.format.enabled) | ||
content = await GenericInputPrompt.Prompt(this.app, this.choice.name); | ||
else | ||
content = this.choice.format.format; | ||
|
||
if (this.choice.task) | ||
content = `- [ ] ${content}`; | ||
|
||
if (await this.fileExists(filePath)) { | ||
const file: TFile = await this.getFileByPath(filePath); | ||
if (!file) return; | ||
|
||
const fileContent: string = await this.app.vault.read(file); | ||
const newFileContent: string = await this.formatter.formatContent(content, this.choice, fileContent, file); | ||
|
||
await this.app.vault.modify(file, newFileContent); | ||
} else { | ||
const createdFile = await this.createFileWithInput(filePath, content); | ||
if (!createdFile) { | ||
log.logError(`could not create '${filePath}.'`); | ||
return; | ||
} | ||
} | ||
|
||
if (this.choice.appendLink) | ||
appendToCurrentLine(`[[${filePath.replace(MARKDOWN_FILE_EXTENSION_REGEX, '')}]]`, this.app); | ||
} | ||
|
||
private async getFilePath(captureTo: string) { | ||
const formattedCaptureTo: string = await this.formatter.formatFileName(captureTo, this.choice.name); | ||
return this.formatFilePath("", formattedCaptureTo); | ||
} | ||
|
||
} |
Oops, something went wrong.