@social-mail/social-mail-client 1.0.21 → 1.0.23

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.
Files changed (29) hide show
  1. package/dist/admin/AdminAppIndex.pack.js +11 -0
  2. package/dist/admin/AdminAppIndex.pack.js.map +1 -1
  3. package/dist/admin/AdminAppIndex.pack.min.js +1 -1
  4. package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
  5. package/dist/common/controls/html/InlineHtmlEditorWithToolbar.js +85 -7
  6. package/dist/common/controls/html/InlineHtmlEditorWithToolbar.js.map +1 -1
  7. package/dist/services/files/LocalFileService.js +11 -0
  8. package/dist/services/files/LocalFileService.js.map +1 -1
  9. package/dist/tsconfig.tsbuildinfo +1 -1
  10. package/dist/web/AppIndex.pack.js +451 -394
  11. package/dist/web/AppIndex.pack.js.map +1 -1
  12. package/dist/web/AppIndex.pack.min.js +46 -34
  13. package/dist/web/AppIndex.pack.min.js.map +1 -1
  14. package/dist/web/page/mails/ComposeMailPage.js +1 -1
  15. package/dist/web/page/mails/ComposeMailPage.js.map +1 -1
  16. package/dist/web/page/mails/MailsPage.js +1 -1
  17. package/dist/web/page/mails/MailsPage.js.map +1 -1
  18. package/node_modules/@web-atoms/web-controls/dist/html-editor/InlineHtmlEditor.d.ts +1 -1
  19. package/node_modules/@web-atoms/web-controls/dist/html-editor/InlineHtmlEditor.d.ts.map +1 -1
  20. package/node_modules/@web-atoms/web-controls/dist/html-editor/InlineHtmlEditor.js +29 -2
  21. package/node_modules/@web-atoms/web-controls/dist/html-editor/InlineHtmlEditor.js.map +1 -1
  22. package/node_modules/@web-atoms/web-controls/dist/tsconfig.tsbuildinfo +1 -1
  23. package/node_modules/@web-atoms/web-controls/package.json +1 -1
  24. package/node_modules/@web-atoms/web-controls/src/html-editor/InlineHtmlEditor.tsx +37 -2
  25. package/package.json +2 -2
  26. package/src/common/controls/html/InlineHtmlEditorWithToolbar.tsx +78 -3
  27. package/src/services/files/LocalFileService.tsx +5 -0
  28. package/src/web/page/mails/ComposeMailPage.tsx +1 -1
  29. package/src/web/page/mails/MailsPage.tsx +1 -1
@@ -11,6 +11,18 @@ import styled from "@web-atoms/core/dist/style/styled";
11
11
 
