@social-mail/social-mail-client 1.2.367 → 1.2.369

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 (75) hide show
  1. package/dist/admin/AdminAppIndex.pack.js +389 -207
  2. package/dist/admin/AdminAppIndex.pack.js.map +1 -1
  3. package/dist/admin/AdminAppIndex.pack.min.js +21 -9
  4. package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
  5. package/dist/common/controls/email-recipients/EmailRecipientChips.d.ts.map +1 -1
  6. package/dist/common/controls/email-recipients/EmailRecipientChips.js +6 -8
  7. package/dist/common/controls/email-recipients/EmailRecipientChips.js.map +1 -1
  8. package/dist/common/controls/html/InlineHtmlEditorWithToolbar.d.ts.map +1 -1
  9. package/dist/common/events/CommonEvents.d.ts +0 -2
  10. package/dist/common/events/CommonEvents.d.ts.map +1 -1
  11. package/dist/common/events/CommonEvents.js +1 -3
  12. package/dist/common/events/CommonEvents.js.map +1 -1
  13. package/dist/public/channel/ChannelView.pack.js +37 -33
  14. package/dist/public/channel/ChannelView.pack.js.map +1 -1
  15. package/dist/public/channel/ChannelView.pack.min.js +1 -1
  16. package/dist/public/channel/ChannelView.pack.min.js.map +1 -1
  17. package/dist/public/contact-us/ContactUsApp.d.ts.map +1 -1
  18. package/dist/public/contact-us/ContactUsApp.js +9 -0
  19. package/dist/public/contact-us/ContactUsApp.js.map +1 -1
  20. package/dist/public/contact-us/ContactUsApp.pack.js +9 -0
  21. package/dist/public/contact-us/ContactUsApp.pack.js.map +1 -1
  22. package/dist/public/contact-us/ContactUsApp.pack.min.js +9 -0
  23. package/dist/public/contact-us/ContactUsApp.pack.min.js.map +1 -1
  24. package/dist/public/store/Store.pack.js +11 -6
  25. package/dist/public/store/Store.pack.js.map +1 -1
  26. package/dist/public/store/Store.pack.min.js +3 -1
  27. package/dist/public/store/Store.pack.min.js.map +1 -1
  28. package/dist/public/store/StoreItemDetailView.d.ts.map +1 -1
  29. package/dist/public/store/StoreItemDetailView.js +2 -0
  30. package/dist/public/store/StoreItemDetailView.js.map +1 -1
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/dist/web/AppIndex.pack.js +389 -207
  33. package/dist/web/AppIndex.pack.js.map +1 -1
  34. package/dist/web/AppIndex.pack.min.js +22 -10
  35. package/dist/web/AppIndex.pack.min.js.map +1 -1
  36. package/dist/web/page/mails/ConversationPage.d.ts +1 -0
  37. package/dist/web/page/mails/ConversationPage.d.ts.map +1 -1
  38. package/dist/web/page/mails/ConversationPage.js +22 -5
  39. package/dist/web/page/mails/ConversationPage.js.map +1 -1
  40. package/dist/web/page/mails/mini-compose/MiniComposeBox.d.ts +11 -5
  41. package/dist/web/page/mails/mini-compose/MiniComposeBox.d.ts.map +1 -1
  42. package/dist/web/page/mails/mini-compose/MiniComposeBox.js +127 -126
  43. package/dist/web/page/mails/mini-compose/MiniComposeBox.js.map +1 -1
  44. package/dist/web/page/mails/mini-compose/MiniComposePage.d.ts +16 -0
  45. package/dist/web/page/mails/mini-compose/MiniComposePage.d.ts.map +1 -0
  46. package/dist/web/page/mails/mini-compose/MiniComposePage.js +146 -0
  47. package/dist/web/page/mails/mini-compose/MiniComposePage.js.map +1 -0
  48. package/dist/web/page/mails/service/ConversationService.d.ts +1 -1
  49. package/dist/web/page/mails/service/ConversationService.d.ts.map +1 -1
  50. package/dist/web/page/mails/service/ConversationService.js +27 -24
  51. package/dist/web/page/mails/service/ConversationService.js.map +1 -1
  52. package/node_modules/@web-atoms/web-controls/dist/basic/AtomChips.d.ts +1 -1
  53. package/node_modules/@web-atoms/web-controls/dist/basic/AtomChips.d.ts.map +1 -1
  54. package/node_modules/@web-atoms/web-controls/dist/basic/AtomChips.js +16 -11
  55. package/node_modules/@web-atoms/web-controls/dist/basic/AtomChips.js.map +1 -1
  56. package/node_modules/@web-atoms/web-controls/dist/basic/AtomRepeater.d.ts.map +1 -1
  57. package/node_modules/@web-atoms/web-controls/dist/basic/AtomRepeater.js +9 -6
  58. package/node_modules/@web-atoms/web-controls/dist/basic/AtomRepeater.js.map +1 -1
  59. package/node_modules/@web-atoms/web-controls/dist/basic/styles/item-suggestion-style.js +8 -0
  60. package/node_modules/@web-atoms/web-controls/dist/basic/styles/item-suggestion-style.js.map +1 -1
  61. package/node_modules/@web-atoms/web-controls/dist/tsconfig.tsbuildinfo +1 -1
  62. package/node_modules/@web-atoms/web-controls/package.json +1 -1
  63. package/node_modules/@web-atoms/web-controls/src/basic/AtomChips.tsx +6 -4
  64. package/node_modules/@web-atoms/web-controls/src/basic/AtomRepeater.tsx +9 -8
  65. package/node_modules/@web-atoms/web-controls/src/basic/styles/item-suggestion-style.ts +8 -0
  66. package/package.json +2 -2
  67. package/src/common/controls/email-recipients/EmailRecipientChips.tsx +11 -5
  68. package/src/common/controls/html/InlineHtmlEditorWithToolbar.tsx +1 -1
  69. package/src/common/events/CommonEvents.ts +0 -5
  70. package/src/public/contact-us/ContactUsApp.tsx +9 -0
  71. package/src/public/store/StoreItemDetailView.tsx +2 -0
  72. package/src/web/page/mails/ConversationPage.tsx +15 -3
  73. package/src/web/page/mails/mini-compose/MiniComposeBox.tsx +212 -114
  74. package/src/web/page/mails/mini-compose/MiniComposePage.tsx +128 -0
  75. package/src/web/page/mails/service/ConversationService.tsx +25 -19
