mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2025-12-21 21:22:25 +00:00
feat: add comment functionality for snippets with modal interface
This commit is contained in:
@@ -62,7 +62,11 @@
|
|||||||
<div id="vis"></div>
|
<div id="vis"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="comment-modal-background" class="comment-modal-background"></div>
|
||||||
|
<div id="comment-modal" class="comment-modal">
|
||||||
|
<textarea id="comment-textarea" placeholder="Add your comment here..."></textarea>
|
||||||
|
<button class="button" id="comment-modal-save">Save</button>
|
||||||
|
</div>
|
||||||
<script type="module" src="src/main.js"></script>
|
<script type="module" src="src/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export class SnippetManager {
|
|||||||
this.isDraftVersion = false;
|
this.isDraftVersion = false;
|
||||||
this.readOnlyMode = false;
|
this.readOnlyMode = false;
|
||||||
|
|
||||||
this.snippets = this.storageManager.loadSnippets();
|
this.snippets = this.loadSnippets();
|
||||||
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
|
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +172,14 @@ export class SnippetManager {
|
|||||||
this.loadSnippet(newSnippet.id);
|
this.loadSnippet(newSnippet.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadSnippets() {
|
||||||
|
const storedSnippets = this.storageManager.loadSnippets();
|
||||||
|
return storedSnippets.map(snippet => ({
|
||||||
|
...snippet,
|
||||||
|
comment: snippet.comment || ''
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
saveSnippetsAndUpdateUI() {
|
saveSnippetsAndUpdateUI() {
|
||||||
this.storageManager.saveSnippets(this.snippets);
|
this.storageManager.saveSnippets(this.snippets);
|
||||||
this.updateUI();
|
this.updateUI();
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export class UIManager {
|
|||||||
document.getElementById('export-snippets').onclick = () => this.snippetManager.storageManager.exportSnippets();
|
document.getElementById('export-snippets').onclick = () => this.snippetManager.storageManager.exportSnippets();
|
||||||
document.getElementById('import-snippets').onclick = () => document.getElementById('import-file').click();
|
document.getElementById('import-snippets').onclick = () => document.getElementById('import-file').click();
|
||||||
document.getElementById('import-file').onchange = (e) => this.handleImport(e);
|
document.getElementById('import-file').onchange = (e) => this.handleImport(e);
|
||||||
|
document.getElementById('comment-modal-save').onclick = () => this.saveComment();
|
||||||
|
document.getElementById('comment-modal-background').onclick = () => this.closeCommentModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleImport(e) {
|
async handleImport(e) {
|
||||||
@@ -66,6 +68,15 @@ export class UIManager {
|
|||||||
this.snippetManager.duplicateSnippet(snippet.id);
|
this.snippetManager.duplicateSnippet(snippet.id);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const commentButton = this.createButton('💬', 'comment-snippet', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
this.openCommentModal(snippet.id);
|
||||||
|
});
|
||||||
|
if (snippet.comment && snippet.comment.trim() !== '') {
|
||||||
|
commentButton.classList.add('has-comment');
|
||||||
|
}
|
||||||
|
buttonsDiv.appendChild(commentButton);
|
||||||
|
|
||||||
div.appendChild(buttonsDiv);
|
div.appendChild(buttonsDiv);
|
||||||
container.appendChild(div);
|
container.appendChild(div);
|
||||||
});
|
});
|
||||||
@@ -79,6 +90,39 @@ export class UIManager {
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openCommentModal(snippetId) {
|
||||||
|
const snippet = this.snippetManager.snippets.find(s => s.id === snippetId);
|
||||||
|
if (!snippet) return;
|
||||||
|
|
||||||
|
const commentTextarea = document.getElementById('comment-textarea');
|
||||||
|
commentTextarea.value = snippet.comment || '';
|
||||||
|
document.getElementById('comment-modal').style.display = 'block';
|
||||||
|
document.getElementById('comment-modal-background').style.display = 'block';
|
||||||
|
this.currentCommentSnippetId = snippetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveComment() {
|
||||||
|
const commentTextarea = document.getElementById('comment-textarea');
|
||||||
|
const snippet = this.snippetManager.snippets.find(s => s.id === this.currentCommentSnippetId);
|
||||||
|
if (snippet) {
|
||||||
|
snippet.comment = commentTextarea.value;
|
||||||
|
this.snippetManager.saveSnippetsAndUpdateUI();
|
||||||
|
}
|
||||||
|
document.getElementById('comment-modal').style.display = 'none';
|
||||||
|
document.getElementById('comment-modal-background').style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
closeCommentModal() {
|
||||||
|
const commentTextarea = document.getElementById('comment-textarea');
|
||||||
|
const snippet = this.snippetManager.snippets.find(s => s.id === this.currentCommentSnippetId);
|
||||||
|
if (snippet) {
|
||||||
|
snippet.comment = commentTextarea.value;
|
||||||
|
this.snippetManager.saveSnippetsAndUpdateUI();
|
||||||
|
}
|
||||||
|
document.getElementById('comment-modal').style.display = 'none';
|
||||||
|
document.getElementById('comment-modal-background').style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
updateSaveButton(hasUnsavedChanges) {
|
updateSaveButton(hasUnsavedChanges) {
|
||||||
const saveButton = document.getElementById('save-snippet');
|
const saveButton = document.getElementById('save-snippet');
|
||||||
saveButton.disabled = !hasUnsavedChanges;
|
saveButton.disabled = !hasUnsavedChanges;
|
||||||
|
|||||||
@@ -268,3 +268,63 @@
|
|||||||
.snippet-item:hover .duplicate-snippet {
|
.snippet-item:hover .duplicate-snippet {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.comment-modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: white;
|
||||||
|
padding: 1rem;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-modal textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 2rem);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-modal .button {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-modal-background {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-snippet {
|
||||||
|
opacity: 0.4;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
min-width: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-snippet.has-comment {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-snippet:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snippet-item:hover .comment-snippet {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user