Fossil SCM

Implemented paste image into chat from clipboard. Fixed posted file download link but the files download with the same name as their message ID, which isn't very friendly. Not sure how to resolve that bit.

stephan 2020-12-23 07:09 chatroom-dev
Commit eb7845f33982b3f14836db15d149d84c40efe761f6e830a493a18fdcf306cd8c
2 files changed +4 +28 -4
+4
--- src/chat.c
+++ src/chat.c
@@ -105,10 +105,14 @@
105105
@ <input type="submit" value="Send">
106106
@ </div>
107107
@ <div id='chat-input-file'>
108108
@ <span>File:</span>
109109
@ <input type="file" name="file">
110
+ @ <div id='chat-pasted-image'>
111
+ @ Or paste an image from clipboard, if supported by your
112
+ @ environment.<br><img>
113
+ @ </div>
110114
@ </div>
111115
@ </div>
112116
@ </form>
113117
@ <hr>
114118
115119
--- src/chat.c
+++ src/chat.c
@@ -105,10 +105,14 @@
105 @ <input type="submit" value="Send">
106 @ </div>
107 @ <div id='chat-input-file'>
108 @ <span>File:</span>
109 @ <input type="file" name="file">
 
 
 
 
110 @ </div>
111 @ </div>
112 @ </form>
113 @ <hr>
114
115
--- src/chat.c
+++ src/chat.c
@@ -105,10 +105,14 @@
105 @ <input type="submit" value="Send">
106 @ </div>
107 @ <div id='chat-input-file'>
108 @ <span>File:</span>
109 @ <input type="file" name="file">
110 @ <div id='chat-pasted-image'>
111 @ Or paste an image from clipboard, if supported by your
112 @ environment.<br><img>
113 @ </div>
114 @ </div>
115 @ </div>
116 @ </form>
117 @ <hr>
118
119
+28 -4
--- src/chat.js
+++ src/chat.js
@@ -1,22 +1,45 @@
11
(function(){
22
const form = document.querySelector('#chat-form');
33
let mxMsg = 0;
44
const F = window.fossil;
55
const _me = F.user.name;
6
+ /* State for pasting an image from the clipboard */
7
+ const ImagePasteState = {
8
+ imgTag: document.querySelector('#chat-pasted-image img'),
9
+ blob: undefined
10
+ };
611
form.addEventListener('submit',(e)=>{
712
e.preventDefault();
8
- if( form.msg.value.length>0 || form.file.value.length>0 ){
13
+ const fd = new FormData(form);
14
+ if(ImagePasteState.blob/*replace file content with this*/){
15
+ fd.set("file", ImagePasteState.blob);
16
+ }
17
+ if( form.msg.value.length>0 || form.file.value.length>0 || ImagePasteState.blob ){
918
fetch("chat-send",{
1019
method: 'POST',
11
- body: new FormData(form)
20
+ body: fd
1221
});
1322
}
23
+ ImagePasteState.blob = undefined;
24
+ ImagePasteState.imgTag.removeAttribute('src');
1425
form.msg.value = "";
1526
form.file.value = "";
1627
form.msg.focus();
1728
});
29
+ /* Handle image paste from clipboard. TODO: confirm that we only
30
+ paste images here (silently ignore non-image data), or change the
31
+ related code to support non-image pasting/posting. */
32
+ document.onpaste = function(event){
33
+ const items = event.clipboardData.items;
34
+ ImagePasteState.blob = items[0].getAsFile();
35
+ const reader = new FileReader();
36
+ reader.onload = function(event){
37
+ ImagePasteState.imgTag.setAttribute('src', event.target.result);
38
+ };
39
+ reader.readAsDataURL(ImagePasteState.blob);
40
+ };
1841
/* Injects element e as a new row in the chat, at the top of the list */
1942
const injectMessage = function f(e){
2043
if(!f.injectPoint){
2144
f.injectPoint = document.querySelector('#message-inject-point');
2245
}
@@ -24,10 +47,11 @@
2447
f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
2548
}else{
2649
f.injectPoint.parentNode.appendChild(e);
2750
}
2851
};
52
+ /* Returns a new TEXT node with the given text content. */
2953
const textNode = (T)=>document.createTextNode(T);
3054
/** Returns the local time string of Date object d, defaulting
3155
to the current time. */
3256
const localTimeString = function ff(d){
3357
if(!ff.pad){
@@ -126,12 +150,12 @@
126150
img.src = "chat-download/" + m.msgid;
127151
span.appendChild(img);
128152
}else{
129153
let a = document.createElement("a");
130154
let txt = "(" + m.fname + " " + m.fsize + " bytes)";
131
- a.href = "%string($downloadurl)/" + m.msgid;
132
- a.appendChild(document.createTextNode(txt));
155
+ a.href = window.fossil.rootPath+'chat-download/' + m.msgid;
156
+ a.appendChild(textNode(txt));
133157
span.appendChild(a);
134158
}
135159
let br = document.createElement("br");
136160
br.style.clear = "both";
137161
span.appendChild(br);
138162
--- src/chat.js
+++ src/chat.js
@@ -1,22 +1,45 @@
1 (function(){
2 const form = document.querySelector('#chat-form');
3 let mxMsg = 0;
4 const F = window.fossil;
5 const _me = F.user.name;
 
 
 
 
 
6 form.addEventListener('submit',(e)=>{
7 e.preventDefault();
8 if( form.msg.value.length>0 || form.file.value.length>0 ){
 
 
 
 
9 fetch("chat-send",{
10 method: 'POST',
11 body: new FormData(form)
12 });
13 }
 
 
14 form.msg.value = "";
15 form.file.value = "";
16 form.msg.focus();
17 });
 
 
 
 
 
 
 
 
 
 
 
 
18 /* Injects element e as a new row in the chat, at the top of the list */
19 const injectMessage = function f(e){
20 if(!f.injectPoint){
21 f.injectPoint = document.querySelector('#message-inject-point');
22 }
@@ -24,10 +47,11 @@
24 f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
25 }else{
26 f.injectPoint.parentNode.appendChild(e);
27 }
28 };
 
29 const textNode = (T)=>document.createTextNode(T);
30 /** Returns the local time string of Date object d, defaulting
31 to the current time. */
32 const localTimeString = function ff(d){
33 if(!ff.pad){
@@ -126,12 +150,12 @@
126 img.src = "chat-download/" + m.msgid;
127 span.appendChild(img);
128 }else{
129 let a = document.createElement("a");
130 let txt = "(" + m.fname + " " + m.fsize + " bytes)";
131 a.href = "%string($downloadurl)/" + m.msgid;
132 a.appendChild(document.createTextNode(txt));
133 span.appendChild(a);
134 }
135 let br = document.createElement("br");
136 br.style.clear = "both";
137 span.appendChild(br);
138
--- src/chat.js
+++ src/chat.js
@@ -1,22 +1,45 @@
1 (function(){
2 const form = document.querySelector('#chat-form');
3 let mxMsg = 0;
4 const F = window.fossil;
5 const _me = F.user.name;
6 /* State for pasting an image from the clipboard */
7 const ImagePasteState = {
8 imgTag: document.querySelector('#chat-pasted-image img'),
9 blob: undefined
10 };
11 form.addEventListener('submit',(e)=>{
12 e.preventDefault();
13 const fd = new FormData(form);
14 if(ImagePasteState.blob/*replace file content with this*/){
15 fd.set("file", ImagePasteState.blob);
16 }
17 if( form.msg.value.length>0 || form.file.value.length>0 || ImagePasteState.blob ){
18 fetch("chat-send",{
19 method: 'POST',
20 body: fd
21 });
22 }
23 ImagePasteState.blob = undefined;
24 ImagePasteState.imgTag.removeAttribute('src');
25 form.msg.value = "";
26 form.file.value = "";
27 form.msg.focus();
28 });
29 /* Handle image paste from clipboard. TODO: confirm that we only
30 paste images here (silently ignore non-image data), or change the
31 related code to support non-image pasting/posting. */
32 document.onpaste = function(event){
33 const items = event.clipboardData.items;
34 ImagePasteState.blob = items[0].getAsFile();
35 const reader = new FileReader();
36 reader.onload = function(event){
37 ImagePasteState.imgTag.setAttribute('src', event.target.result);
38 };
39 reader.readAsDataURL(ImagePasteState.blob);
40 };
41 /* Injects element e as a new row in the chat, at the top of the list */
42 const injectMessage = function f(e){
43 if(!f.injectPoint){
44 f.injectPoint = document.querySelector('#message-inject-point');
45 }
@@ -24,10 +47,11 @@
47 f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
48 }else{
49 f.injectPoint.parentNode.appendChild(e);
50 }
51 };
52 /* Returns a new TEXT node with the given text content. */
53 const textNode = (T)=>document.createTextNode(T);
54 /** Returns the local time string of Date object d, defaulting
55 to the current time. */
56 const localTimeString = function ff(d){
57 if(!ff.pad){
@@ -126,12 +150,12 @@
150 img.src = "chat-download/" + m.msgid;
151 span.appendChild(img);
152 }else{
153 let a = document.createElement("a");
154 let txt = "(" + m.fname + " " + m.fsize + " bytes)";
155 a.href = window.fossil.rootPath+'chat-download/' + m.msgid;
156 a.appendChild(textNode(txt));
157 span.appendChild(a);
158 }
159 let br = document.createElement("br");
160 br.style.clear = "both";
161 span.appendChild(br);
162

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button