@@ -34,6 +34,7 @@ import { apiPath } from "../../../common/apiPath";
34
34
  import { AddIconTextButton, DeleteIconTextButton, EditIconTextButton } from "../../../common/controls/buttons/IconButton";
35
35
  import sleep from "@web-atoms/core/dist/core/sleep";
36
36
  import UnsubscribeWindow from "./unsubscribe/UnsubscribeWindow";
37
+ import MiniComposePage from "./mini-compose/MiniComposePage";
37
38
 
38
39
  const itemCss = styled.css `
39
40
  border: solid 1px lightgray;
@@ -67,6 +68,7 @@ const itemCss = styled.css `
67
68
  }
68
69
  margin-bottom: 5px;
69
70
  }
71
+
70
72
  `.installLocal();
71
73
 
72
74
 
@@ -82,6 +84,10 @@ const css = styled.css `
82
84
 
83
85
  }
84
86
  }
87
+
88
+ & [data-mini-compose] {
89
+ border-top: solid 1px lightgray;
90
+ }
85
91
  `.installLocal();
86
92
 
87
93
  let id = 1;
@@ -374,7 +380,8 @@ export default class ConversationPage extends ContentPage {
374
380
  @Action({ onEvent: "edit-draft"})
375
381
  startCompose(thread: IMailboxContactEmail = null, email = null) {
376
382
  this.footerRenderer = () => <MiniComposeBox
377
- mailboxContact={thread ?? this.parameters}
383
+ senderID={this.parameters.mailboxID}
384
+ mailboxContacts={[thread ?? this.parameters]}
378
385
  draft={thread?.email ?? email}
379
386
  />;
380
387
  }
@@ -478,11 +485,11 @@ export default class ConversationPage extends ContentPage {
478
485
  data-click-event="none"
479
486
  data-click-animate="none">
480
487
  <MenuItem
481
- eventClick={() => CommonEvents.onEmailForward.dispatchEvent(thread)}
488
+ eventClick={() => this.onEmailForward(thread)}
482
489
  label="As Inline Message"
483
490
  />
484
491
  <MenuItem
485
- eventClick={() => CommonEvents.onEmailForwardAsAttachment.dispatchEvent(thread)}
492
+ eventClick={() => this.onEmailForward(thread, true)}
486
493
  label="As Attachment"
487
494
  />
488
495
  </div>, { alignment: "above"});
@@ -526,6 +533,11 @@ export default class ConversationPage extends ContentPage {
526
533
  PageNavigator.pushPage(LogsPage, { emailID });
527
534
  }
528
535
 
536
+ @Action({})
537
+ async onEmailForward(thread: IMailboxContactEmail, asAttachment = false) {
538
+ PageNavigator.pushPage(MiniComposePage, { thread , asAttachment });
539
+ }
540
+
529
541
  @Action({ onEvent: "react-email"})
530
542
  async reactEmail(thread: IMailboxContactEmail, ce: CustomEvent) {
531
543
  const emoji = await EmojiPicker.show<string>({
@@ -1,7 +1,7 @@
1
1
  import XNode from "@web-atoms/core/dist/core/XNode";
2
2
  import styled from "@web-atoms/core/dist/style/styled";
3
3
  import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
4
- import { AppFile, Email, IAppFile, IEmail, IMailboxContact, IMailboxContactEmail } from "../../../../model/model";
4
+ import { AppFile, Email, EmailRecipient, IAppFile, IEmail, IEmailRecipient, IMailboxContact, IMailboxContactEmail } from "../../../../model/model";
5
5
  import Bind from "@web-atoms/core/dist/core/Bind";
6
6
  import Action from "@web-atoms/core/dist/view-model/Action";
7
7
  import AudioRecorder from "../../../../common/controls/audio/AudioRecorder";
@@ -36,12 +36,12 @@ import EmailLabel from "../../../../common/controls/email-recipients/EmailLabel"
36
36
  import Loader from "../../../../common/controls/Loader";
37
37
  import { descendentElementIterator } from "@web-atoms/core/dist/web/core/AtomUI";
38
38
  import TitleEditor from "@web-atoms/web-controls/dist/basic/TitleEditor";
39
+ import EmailRecipientChips from "../../../../common/controls/email-recipients/EmailRecipientChips";
39
40
 
40
41
  const css = styled.css `
