Skip to content

Commit c8eb7d6

Browse files
committed
add git commit button
1 parent 20a5a71 commit c8eb7d6

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed

docs/.obsidian/plugins/docs-viewer/main.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,55 @@
11
const obsidian = require('obsidian');
2+
const { exec } = require('child_process');
3+
const { promisify } = require('util');
4+
5+
const execPromise = promisify(exec);
6+
7+
/**
8+
* Modal for Git commit messages
9+
*/
10+
class GitCommitModal extends obsidian.Modal {
11+
constructor(app, plugin) {
12+
super(app);
13+
this.plugin = plugin;
14+
}
15+
16+
onOpen() {
17+
const { contentEl } = this;
18+
contentEl.createEl('h2', { text: 'Git Commit & Push' });
19+
20+
const commitMsgContainer = contentEl.createDiv();
21+
commitMsgContainer.createEl('label', { text: 'Commit Message:' });
22+
23+
const inputEl = commitMsgContainer.createEl('textarea');
24+
inputEl.style.width = '100%';
25+
inputEl.style.height = '100px';
26+
inputEl.style.marginBottom = '10px';
27+
28+
const buttonContainer = contentEl.createDiv();
29+
buttonContainer.style.display = 'flex';
30+
buttonContainer.style.justifyContent = 'flex-end';
31+
32+
const cancelButton = buttonContainer.createEl('button', { text: 'Cancel' });
33+
cancelButton.addEventListener('click', () => this.close());
34+
35+
const commitButton = buttonContainer.createEl('button', { text: 'Commit & Push' });
36+
commitButton.style.marginLeft = '10px';
37+
commitButton.addEventListener('click', async () => {
38+
const message = inputEl.value.trim();
39+
if (message) {
40+
await this.plugin.commitAndPush(message);
41+
this.close();
42+
} else {
43+
new obsidian.Notice('Please enter a commit message');
44+
}
45+
});
46+
}
47+
48+
onClose() {
49+
const { contentEl } = this;
50+
contentEl.empty();
51+
}
52+
}
253

354
/**
455
* @class DocsViewerPlugin
@@ -13,19 +64,116 @@ class DocsViewerPlugin extends obsidian.Plugin {
1364
async onload() {
1465
console.log('Loading DocsViewer plugin');
1566

67+
// Store Git status and ribbon icon reference
68+
this.hasUncommittedChanges = false;
69+
this.gitRibbonIcon = null;
70+
1671
this.updateAllTitles();
1772

1873
this.app.workspace.onLayoutReady(() => {
1974
this.registerEvents();
2075

2176
setTimeout(() => {
2277
this.updateAllTitles();
78+
this.updateGitStatus();
2379
}, 500);
2480
});
2581

2682
this.registerInterval(
2783
window.setInterval(() => this.updateAllTitles(), 5000)
2884
);
85+
86+
// Add Git commit button to the left ribbon
87+
this.gitRibbonIcon = this.addRibbonIcon('git-pull-request', 'Git Commit & Push', async () => {
88+
try {
89+
const hasChanges = await this.hasGitChanges();
90+
91+
if (hasChanges) {
92+
new GitCommitModal(this.app, this).open();
93+
} else {
94+
new obsidian.Notice('No changes to commit');
95+
}
96+
} catch (error) {
97+
console.error('Git error:', error);
98+
new obsidian.Notice(`Git error: ${error.message}`);
99+
}
100+
});
101+
102+
// Add periodic Git status check
103+
this.registerInterval(
104+
window.setInterval(() => this.updateGitStatus(), 30000) // Check every 30 seconds
105+
);
106+
107+
// Initial Git status check
108+
this.updateGitStatus();
109+
}
110+
111+
/**
112+
* @description Updates the Git status indicator based on uncommitted changes
113+
* @returns {Promise<void>}
114+
*/
115+
async updateGitStatus() {
116+
try {
117+
const hasChanges = await this.hasGitChanges();
118+
119+
if (hasChanges && !this.hasUncommittedChanges) {
120+
// Add notification indicator
121+
this.gitRibbonIcon.addClass('git-notification-indicator');
122+
this.hasUncommittedChanges = true;
123+
} else if (!hasChanges && this.hasUncommittedChanges) {
124+
// Remove notification indicator
125+
this.gitRibbonIcon.removeClass('git-notification-indicator');
126+
this.hasUncommittedChanges = false;
127+
}
128+
} catch (error) {
129+
console.error('Error updating Git status:', error);
130+
}
131+
}
132+
133+
/**
134+
* @description Check if there are uncommitted changes in the repository
135+
* @returns {Promise<boolean>} True if there are changes to commit
136+
*/
137+
async hasGitChanges() {
138+
try {
139+
const vaultPath = this.app.vault.adapter.basePath;
140+
const { stdout } = await execPromise('git status --porcelain', { cwd: vaultPath });
141+
return stdout.trim().length > 0;
142+
} catch (error) {
143+
console.error('Error checking git status:', error);
144+
throw error;
145+
}
146+
}
147+
148+
/**
149+
* @description Commit and push changes to the Git repository
150+
* @param {string} message - The commit message
151+
* @returns {Promise<void>}
152+
*/
153+
async commitAndPush(message) {
154+
try {
155+
const vaultPath = this.app.vault.adapter.basePath;
156+
157+
// Add all changes
158+
await execPromise('git add .', { cwd: vaultPath });
159+
160+
// Commit with the provided message
161+
await execPromise(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd: vaultPath });
162+
163+
// Push to remote
164+
new obsidian.Notice('Committing changes...');
165+
const { stdout } = await execPromise('git push', { cwd: vaultPath });
166+
167+
// Update Git status after commit
168+
this.updateGitStatus();
169+
170+
new obsidian.Notice('Successfully committed and pushed changes');
171+
console.log('Git push result:', stdout);
172+
} catch (error) {
173+
console.error('Error in git operations:', error);
174+
new obsidian.Notice(`Git error: ${error.message}`);
175+
throw error;
176+
}
29177
}
30178

31179
/**
@@ -213,6 +361,11 @@ class DocsViewerPlugin extends obsidian.Plugin {
213361
document.querySelectorAll('.nav-file, .nav-file-title').forEach(el => {
214362
el.style.order = '';
215363
});
364+
365+
// Clean up Git notification indicator if it exists
366+
if (this.gitRibbonIcon) {
367+
this.gitRibbonIcon.removeClass('git-notification-indicator');
368+
}
216369
}
217370
}
218371

docs/.obsidian/plugins/docs-viewer/styles.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,20 @@
6666
margin-left: 4px;
6767
font-size: 0.85em;
6868
}
69+
70+
/* Git notification indicator */
71+
.git-notification-indicator {
72+
position: relative;
73+
}
74+
75+
.git-notification-indicator::after {
76+
content: '';
77+
position: absolute;
78+
top: 3px;
79+
right: 3px;
80+
width: 8px;
81+
height: 8px;
82+
background-color: #f44336;
83+
border-radius: 50%;
84+
border: 1px solid var(--background-primary);
85+
}

0 commit comments

Comments
 (0)