12
12
  styled.css `
13
13
 
14
+ & > [data-element=editor] {
15
+
16
+ padding: var(--spacing, 5px);
17
+ border: solid 1px lightgray;
18
+ border-radius: var(--spacing, 5px);
19
+ margin: var(--spacing, 5px);
20
+
21
+ & > * {
22
+ outline: none;
23
+ }
24
+ }
25
+
14
26
  & > [data-element=toolbar] {
15
27
  flex-direction: column;
16
28
  align-items: center;
@@ -207,13 +219,35 @@ export default class InlineHtmlEditor extends AtomControl {
207
219
  this.bindEvent(this.editor, "blur", () => this.saveSelection(), void 0, true);
208
220
  this.bindEvent(this.editor, "input", (e: InputEvent) => this.onContentInput(e));
209
221
  this.bindEvent(this.editor, "keydown", (e: KeyboardEvent) => this.updateQueryCommand());
210
- this.bindEvent(this.editor, "click", (e: KeyboardEvent) => this.updateQueryCommand());
222
+ this.bindEvent(this.editor, "click", (e: MouseEvent) => this.updateQueryCommand(e));
211
223
  this.bindEvent(this.editor, "paste", (e: ClipboardEvent) => this.onPasteEvent(e));
212
224
  this.bindEvent(this.editor, "cut", () => this.onContentInput());
213
225
  this.bindEvent(this.editor, "drop", (e: DragEvent) => this.onDrop(e));
214
226
  }
215
227
 
216
- protected updateQueryCommand() {
228
+ protected updateQueryCommand(e?: Event) {
229
+ if (e?.type === "click") {
230
+ if (!this.editor.textContent) {
231
+ let first = this.editor.firstElementChild;
232
+ if(!first) {
233
+ first = document.createElement("div");
234
+ first.innerHTML = "<p><br/></p>";
235
+ this.editor.appendChild(first);
236
+ }
237
+ else {
238
+ if (!first.lastChild) {
239
+ first.innerHTML = "<p></br></b>";
240
+ }
241
+ }
242
+ // const selection = window.getSelection();
243
+ // selection.removeAllRanges();
244
+ // const range = document.createRange();
245
+ // // find editable...
246
+ // range.setEndAfter(first.lastChild);
247
+ // range.setStartAfter(first.lastChild);
248
+ // selection.addRange(range);
249
+ }
250
+ }
217
251
  this.version++;
218
252
  }
219
253
 
@@ -238,6 +272,7 @@ export default class InlineHtmlEditor extends AtomControl {
238
272
  protected onPasteEvent(e: ClipboardEvent) {
239
273
  // tslint:disable-next-line: no-console
240
274
  if (!e.clipboardData.types.find((x) => x === "text/html")) {
275
+ this.onContentInput();
241
276
  return;
242
277
  }
243
278
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-client",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -19,7 +19,7 @@
19
19
  "@web-atoms/font-awesome": "^1.0.37",
20
20
  "@web-atoms/hybrid-clr": "^1.0.21",
21
21
  "@web-atoms/module-loader": "^2.1.32",
22
- "@web-atoms/web-controls": "^2.3.250",
22
+ "@web-atoms/web-controls": "^2.3.254",
23
23
  "reflect-metadata": "^0.1.13"
24
24
  },
25
25
  "devDependencies": {
@@ -16,12 +16,15 @@ import NumberedList from "@web-atoms/web-controls/dist/html-editor/commands/Numb
16
16
  import UnorderedList from "@web-atoms/web-controls/dist/html-editor/commands/UnorderedList";
17
17
  import IndentLess from "@web-atoms/web-controls/dist/html-editor/commands/IndentLess";
18
18
  import IndentMore from "@web-atoms/web-controls/dist/html-editor/commands/IndentMore";
19
- import AttachImage from "@web-atoms/web-controls/dist/html-editor/commands/AttachImage";
20
19
  import AttachFile from "@web-atoms/web-controls/dist/html-editor/commands/AttachFile";
21
20
  import AddLink from "@web-atoms/web-controls/dist/html-editor/commands/AddLink";
22
21
  import Unlink from "@web-atoms/web-controls/dist/html-editor/commands/Unlink";
23
22
  import RemoveFormat from "@web-atoms/web-controls/dist/html-editor/commands/RemoveFormat";
24
23
  import Source from "@web-atoms/web-controls/dist/html-editor/commands/Source";
24
+ import UploadEvent from "@web-atoms/web-controls/dist/basic/UploadEvent";
25
+ import LocalFileService, { IUploadedFile, UploadedFiles } from "../../../services/files/LocalFileService";
26
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
27
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
25
28
 
26
29
  const link = document.createElement("link");
27
30
  link.href = "https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css";
@@ -33,7 +36,79 @@ link.onload = () => {
33
36
  };
34
37
  document.head.appendChild(link);
35
38
 
36
- export default function InlineHtmlEditorWithToolbar(a: Partial<InlineHtmlEditor> & { presenter?: any}) {
39
+ const onAttachImage = async (ce: UploadedFiles) => {
40
+ const c = AtomControl.from(ce.target) as any;
41
+ // create data url...
42
+ if(!ce.detail?.files?.length) {
43
+ return;
44
+ }
45
+ const file = ce.detail.files[0];
46
+
47
+ c.executeCommand("insertHTML", void 0, `<div><img data-content="data-url" data-content-id=${file.appFileID} src="${file.url}" style='max-height: 700px;'/></div>`);
48
+ };
49
+
50
+ function AttachImage({
51
+ accept = "image/*",
52
+ maxSize = 1024*1024*5,
53
+ authorize = true,
54
+ capture = null as string,
55
+ ariaLabel = "upload"
56
+ }) {
57
+ return <button
58
+ title="Insert Image"
59
+ class="command"
60
+ { ... UploadEvent.AttachUploadAction({
61
+ accept,
62
+ forceType: true,
63
+ maxSize,
64
+ authorize,
65
+ capture,
66
+ multiple: false,
67
+ ariaLabel,
68
+ "event-files-available": onAttachImage as any
69
+ })}
70
+ >
71
+ <i class="ri-image-add-fill" />
72
+ </button>;
73
+ }
74
+
75
+ export class MailHtmlEditor extends InlineHtmlEditor {
76
+
77
+ public files: IUploadedFile[];
78
+
79
+ @InjectProperty
80
+ private localFileService: LocalFileService;
81
+
82
+ protected onPasteEvent(e: ClipboardEvent): void {
83
+ if (e.clipboardData.files.length) {
84
+ e.preventDefault();
85
+ e.stopPropagation();
86
+ this.app.runAsync(async() => {
87
+ const files = await this.localFileService.uploadWithProgress(Array.from(e.clipboardData.files));
88
+ for (const file of files) {
89
+ this.executeCommand("insertHTML", void 0, `<div><img data-content="data-url" data-content-id=${file.appFileID} src="${file.url}" style='max-height: 700px;'/></div>`);
90
+ }
91
+ this.element.dispatchEvent(new CustomEvent("filesAvailable", { detail: { files, extra: "none" }, bubbles: true }));
92
+ });
93
+ return;
94
+ }
95
+ super.onPasteEvent(e);
96
+ }
97
+
98
+ protected preCreate(): void {
99
+ super.preCreate();
100
+ this.sanitizeHtml = (node) => {
101
+ const images = Array.from(node.querySelectorAll(`img[data-content-id]`));
102
+ for (const image of images) {
103
+ image.setAttribute("src", `cid:${image.getAttribute("data-content-id")}`);
104
+ }
105
+ };
106
+
107
+ }
108
+
109
+ }
110
+
111
+ export default function InlineHtmlEditorWithToolbar(a: Partial<MailHtmlEditor> & { presenter?: any}) {
37
112
  const toolbar = () => <div>
38
113
  <Toolbar>
39
114
  <Bold/>
@@ -66,7 +141,7 @@ export default function InlineHtmlEditorWithToolbar(a: Partial<InlineHtmlEditor>
66
141
  <Source/>
67
142
  </Toolbar>
68
143
  </div>;
69
- return <InlineHtmlEditor
144
+ return <MailHtmlEditor
70
145
  { ... a}
71
146
  toolbar={toolbar}
72
147
  />;
@@ -79,6 +79,11 @@ export default class LocalFileService {
79
79
  });
80
80
  }
81
81
 
82
+ async uploadWithProgress(files: File[]) {
83
+ const detail = await FileUploadWindow.showModal<{ files: IUploadedFile[]}>({ parameters: { files, extra: "" }});
84
+ return detail.files;
85
+ }
86
+
82
87
  async upload(files: File[]) {
83
88
  return files.map((file) => {
84
89
  const uploadFile: IFileUpload = {
@@ -43,7 +43,7 @@ export default class ComposeMailPage extends PopupWindowPage {
43
43
  this.model = this.parameters.model ?? Email.create({
44
44
  subject: this.parameters.subject ?? "",
45
45
  textBody: "",
46
- htmlBody: `<div contentEditable="true">Type message here... </div>`,
46
+ htmlBody: `<div contentEditable="true"><p><br/><br/><br/><br/><br/></p></div>`,
47
47
  recipients: [],
48
48
  attachments: []
49
49
  });
@@ -50,7 +50,7 @@ export default class MailsPage extends MasterDetailPage {
50
50
  data-list-selection="default"
51
51
  data-items-updated-event="mails-available"
52
52
  data-selection-updated-event="mail-selected"
53
- selectedItem={Bind.oneWay(() => this.selectedThread)}
53
+ selectedItem={Bind.twoWays(() => this.selectedThread)}
54
54
  selectOnClick={true}
55
55
  items={this.mails}
56
56
  { ... InfiniteRepeater.pagedItems((start) => (c, e, cancelToken) => this.mailService.list({