@filipc77/cowrite 0.4.13 → 0.4.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/ui/client.js +47 -9
- package/ui/index.html +4 -1
- package/ui/styles.css +28 -0
package/package.json
CHANGED
package/ui/client.js
CHANGED
|
@@ -12,6 +12,7 @@ const statusEl = $("#status");
|
|
|
12
12
|
const popup = $("#commentPopup");
|
|
13
13
|
const popupSelection = $("#popupSelection");
|
|
14
14
|
const commentInput = $("#commentInput");
|
|
15
|
+
const commentTrigger = $("#commentTrigger");
|
|
15
16
|
const filePicker = $("#filePicker");
|
|
16
17
|
const fileList = $("#fileList");
|
|
17
18
|
|
|
@@ -120,38 +121,55 @@ function send(msg) {
|
|
|
120
121
|
// --- Selection & Comment Creation ---
|
|
121
122
|
|
|
122
123
|
document.addEventListener("mouseup", (e) => {
|
|
123
|
-
// Don't trigger when clicking inside popup or
|
|
124
|
-
if (popup.contains(e.target) || $("#sidebar").contains(e.target)) return;
|
|
124
|
+
// Don't trigger when clicking inside popup, sidebar, or trigger button
|
|
125
|
+
if (popup.contains(e.target) || commentTrigger.contains(e.target) || $("#sidebar").contains(e.target)) return;
|
|
125
126
|
|
|
126
127
|
const selection = window.getSelection();
|
|
127
128
|
if (!selection || selection.isCollapsed) {
|
|
128
|
-
|
|
129
|
+
hideTrigger();
|
|
129
130
|
return;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
const text = selection.toString().trim();
|
|
133
134
|
if (!text) {
|
|
134
|
-
|
|
135
|
+
hideTrigger();
|
|
135
136
|
return;
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
// Compute character offset in the source content
|
|
139
140
|
const offset = computeOffset(selection, text);
|
|
140
141
|
if (offset === -1) {
|
|
141
|
-
|
|
142
|
+
hideTrigger();
|
|
142
143
|
return;
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
selectionInfo = { offset, length: text.length, selectedText: text };
|
|
146
147
|
|
|
147
|
-
//
|
|
148
|
+
// Show the small "Comment" trigger button near the selection end
|
|
148
149
|
const range = selection.getRangeAt(0);
|
|
149
150
|
const rect = range.getBoundingClientRect();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
commentTrigger.style.left = `${Math.min(rect.right + 8, window.innerWidth - 100)}px`;
|
|
152
|
+
commentTrigger.style.top = `${rect.top - 4}px`;
|
|
153
|
+
commentTrigger.hidden = false;
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Clicking the trigger button opens the full comment popup
|
|
157
|
+
commentTrigger.addEventListener("mousedown", (e) => {
|
|
158
|
+
// Prevent the mousedown from clearing the text selection
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
commentTrigger.addEventListener("click", () => {
|
|
163
|
+
if (!selectionInfo) return;
|
|
164
|
+
|
|
165
|
+
// Position the popup near the trigger
|
|
166
|
+
const triggerRect = commentTrigger.getBoundingClientRect();
|
|
167
|
+
popup.style.left = `${Math.min(triggerRect.left, window.innerWidth - 340)}px`;
|
|
168
|
+
popup.style.top = `${triggerRect.bottom + 8}px`;
|
|
169
|
+
popupSelection.textContent = selectionInfo.selectedText;
|
|
153
170
|
commentInput.value = "";
|
|
154
171
|
popup.hidden = false;
|
|
172
|
+
commentTrigger.hidden = true;
|
|
155
173
|
commentInput.focus();
|
|
156
174
|
});
|
|
157
175
|
|
|
@@ -247,8 +265,17 @@ function computeDomOffset(node, charOffset) {
|
|
|
247
265
|
return -1;
|
|
248
266
|
}
|
|
249
267
|
|
|
268
|
+
function hideTrigger() {
|
|
269
|
+
commentTrigger.hidden = true;
|
|
270
|
+
// Only clear selectionInfo if popup isn't open
|
|
271
|
+
if (popup.hidden) {
|
|
272
|
+
selectionInfo = null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
250
276
|
function hidePopup() {
|
|
251
277
|
popup.hidden = true;
|
|
278
|
+
commentTrigger.hidden = true;
|
|
252
279
|
selectionInfo = null;
|
|
253
280
|
}
|
|
254
281
|
|
|
@@ -478,5 +505,16 @@ themeToggle.addEventListener("change", () => {
|
|
|
478
505
|
applyTheme(theme);
|
|
479
506
|
});
|
|
480
507
|
|
|
508
|
+
// Hide trigger when selection is cleared (e.g. clicking elsewhere)
|
|
509
|
+
document.addEventListener("selectionchange", () => {
|
|
510
|
+
const selection = window.getSelection();
|
|
511
|
+
if (!selection || selection.isCollapsed) {
|
|
512
|
+
// Small delay to avoid race with the trigger button click
|
|
513
|
+
setTimeout(() => {
|
|
514
|
+
if (popup.hidden) hideTrigger();
|
|
515
|
+
}, 100);
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
|
|
481
519
|
// --- Init ---
|
|
482
520
|
connect();
|
package/ui/index.html
CHANGED
|
@@ -50,7 +50,10 @@
|
|
|
50
50
|
</div>
|
|
51
51
|
</main>
|
|
52
52
|
|
|
53
|
-
<!-- Floating comment button
|
|
53
|
+
<!-- Floating comment button (appears on text selection) -->
|
|
54
|
+
<button class="comment-trigger" id="commentTrigger" hidden>Comment</button>
|
|
55
|
+
|
|
56
|
+
<!-- Comment form (appears when comment button is clicked) -->
|
|
54
57
|
<div class="comment-popup" id="commentPopup" hidden>
|
|
55
58
|
<div class="popup-header">Selection</div>
|
|
56
59
|
<div class="popup-selection" id="popupSelection"></div>
|
package/ui/styles.css
CHANGED
|
@@ -671,6 +671,34 @@ main {
|
|
|
671
671
|
transform: scale(0.97);
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
+
/* ---- Comment trigger button ---- */
|
|
675
|
+
.comment-trigger {
|
|
676
|
+
position: fixed;
|
|
677
|
+
z-index: 999;
|
|
678
|
+
font-family: var(--font-sans);
|
|
679
|
+
font-size: 12px;
|
|
680
|
+
font-weight: 600;
|
|
681
|
+
padding: 6px 14px;
|
|
682
|
+
border-radius: var(--radius-sm);
|
|
683
|
+
border: 1px solid var(--border);
|
|
684
|
+
background: var(--surface);
|
|
685
|
+
color: var(--accent);
|
|
686
|
+
cursor: pointer;
|
|
687
|
+
box-shadow: var(--shadow-md);
|
|
688
|
+
transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
|
|
689
|
+
animation: popup-enter 0.15s ease;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
.comment-trigger:hover {
|
|
693
|
+
background: var(--accent);
|
|
694
|
+
color: var(--bg);
|
|
695
|
+
border-color: var(--accent);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.comment-trigger:active {
|
|
699
|
+
transform: scale(0.96);
|
|
700
|
+
}
|
|
701
|
+
|
|
674
702
|
/* ---- Comment popup ---- */
|
|
675
703
|
.comment-popup {
|
|
676
704
|
position: fixed;
|