41
42
  display: grid;
42
43
  grid-template-columns: auto 1fr auto;
43
44
  grid-template-rows: auto 1fr auto;
44
- border-top: solid 1px lightgray;
45
45
  max-height: 50vh;
46
46
 
47
47
  background-color: canvas;
@@ -103,12 +103,25 @@ const defaultEmailBody = `<section style="background-color: white; color: black;
103
103
 
104
104
  export default class MiniComposeBox extends AtomControl {
105
105
 
106
- public mailboxContact: IMailboxContact = null;
106
+ public mailboxContacts: IMailboxContact[] = [];
107
+
108
+ public senderID: number = null;
107
109
 
108
110
  public draft: IEmail = null;
109
111
 
110
112
  public typedMessage: string = "";
111
113
 
114
+ public to = null as IEmailRecipient[];
115
+
116
+ public cc = null as IEmailRecipient[];
117
+ public bcc = null as IEmailRecipient[];
118
+
119
+ public showSendButton = true;
120
+
121
+ public showTo = false;
122
+ private showCc = false;
123
+ private showBcc = false;
124
+
112
125
  @InjectProperty
113
126
  private conversationService: ConversationService;
114
127
 
@@ -129,6 +142,7 @@ export default class MiniComposeBox extends AtomControl {
129
142
  constructor(app, e) {
130
143
  super(app, e);
131
144
  this.element.className = css;
145
+ this.element.setAttribute("data-mini-compose", "mini-compose");
132
146
  this.app.runAsync(() => this.init());
133
147
  }
134
148
 
@@ -146,6 +160,34 @@ export default class MiniComposeBox extends AtomControl {
146
160
  this.ensureDraft();
147
161
  }
148
162
 
163
+ // segregate to/cc/bcc
164
+ this.to ??= [];
165
+ this.cc ??= [];
166
+ this.bcc ??= [];
167
+ if (this.draft.recipients) {
168
+ for (const iterator of this.draft.recipients) {
169
+ if (iterator.type === "to") {
170
+ this.to.add(iterator);
171
+ this.showTo ||= !this.mailboxContacts?.some((x) => x.emailAddressID === iterator.emailAddressID);
172
+ continue;
173
+ }
174
+ if (iterator.type === "cc") {
175
+ this.showTo = true;
176
+ this.showCc = true;
177
+ this.cc.add(iterator);
178
+ continue;
179
+ }
180
+ if (iterator.type === "bcc") {
181
+ this.showTo = true;
182
+ this.showCc = true;
183
+ this.showBcc = true;
184
+ this.bcc.add(iterator);
185
+ continue;
186
+ }
187
+ }
188
+ }
189
+
190
+
149
191
  this.typedMessage = this.draft?.htmlBody
150
192
  ? this.draft.htmlBody
151
193
  : defaultEmailBody;
@@ -154,23 +196,61 @@ export default class MiniComposeBox extends AtomControl {
154
196
  <MailHtmlEditor
155
197
  toolbar={() => <div>
156
198
  <Toolbar>
157
- <Insert/>
199
+ <Insert alignment={ this.showSendButton ? "above" : "below" }/>
158
200
  <Separator/>
159
- <Attach/>
201
+ <Attach alignment={ this.showSendButton ? "above" : "below" }/>
160
202
  <Separator/>
161
203
  <Bold/>
162
204
  <Italic/>
163
205
  <Underline/>
164
206
  <StrikeThrough/>
165
- <Align alignment="above"/>
207
+ <Align alignment={ this.showSendButton ? "above" : "below" }/>
166
208
  <Separator/>
167
209
  <AddLink/>
168
210
  <Unlink/>
169
211
  </Toolbar>
170
- <TitleEditor
171
- class="subject"
172
- placeholder="Subject ... "
173
- value={Bind.sourceTwoWays(this, (x) => x.source.draft.subject)}/>
212
+ <div data-layout="vertical-flex-stretch-items" style-width="100%">
213
+ <div data-layout="row">
214
+ <TitleEditor
215
+ data-flex="stretch-full"
216
+ class="subject"
217
+ placeholder="Subject ... "
218
+ value={Bind.sourceTwoWays(this, (x) => x.source.draft.subject)}/>
219
+ <i
220
+ style-display={Bind.source(this, (x) => !x.source.showTo)}
221
+ event-click={() => this.showTo = true} class="fas fa-angle-down"/>
222
+ </div>
223
+ <div data-layout="row" style-display={Bind.source(this, (x) => x.source.showTo)}>
224
+ <EmailRecipientChips
225
+ prompt="To"
226
+ data-flex="stretch-full"
227
+ items={this.to}
228
+ />
229
+ <label
230
+ style-display={Bind.source(this, (x) => !x.source.showCc)}
231
+ event-click={() => this.showCc = true}
232
+ text="CC"
233
+ />
234
+ </div>
235
+ <div data-layout="row" style-display={Bind.source(this, (x) => x.source.showCc)}>
236
+ <EmailRecipientChips
237
+ prompt="Cc"
238
+ data-flex="stretch-full"
239
+ items={this.cc}
240
+ />
241
+ <label
242
+ style-display={Bind.source(this, (x) => !x.source.showBcc)}
243
+ event-click={() => this.showBcc = true}
244
+ text="BCC"
245
+ />
246
+ </div>
247
+ <EmailRecipientChips
248
+ prompt="Bcc"
249
+ data-flex="stretch-full"
250
+ style-display={Bind.source(this, (x) => x.source.showBcc)}
251
+ items={this.bcc}
252
+ />
253
+ </div>
174
254
  </div>}
175
255
  data-element="editor"
176
256
  data-html-editor="email-editor"
@@ -179,17 +259,17 @@ export default class MiniComposeBox extends AtomControl {
179
259
  style-min-height="50px"
180
260
  attachments={Bind.oneWay(() => this.draft.attachments)}
181
261
  />
182
- <i
262
+ { this.showSendButton && <i
183
263
  data-element="send"
184
264
  class="fa-solid fa-microphone-lines mic"
185
265
  event-click={() => this.sendAudioMessage()}
186
- style-display={Bind.oneWay(() => !this.typedMessage)} />
187
- <i
266
+ style-display={Bind.oneWay(() => !this.typedMessage)} /> }
267
+ { this.showSendButton && <i
188
268
  data-element="send"
189
269
  class="fa-solid fa-angle-double-right send"
190
270
  style-display={Bind.oneWay(() => !!this.typedMessage)}
191
271
  data-click-event="send-email"
192
- />
272
+ /> }
193
273
  <AtomRepeater
194
274
  data-element="files"
195
275
  items={Bind.oneWay(() => this.draft?.attachments)}
@@ -329,93 +409,93 @@ export default class MiniComposeBox extends AtomControl {
329
409
  this.draft = mce.email;
330
410
  }
331
411
 
332
- @Action({ onEvent: CommonEvents.onEmailForward})
333
- async onForwardEmail(mce: IMailboxContactEmail) {
334
- if (this.draft?.emailID) {
335
- await this.save(true);
336
- this.draft = null;
337
- }
338
- this.ensureDraft();
339
- const { email } = mce;
340
- const { recipients } = email;
341
- const to = recipients?.filter((x) => x.type === "to");
342
- const cc = recipients?.filter((x) => x.type === "cc");
343
- this.draft.htmlBody = DomToString(
344
- <section
345
- style="background-color: white; color: black;">
346
- <section contentEditable="true">
347
- {"\xa0"}
348
- <br/>
349
- </section>
350
- <blockquote
351
- contentEditable="false"
352
- data-type="forwarded"
353
- style="margin-inline-start: 20px; margin-inline-end: 0; border-left: solid 1px lightgray; padding-left: 10px;">
354
- <summary><div>From: ${email.senderName} {`<${email.senderEmail.emailAddress}>`}</div>
355
- <div>
356
- { to?.length && <div>
357
- <label style="margin-right:10px;">To:</label>
358
- { ... to.map((x) => <EmailLabel recipient={x} />) }
359
- </div> }
360
- { cc?.length && <div>
361
- <label style="margin-right:10px;">CC:</label>
362
- { ... cc.map((x) => <EmailLabel recipient={x} />) }
363
- </div>}
364
- <div>
365
- <label style="margin-right:10px;">Subject:</label>
366
- <label>{email.subject}</label>
367
- </div>
368
- <div data-type="html-body">
369
- {email.htmlBody}
370
- </div>
371
- </div>
372
- </summary>
373
- </blockquote>
374
- <footer data-social-mail-commands="emoji-bar">
375
- </footer>
376
- </section>);
377
-
378
- // copy all attachments..
379
- this.editor.htmlContent = this.draft.htmlBody;
380
-
381
- const attachments = mce.email.attachments;
382
- if (attachments) {
383
- for (const iterator of attachments) {
384
- this.draft.attachments.add(AppFile.create({
385
- ... iterator,
386
- appFileID: void 0,
387
- }));
388
- }
389
- }
390
- await this.save(!!attachments);
391
- }
392
-
393
- @Action({ onEvent: CommonEvents.onEmailForwardAsAttachment})
394
- async onForwardEmailAsAttachment(mce: IMailboxContactEmail) {
395
- if (this.draft?.emailID) {
396
- await this.save(true);
397
- this.draft = null;
398
- }
399
- this.ensureDraft();
400
- const { email, signedFileLogID } = mce;
401
- const { mimeFileID } = email;
402
-
403
- this.draft.htmlBody = DomToString(<section
404
- style="background-color: white; color: black;">
405
- <section contentEditable="true">
406
- {"\xa0"}
407
- <br/>
408
- </section>
409
- </section>);
410
- this.editor.htmlContent = this.draft.htmlBody;
411
-
412
- this.draft.attachments.add(AppFile.create({
413
- name: "forwarded.eml",
414
- sourceEmailLogID: mimeFileID ?? signedFileLogID,
415
- contentType: "message/rfc822"
416
- }));
417
- await this.save(true);
418
- }
412
+ // @Action({ onEvent: CommonEvents.onEmailForward})
413
+ // async onForwardEmail(mce: IMailboxContactEmail) {
414
+ // if (this.draft?.emailID) {
415
+ // await this.save(true);
416
+ // this.draft = null;
417
+ // }
418
+ // this.ensureDraft();
419
+ // const { email } = mce;
420
+ // const { recipients } = email;
421
+ // const to = recipients?.filter((x) => x.type === "to");
422
+ // const cc = recipients?.filter((x) => x.type === "cc");
423
+ // this.draft.htmlBody = DomToString(
424
+ // <section
425
+ // style="background-color: white; color: black;">
426
+ // <section contentEditable="true">
427
+ // {"\xa0"}
428
+ // <br/>
429
+ // </section>
430
+ // <blockquote
431
+ // contentEditable="false"
432
+ // data-type="forwarded"
433
+ // style="margin-inline-start: 20px; margin-inline-end: 0; border-left: solid 1px lightgray; padding-left: 10px;">
434
+ // <summary><div>From: ${email.senderName} {`<${email.senderEmail.emailAddress}>`}</div>
435
+ // <div>
436
+ // { to?.length && <div>
437
+ // <label style="margin-right:10px;">To:</label>
438
+ // { ... to.map((x) => <EmailLabel recipient={x} />) }
439
+ // </div> }
440
+ // { cc?.length && <div>
441
+ // <label style="margin-right:10px;">CC:</label>
442
+ // { ... cc.map((x) => <EmailLabel recipient={x} />) }
443
+ // </div>}
444
+ // <div>
445
+ // <label style="margin-right:10px;">Subject:</label>
446
+ // <label>{email.subject}</label>
447
+ // </div>
448
+ // <div data-type="html-body">
449
+ // {email.htmlBody}
450
+ // </div>
451
+ // </div>
452
+ // </summary>
453
+ // </blockquote>
454
+ // <footer data-social-mail-commands="emoji-bar">
455
+ // </footer>
456
+ // </section>);
457
+
458
+ // // copy all attachments..
459
+ // this.editor.htmlContent = this.draft.htmlBody;
460
+
461
+ // const attachments = mce.email.attachments;
462
+ // if (attachments) {
463
+ // for (const iterator of attachments) {
464
+ // this.draft.attachments.add(AppFile.create({
465
+ // ... iterator,
466
+ // appFileID: void 0,
467
+ // }));
468
+ // }
469
+ // }
470
+ // await this.save(!!attachments);
471
+ // }
472
+
473
+ // @Action({ onEvent: CommonEvents.onEmailForwardAsAttachment})
474
+ // async onForwardEmailAsAttachment(mce: IMailboxContactEmail) {
475
+ // if (this.draft?.emailID) {
476
+ // await this.save(true);
477
+ // this.draft = null;
478
+ // }
479
+ // this.ensureDraft();
480
+ // const { email, signedFileLogID } = mce;
481
+ // const { mimeFileID } = email;
482
+
483
+ // this.draft.htmlBody = DomToString(<section
484
+ // style="background-color: white; color: black;">
485
+ // <section contentEditable="true">
486
+ // {"\xa0"}
487
+ // <br/>
488
+ // </section>
489
+ // </section>);
490
+ // this.editor.htmlContent = this.draft.htmlBody;
491
+
492
+ // this.draft.attachments.add(AppFile.create({
493
+ // name: "forwarded.eml",
494
+ // sourceEmailLogID: mimeFileID ?? signedFileLogID,
495
+ // contentType: "message/rfc822"
496
+ // }));
497
+ // await this.save(true);
498
+ // }
419
499
 
420
500
  @Action({
421
501
  onEvent: "send-email"
@@ -440,6 +520,7 @@ export default class MiniComposeBox extends AtomControl {
440
520
  const saved = this.draft;
441
521
  this.draft = Email.create({
442
522
  subject: "",
523
+ senderID: this.senderID,
443
524
  htmlBody: defaultEmailBody,
444
525
  attachments: []
445
526
  });
@@ -455,6 +536,23 @@ export default class MiniComposeBox extends AtomControl {
455
536
  await this.addFiles(uploadedFile);
456
537
  }
457
538
 
539
+ async save(saveAttachments = true) {
540
+ const { prevSave, saveCancelToken } = this;
541
+ saveCancelToken?.cancel();
542
+ const ct = this.saveCancelToken = new CancelToken();
543
+ this.prevSave = (async () => {
544
+ try {
545
+ if (prevSave) {
546
+ await prevSave;
547
+ }
548
+ this.draft.senderID = this.senderID;
549
+ this.draft = await this.conversationService.draft(this.draft, this.mailboxContacts , true, saveAttachments, ct);
550
+ } catch {
551
+ // ignore...
552
+ }
553
+ })().catch(console.error);
554
+ }
555
+
458
556
  private async addFiles(... files: IUploadedFile[]) {
459
557
  this.ensureDraft();
460
558
  const attachments = this.draft.attachments;
@@ -477,25 +575,25 @@ export default class MiniComposeBox extends AtomControl {
477
575
  private ensureDraft() {
478
576
  this.draft ??= Email.create({
479
577
  subject: "",
578
+ senderID: this.senderID,
480
579
  attachments: []
481
580
  });
482
581
  this.draft.attachments ??= [];
483
- }
484
582
 
485
- private async save(saveAttachments = true) {
486
- const { prevSave, saveCancelToken } = this;
487
- saveCancelToken?.cancel();
488
- const ct = this.saveCancelToken = new CancelToken();
489
- this.prevSave = (async () => {
490
- try {
491
- if (prevSave) {
492
- await prevSave;
583
+ // populate recipients
584
+ if (!this.draft.recipients) {
585
+ const recipients = this.draft.recipients = [] as IEmailRecipient[];
586
+ for (const iterator of this.mailboxContacts) {
587
+ if (recipients.some((x) => x.emailAddressID === iterator.emailAddressID)) {
588
+ continue;
493
589
  }
494
- this.draft = await this.conversationService.draft({ ... this.mailboxContact, email: this.draft }, true, saveAttachments, ct);
495
- } catch {
496
- // ignore...
590
+ recipients.push(EmailRecipient.create({
591
+ emailAddressID: iterator.emailAddressID,
592
+ emailAddressText: iterator.emailAddress?.emailAddress ?? "",
593
+ type: "to"
594
+ }));
497
595
  }
498
- })().catch(console.error);
596
+ }
499
597
  }
500
598
 
501
599
  }
@@ -0,0 +1,128 @@
1
+ import { PopupWindowPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
2
+ import { AppFile, Email, IAppFile, IMailboxContactEmail } from "../../../../model/model";
3
+ import DomToString from "@web-atoms/email-dom/dist/DomToString";
4
+ import XNode from "@web-atoms/core/dist/core/XNode";
5
+ import EmailLabel from "../../../../common/controls/email-recipients/EmailLabel";
6
+ import MiniComposeBox from "./MiniComposeBox";
7
+ import Bind from "@web-atoms/core/dist/core/Bind";
8
+ import { EmailIconTextButton, SaveIconTextButton } from "../../../../common/controls/buttons/IconButton";
9
+ import Action from "@web-atoms/core/dist/view-model/Action";
10
+
11
+ export default class MiniComposePage extends PopupWindowPage<{ thread: IMailboxContactEmail, asAttachment: boolean }> {
12
+
13
+ composer: MiniComposeBox;
14
+
15
+ async init() {
16
+
17
+ const { htmlBody, attachments } = this.prepareEmail();
18
+
19
+ const draft = Email.create({
20
+ senderID: this.parameters.thread.mailboxID,
21
+ htmlBody,
22
+ attachments
23
+ });
24
+
25
+ this.renderer = <div>
26
+ <MiniComposeBox
27
+ senderID={this.parameters.thread.mailboxID}
28
+ draft={draft}
29
+ to={[]}
30
+ mailboxContacts={[]}
31
+ presenter={Bind.presenter((c) => this.composer = c)}
32
+ showSendButton={false}
33
+ showTo={true}
34
+ />
35
+ <div data-layout="command-row">
36
+ <EmailIconTextButton
37
+ event-click={() => this.save(true)}
38
+ text="Send"
39
+ />
40
+ <SaveIconTextButton
41
+ event-click={() => this.save()}
42
+ />
43
+ </div>
44
+ </div>;
45
+
46
+ }
47
+
48
+ @Action({ close: true })
49
+ async save(send = false) {
50
+ if (send) {
51
+ await this.composer.sendEmail();
52
+ return send;
53
+ }
54
+ await this.composer.save(true);
55
+ return send;
56
+ }
57
+
58
+ prepareEmail () {
59
+
60
+ this.title = "Forward";
61
+
62
+ let htmlBody;
63
+ let attachments = [] as IAppFile[];
64
+
65
+ const { thread: { email, signedFileLogID }, asAttachment } = this.parameters;
66
+ const { mimeFileID } = email;
67
+
68
+ if (asAttachment) {
69
+ htmlBody = DomToString(<section
70
+ style="background-color: white; color: black;">
71
+ <section contentEditable="true">
72
+ {"\xa0"}
73
+ <br/>
74
+ </section>
75
+ </section>);
76
+
77
+ attachments = [AppFile.create({
78
+ name: "forwarded.eml",
79
+ sourceEmailLogID: mimeFileID ?? signedFileLogID,
80
+ contentType: "message/rfc822"
81
+ })];
82
+ } else {
83
+ const { recipients } = email;
84
+ const to = recipients?.filter((x) => x.type === "to");
85
+ const cc = recipients?.filter((x) => x.type === "cc");
86
+ htmlBody = DomToString(
87
+ <section
88
+ style="background-color: white; color: black;">
89
+ <section contentEditable="true">
90
+ {"\xa0"}
91
+ <br/>
92
+ </section>
93
+ <blockquote
94
+ contentEditable="false"
95
+ data-type="forwarded"
96
+ style="margin-inline-start: 20px; margin-inline-end: 0; border-left: solid 1px lightgray; padding-left: 10px;">
97
+ <summary><div>From: {email.senderName} {`<${email.senderEmail.emailAddress}>`}</div>
98
+ <div>
99
+ { (to?.length) > 0 && <div>
100
+ <label style="margin-right:10px;">To:</label>
101
+ { ... to.map((x) => <EmailLabel recipient={x} />) }
102
+ </div> }
103
+ { (cc?.length > 0) && <div>
104
+ <label style="margin-right:10px;">CC:</label>
105
+ { ... cc.map((x) => <EmailLabel recipient={x} />) }
106
+ </div>}
107
+ <div>
108
+ <label style="margin-right:10px;">Subject:</label>
109
+ <label>{email.subject}</label>
110
+ </div>
111
+ <div data-type="html-body">
112
+ <div innerHTML={email.htmlBody}></div>
113
+ </div>
114
+ </div>
115
+ </summary>
116
+ </blockquote>
117
+ <footer data-social-mail-commands="emoji-bar">
118
+ </footer>
119
+ </section>);
120
+
121
+ attachments = email.attachments?.map((x) => AppFile.create({ ... x, appFileID: void 0}));
122
+
123
+ return { htmlBody, attachments };
124
+ }
125
+
126
+ }
127
+
128
+ }