Skip to content

Commit 88ded1f

Browse files
committed
Merge branch 'master' into release
2 parents 5aa9026 + f3586ea commit 88ded1f

File tree

9 files changed

+199
-25
lines changed

9 files changed

+199
-25
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: bug
6+
assignees: ''
7+
8+
---
9+
10+
- [ ] The Plugin is up to date
11+
- [ ] Obsidian is up to date
12+
13+
**Describe the bug**
14+
A clear and concise description of what the bug is.
15+
16+
**To Reproduce**
17+
Steps to reproduce the behavior:
18+
1. Go to '...'
19+
2. Click on '....'
20+
3. Scroll down to '....'
21+
4. See error
22+
23+
**Expected behavior**
24+
A clear and concise description of what you expected to happen.
25+
26+
**Screenshots**
27+
If applicable, add screenshots to help explain your problem.
28+
29+
**Occurs on**
30+
- [ ] Windows
31+
- [ ] macOS
32+
- [ ] Linux
33+
- [ ] Android
34+
- [ ] iOS
35+
36+
**Plugin version**
37+
x.x.x
38+
39+
**Additional context**
40+
Add any other context about the problem here.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: feature request
6+
assignees: ''
7+
8+
---
9+
10+
**Is your feature request related to a problem? Please describe.**
11+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
**Additional context**
17+
Add any other context or screenshots about the feature request here.

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This plugin can create input fields inside your notes and bind them to metadata
55
This plugin is not yet finished.
66

77
Planed features are:
8-
- two-way sync (listening to file changes and updating the input fields)
8+
- ranges for sliders
99
- more input types
1010

1111
### How to use
@@ -36,6 +36,9 @@ The folder structure should look like this:
3636
```
3737

3838
### Problems, unexpected behavior or improvement suggestions?
39+
#### The sync seems laggy
40+
This is intentional. To reduce the load on your hard drive the plugin ony syncs about 5 times a second.
41+
3942
You are more than welcome to open an issue on [GitHub](https://github.com/mProjectsCode/obsidian-meta-bind-plugin/issues).
4043

4144
### Contributions

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "obsidian-meta-bind-plugin",
33
"name": "Meta Bind Plugin",
4-
"version": "0.1.1",
4+
"version": "0.1.2",
55
"minAppVersion": "0.14.0",
66
"description": "This plugin can create input fields inside your notes and bind them to metadata fields.",
77
"author": "Moritz Jung",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "obsidian-meta-bind-plugin",
3-
"version": "0.1.1",
3+
"version": "0.1.2",
44
"description": "This plugin can create input fields inside your notes and bind them to metadata fields.",
55
"main": "main.js",
66
"scripts": {

src/Logger.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import MetaBindPlugin from './main';
2+
3+
export class Logger {
4+
static plugin: MetaBindPlugin;
5+
static prefix: string = 'meta-bind |';
6+
7+
static log(data: any): void {
8+
console.log(this.prefix, data);
9+
}
10+
11+
static logDebug(data: any): void {
12+
if (this.plugin.settings.devMode) {
13+
Logger.log(data);
14+
}
15+
}
16+
17+
static logWarning(data: any): void {
18+
console.warn(this.prefix, data);
19+
}
20+
21+
static logError(data: any): void {
22+
console.error(this.prefix, data);
23+
}
24+
}

src/InputField.ts renamed to src/MarkdownInputField.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import {MarkdownRenderChild, SliderComponent, TextComponent, TFile, ToggleComponent} from 'obsidian';
1+
import {MarkdownRenderChild, SliderComponent, TextComponent, TFile, ToggleComponent, ValueComponent} from 'obsidian';
22
import MetaBindPlugin from './main';
3+
import {Logger} from './Logger';
34

4-
export class InputField extends MarkdownRenderChild {
5+
export class MarkdownInputField extends MarkdownRenderChild {
56
plugin: MetaBindPlugin;
67
metaData: any;
8+
uid: number;
9+
inputElement: ValueComponent<any>;
710
error: string;
811

912
declaration: string;
@@ -12,22 +15,23 @@ export class InputField extends MarkdownRenderChild {
1215
boundMetadataField: string;
1316
file: TFile;
1417

15-
limitInterval: NodeJS.Timer;
18+
limitInterval: number;
1619
intervalCounter: number;
1720
valueQueue: any[];
1821

19-
constructor(containerEl: HTMLElement, fullDeclaration: string, plugin: MetaBindPlugin, filePath: string) {
22+
constructor(containerEl: HTMLElement, fullDeclaration: string, plugin: MetaBindPlugin, filePath: string, uid: number) {
2023
super(containerEl);
2124

2225
//console.log(this, 2)
2326

2427
this.error = '';
2528
this.declaration = fullDeclaration;
29+
this.uid = uid;
2630
this.plugin = plugin;
2731

2832
this.valueQueue = [];
2933
this.intervalCounter = 0;
30-
this.limitInterval = setInterval(this.incrementInterval.bind(this), 10);
34+
this.limitInterval = window.setInterval(this.incrementInterval.bind(this), 10);
3135

3236
const regExp = new RegExp(/\[.*?\]/);
3337
let declaration = regExp.exec(fullDeclaration)[0];
@@ -93,16 +97,25 @@ export class InputField extends MarkdownRenderChild {
9397
}
9498
}
9599

100+
updateValue(value: any) {
101+
if (value != null && this.inputElement.getValue() !== value && this.valueQueue.length === 0) {
102+
Logger.logDebug(`updating input field ${this.uid} to '${value.toString()}'`);
103+
this.inputElement.setValue(value);
104+
}
105+
}
106+
96107
getInitialValue() {
97108
// console.log(this);
98109
if (this.isBound) {
99110
return this.metaData[this.boundMetadataField];
100111
}
101112
}
102113

103-
onload() {
114+
async onload() {
104115
//console.log('load', this);
105116

117+
this.metaData = await this.metaData;
118+
106119
const container = this.containerEl.createDiv();
107120
container.addClass('meta-bind-plugin-input-wrapper');
108121

@@ -113,34 +126,42 @@ export class InputField extends MarkdownRenderChild {
113126
return;
114127
}
115128

129+
this.plugin.registerMarkdownInputField(this);
130+
116131
if (this.inputFieldType === 'toggle') {
117132
const newEl = new ToggleComponent(container);
118133
newEl.setValue(this.getInitialValue());
119134
newEl.onChange(async (value) => {
120135
await this.updateMetaData(value);
121136
});
137+
this.inputElement = newEl;
122138
} else if (this.inputFieldType === 'slider') {
123139
const newEl = new SliderComponent(container);
124140
newEl.setValue(this.getInitialValue());
125141
newEl.onChange(async (value) => {
126142
await this.updateMetaData(value);
127143
});
144+
newEl.setDynamicTooltip();
145+
this.inputElement = newEl;
128146
} else if (this.inputFieldType === 'text') {
129147
const newEl = new TextComponent(container);
130148
newEl.setValue(this.getInitialValue());
131149
newEl.onChange(async (value) => {
132150
await this.updateMetaData(value);
133151
});
152+
this.inputElement = newEl;
134153
}
135154

136155
this.containerEl.empty();
137156
this.containerEl.appendChild(container);
138157
}
139158

140159
onunload() {
160+
this.plugin.unregisterMarkdownInputField(this);
161+
141162
super.onunload();
142163

143164
//console.log('unload', this);
144-
clearInterval(this.limitInterval);
165+
window.clearInterval(this.limitInterval);
145166
}
146167
}

src/main.ts

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
import {Notice, Plugin, stringifyYaml, TFile} from 'obsidian';
1+
import {parseYaml, Plugin, stringifyYaml, TFile} from 'obsidian';
22
import {DEFAULT_SETTINGS, MetaBindPluginSettings, MetaBindSettingTab} from './settings/Settings';
3-
import {InputField} from './InputField';
3+
import {MarkdownInputField} from './MarkdownInputField';
44
import {getFileName, isPath, removeFileEnding} from './Utils';
5+
import {Logger} from './Logger';
56

67
export default class MetaBindPlugin extends Plugin {
78
settings: MetaBindPluginSettings;
89

10+
activeMarkdownInputFields: MarkdownInputField[];
11+
markDownInputFieldIndex: number;
12+
913
async onload() {
1014
await this.loadSettings();
1115

12-
// This creates an icon in the left ribbon.
13-
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
14-
15-
});
16+
Logger.plugin = this;
1617

18+
this.activeMarkdownInputFields = [];
19+
this.markDownInputFieldIndex = 0;
1720

1821
this.registerMarkdownPostProcessor((element, context) => {
1922
const codeBlocks = element.querySelectorAll('code');
@@ -23,24 +26,51 @@ export default class MetaBindPlugin extends Plugin {
2326
const isInputField = text.startsWith('INPUT[') && text.endsWith(']');
2427
// console.log(context.sourcePath);
2528
if (isInputField) {
26-
context.addChild(new InputField(codeBlock, text, this, context.sourcePath));
29+
context.addChild(new MarkdownInputField(codeBlock, text, this, context.sourcePath, this.markDownInputFieldIndex));
30+
this.markDownInputFieldIndex += 1;
2731
}
2832
}
2933
});
3034

31-
this.registerEvent(this.app.vault.on('modify', () => {
32-
// console.log('file modified')
35+
this.registerEvent(this.app.vault.on('modify', async abstractFile => {
36+
if (abstractFile instanceof TFile) {
37+
await this.updateMarkdownInputFieldsOnFileChange(abstractFile as TFile);
38+
}
3339
}));
3440

3541
this.addSettingTab(new MetaBindSettingTab(this.app, this));
3642
}
3743

3844
onunload() {
45+
for (const activeMarkdownInputField of this.activeMarkdownInputFields) {
46+
activeMarkdownInputField.unload();
47+
}
48+
}
49+
50+
registerMarkdownInputField(markdownInputField: MarkdownInputField) {
51+
this.activeMarkdownInputFields.push(markdownInputField);
52+
}
3953

54+
unregisterMarkdownInputField(markdownInputField: MarkdownInputField) {
55+
this.activeMarkdownInputFields = this.activeMarkdownInputFields.filter(x => x.uid !== markdownInputField.uid);
56+
}
57+
58+
async updateMarkdownInputFieldsOnFileChange(file: TFile) {
59+
const metadata = await this.getMetaDataForFile(file);
60+
61+
for (const activeMarkdownInputField of this.activeMarkdownInputFields) {
62+
if (!activeMarkdownInputField.file || !activeMarkdownInputField.isBound) {
63+
continue;
64+
}
65+
66+
if (activeMarkdownInputField.file.path === file.path) {
67+
activeMarkdownInputField.updateValue(metadata[activeMarkdownInputField.boundMetadataField]);
68+
}
69+
}
4070
}
4171

4272
async updateMetaData(key: string, value: any, file: TFile) {
43-
// console.log('update', key, value);
73+
Logger.logDebug(`updating '${key}: ${value}' in '${file.path}'`);
4474

4575
if (!file) {
4676
console.log('no file');
@@ -51,12 +81,14 @@ export default class MetaBindPlugin extends Plugin {
5181
const regExp = new RegExp('^(---)\\n[\\s\\S]*\\n---');
5282
fileContent = fileContent.replace(regExp, '');
5383

54-
let metadata: any = this.getMetaDataForFile(file);
84+
let metadata: any = await this.getMetaDataForFile(file);
85+
// console.log(metadata);
5586
if (!metadata) {
5687
return;
5788
}
5889

5990
metadata[key] = value;
91+
// console.log(metadata);
6092

6193
fileContent = `---\n${stringifyYaml(metadata)}---` + fileContent;
6294
await this.app.vault.modify(file, fileContent);
@@ -82,8 +114,12 @@ export default class MetaBindPlugin extends Plugin {
82114
return files;
83115
}
84116

85-
getMetaDataForFile(file: TFile): any {
117+
async getMetaDataForFile(file: TFile): Promise<any> {
118+
// console.log(`reading metadata for ${file.path}`);
119+
86120
let metadata: any;
121+
122+
/* metadata cache is unreliable and might not be updated yet
87123
try {
88124
metadata = this.app.metadataCache.getFileCache(file).frontmatter;
89125
} catch (e) {
@@ -98,6 +134,26 @@ export default class MetaBindPlugin extends Plugin {
98134
} else {
99135
metadata = {};
100136
}
137+
*/
138+
139+
let fileContent: string = await this.app.vault.read(file);
140+
const regExp = new RegExp('^(---)\\n[\\s\\S]*\\n---');
141+
let frontMatter = regExp.exec(fileContent)[0];
142+
if (frontMatter === null) {
143+
return {};
144+
}
145+
// console.log(frontMatter);
146+
frontMatter = frontMatter.substring(4);
147+
frontMatter = frontMatter.substring(0, frontMatter.length - 3);
148+
// console.log(frontMatter);
149+
150+
metadata = parseYaml(frontMatter);
151+
152+
if (!metadata) {
153+
metadata = {};
154+
}
155+
156+
//console.log(metadata);
101157

102158
return metadata;
103159
}

0 commit comments

Comments
 (0)