@social-mail/social-mail-client 1.2.5 → 1.2.7

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 (39) hide show
  1. package/dist/admin/AdminAppIndex.pack.js +60 -11
  2. package/dist/admin/AdminAppIndex.pack.js.map +1 -1
  3. package/dist/admin/AdminAppIndex.pack.min.js +5 -5
  4. package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
  5. package/dist/common/events/CommonEvents.d.ts +2 -1
  6. package/dist/common/events/CommonEvents.d.ts.map +1 -1
  7. package/dist/common/events/CommonEvents.js +2 -1
  8. package/dist/common/events/CommonEvents.js.map +1 -1
  9. package/dist/tsconfig.tsbuildinfo +1 -1
  10. package/dist/web/AppIndex.pack.js +60 -11
  11. package/dist/web/AppIndex.pack.js.map +1 -1
  12. package/dist/web/AppIndex.pack.min.js +5 -5
  13. package/dist/web/AppIndex.pack.min.js.map +1 -1
  14. package/dist/web/page/mails/ConversationPage.d.ts +1 -1
  15. package/dist/web/page/mails/ConversationPage.d.ts.map +1 -1
  16. package/dist/web/page/mails/ConversationPage.js +12 -5
  17. package/dist/web/page/mails/ConversationPage.js.map +1 -1
  18. package/dist/web/page/mails/MiniComposeBox.d.ts +4 -2
  19. package/dist/web/page/mails/MiniComposeBox.d.ts.map +1 -1
  20. package/dist/web/page/mails/MiniComposeBox.js +35 -5
  21. package/dist/web/page/mails/MiniComposeBox.js.map +1 -1
  22. package/dist/web/page/mails/service/ConversationService.d.ts +1 -0
  23. package/dist/web/page/mails/service/ConversationService.d.ts.map +1 -1
  24. package/dist/web/page/mails/service/ConversationService.js +11 -0
  25. package/dist/web/page/mails/service/ConversationService.js.map +1 -1
  26. package/index.js +0 -1
  27. package/node_modules/@web-atoms/web-controls/dist/dev/DevHost.d.ts +35 -0
  28. package/node_modules/@web-atoms/web-controls/dist/dev/DevHost.d.ts.map +1 -0
  29. package/node_modules/@web-atoms/web-controls/dist/dev/DevHost.js +203 -0
  30. package/node_modules/@web-atoms/web-controls/dist/dev/DevHost.js.map +1 -0
  31. package/node_modules/@web-atoms/web-controls/dist/tsconfig.tsbuildinfo +1 -1
  32. package/node_modules/@web-atoms/web-controls/index.js +89 -0
  33. package/node_modules/@web-atoms/web-controls/package.json +1 -1
  34. package/node_modules/@web-atoms/web-controls/src/dev/DevHost.tsx +222 -0
  35. package/package.json +2 -2
  36. package/src/common/events/CommonEvents.ts +4 -2
  37. package/src/web/page/mails/ConversationPage.tsx +11 -6
  38. package/src/web/page/mails/MiniComposeBox.tsx +28 -4
  39. package/src/web/page/mails/service/ConversationService.tsx +8 -0
@@ -0,0 +1,89 @@
1
+ (() => {
2
+
3
+ let script = document.currentScript;
4
+ let src = script.src;
5
+ let index = src.lastIndexOf("/");
6
+ src = src.substring(0, index);
7
+
8
+ const loadScript = (url) => {
9
+ return new Promise((resolve, reject) => {
10
+ var script = document.createElement("script");
11
+ script.type = "text/javascript";
12
+ script.src = url;
13
+ var s = script;
14
+ s.onerror = function (e) {
15
+ alert(`Script ${url} failed to load`);
16
+ console.error(`${url} failed to load ${e.stack || e}`);
17
+ reject(e);
18
+ };
19
+ s.onload = s.onreadystatechange = function () {
20
+ if ((s.readyState && s.readyState !== "complete" && s.readyState !== "loaded")) {
21
+ console.error("error loading " + url);
22
+ reject(`error loading ${url}`);
23
+ return;
24
+ }
25
+ s.onload = s.onreadystatechange = null;
26
+ resolve();
27
+ s.remove();
28
+ };
29
+ document.body.appendChild(s);
30
+ });
31
+ };
32
+
33
+ const loadPackage = () => {
34
+
35
+ let package = script.getAttribute("data-package");
36
+ let packageRoot = script.getAttribute("data-package-root");
37
+ if (packageRoot === void 0 || packageRoot === null) {
38
+ packageRoot = src;
39
+ }
40
+ if (!package) {
41
+ fetch(src + "/package.json").then((x) => x.json().then((json) => {
42
+ script.setAttribute("data-package", json.name);
43
+ loadPackage();
44
+ }));
45
+ return;
46
+ }
47
+
48
+ const view = script.getAttribute("data-view");
49
+
50
+ const packed = JSON.parse(script.getAttribute("data-packed") ?? "true");
51
+ const min = JSON.parse(script.getAttribute("data-min") ?? "true");
52
+ const viewName = view.startsWith("@") ? view : `${package}/${view}`;
53
+
54
+ const init = () => {
55
+ const empty = () => () => null;
56
+
57
+ AmdLoader.moduleProgress = empty;
58
+ const done = () => {
59
+ const we = document.getElementById("webAtomsLoader");
60
+ if (we) {
61
+ we.remove();
62
+ }
63
+ };
64
+ UMD.setupRoot(package, packageRoot);
65
+ UMD.lang = "en-US";
66
+ const map = script.getAttribute("data-map");
67
+ if (map) {
68
+ try {
69
+ for (const [key, value] of JSON.parse(map)) {
70
+ UMD.map(key, value);
71
+ }
72
+ } catch (error) {
73
+ console.error(error);
74
+ }
75
+ }
76
+ UMD.loadView(viewName, 0).then(done);
77
+ }
78
+
79
+ if (!packed) {
80
+ init();
81
+ return;
82
+ }
83
+
84
+ const viewUrl = `${packageRoot}/${view}${packed ? ".pack" : ""}${min ? ".min" : ""}.js`;
85
+ loadScript(viewUrl).then(init);
86
+ };
87
+
88
+ loadPackage();
89
+ })();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@web-atoms/web-controls",
3
- "version": "2.4.6",
3
+ "version": "2.4.15",
4
4
  "description": "HTML controls for web atoms core",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,222 @@
1
+ import Bind from "@web-atoms/core/dist/core/Bind"
2
+ import XNode from "@web-atoms/core/dist/core/XNode"
3
+ import { BaseService, Get, Query } from "@web-atoms/core/dist/services/http/RestService";
4
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
5
+ import styled from "@web-atoms/core/dist/style/styled";
6
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
7
+
8
+ import "@web-atoms/data-styles/data-styles";
9
+ import { CancelToken } from "@web-atoms/core/dist/core/types";
10
+ import Action from "@web-atoms/core/dist/view-model/Action";
11
+ import DISingleton from "@web-atoms/core/dist/di/DISingleton";
12
+ import AtomRepeater from "../basic/AtomRepeater";
13
+ import ToggleButtonBar from "../basic/ToggleButtonBar";
14
+
15
+ styled.css `
16
+ :root {
17
+ --accent-color: orangered;
18
+ --accent-text-color: white;
19
+ }
20
+ html, body {
21
+ margin: 0;
22
+ padding: 0;
23
+ font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
24
+ }
25
+ `.installGlobal();
26
+
27
+ const css = styled.css `
28
+ position: absolute;
29
+ left: 0;
30
+ top: 0;
31
+ right: 0;
32
+ bottom: 0;
33
+ display: grid;
34
+ grid-template-rows: auto 1fr;
35
+ gap: 5px;
36
+
37
+ & > header {
38
+ grid-row: 1;
39
+ }
40
+ & > div {
41
+ grid-row: 2;
42
+ align-items: stretch;
43
+ justify-self: stretch;
44
+ overflow: auto;
45
+
46
+ & [data-item-index]:hover {
47
+ background-color: lightgreen;
48
+ }
49
+ }
50
+ `.installLocal();
51
+
52
+ const fileTypes = () => [
53
+ { label: "Packed", value: "packed"},
54
+ { label: "All", value: "all"}
55
+ ];
56
+
57
+ const designModes = () => [
58
+ { label: "Design", value: true },
59
+ { label: "Live", value: false }
60
+ ];
61
+
62
+ const replaceSrc = (src: string): string => {
63
+ src = src.split("\\").join("/");
64
+ const tokens = src.split("/");
65
+ if (tokens[0] === "src") {
66
+ tokens[0] = "dist";
67
+ }
68
+ return tokens.join("/");
69
+ }
70
+
71
+ const toAbsoluteUrl = (file: IFilePath, designMode?: boolean) => {
72
+ let url = `/_view/${replaceSrc(file.dir)}/${file.name}`;
73
+ if (designMode) {
74
+ if (url.indexOf("?") === -1) {
75
+ url += "?";
76
+ }
77
+ url += "&designMode=true";
78
+ }
79
+ return `${location.protocol}//${location.host}${url}`;
80
+ };
81
+
82
+ @DISingleton({})
83
+ export class FileService extends BaseService {
84
+
85
+ public async getModules(search: string, packed: boolean, cancelToken: CancelToken) {
86
+ const result = await this.getRemoteModules(search, packed, cancelToken);
87
+ return result.files;
88
+ }
89
+
90
+ @Get("/flat-modules")
91
+ private getRemoteModules(
92
+ @Query("search") search: string,
93
+ @Query("packed") packed: boolean,
94
+ ct?: CancelToken): Promise<IFilePathResult> {
95
+ return null;
96
+ }
97
+
98
+ }
99
+
100
+ export default class AppHost extends AtomControl {
101
+
102
+ public search: string = "";
103
+
104
+ public designMode = false;
105
+
106
+ public fileType = "packed";
107
+
108
+ @InjectProperty
109
+ private fileService: FileService;
110
+
111
+ public async init() {
112
+
113
+ this.render(
114
+ <div
115
+ class={css}>
116
+ <header
117
+ data-layout="row"
118
+ data-padding="auto"
119
+ class="header">
120
+ <input
121
+ type="search"
122
+ value={Bind.twoWaysImmediate(() => this.search)}
123
+ placeholder="Search...">
124
+ </input>
125
+
126
+ <span>Mode</span>
127
+ <ToggleButtonBar
128
+ items={designModes()}
129
+ value={Bind.twoWays(() => this.designMode)}
130
+ />
131
+
132
+ <ToggleButtonBar
133
+ items={fileTypes()}
134
+ value={Bind.twoWays(() => this.fileType)}
135
+ />
136
+ </header>
137
+ <div>
138
+ <AtomRepeater
139
+ class="grid"
140
+ items={Bind.oneWayAsync((x, e, cancelToken) =>
141
+ this.getModules(this.search, this.fileType === "packed", cancelToken))}
142
+ for="table"
143
+ itemRenderer={(item: IFilePath) => <tr
144
+ template="itemTemplate">
145
+ <td>
146
+ <div
147
+ text={item.name}
148
+ title={item.dir}
149
+ style="font-weight: 500;">
150
+ </div>
151
+ <div
152
+ style="font-size: small;"
153
+ text={item.dir}>
154
+ </div>
155
+ </td>
156
+ <td>
157
+ <a
158
+ data-layout="accent-button"
159
+ data-text-decoration="none"
160
+ href={Bind.source(item, (x) => toAbsoluteUrl(x.source, this.designMode))}
161
+ target="_blank"
162
+ text="Open">
163
+ </a>
164
+ <i
165
+ class="fas fa-copy"
166
+ title="Copy Url"
167
+ style="margin: 5px; cursor: pointer;"
168
+ data-click-event="copy-url"
169
+ eventClick={() => this.copyUrl(toAbsoluteUrl(item, this.designMode))}>
170
+ </i>
171
+ </td>
172
+ </tr> } />
173
+ </div>
174
+ </div>
175
+ );
176
+ }
177
+
178
+ async getModules(search: string, packed: boolean, cancelToken: CancelToken) {
179
+ const result = await this.fileService.getModules(search, packed, cancelToken);
180
+ if (!result.length && packed) {
181
+ this.fileType = "all";
182
+ }
183
+ return result;
184
+ }
185
+
186
+ protected preCreate(): void {
187
+ super.preCreate();
188
+ (this.app).installStyleSheet({
189
+ href: "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css",
190
+ integrity: "sha256-HtsXJanqjKTc8vVQjO4YMhiqFoXkfBsjBWcX91T1jr8=",
191
+ crossOrigin: "anonymous"
192
+ });
193
+ this.runAfterInit(() => this.app.runAsync(() => this.init()));
194
+ }
195
+
196
+ @Action({ success: "Copied successfully"})
197
+ protected async copyUrl(url: string) {
198
+ await navigator.clipboard.writeText(url);
199
+ }
200
+ }
201
+ export interface IFilePath {
202
+
203
+ name: string;
204
+ base: string;
205
+ dir: string;
206
+ ext: string;
207
+ root: string;
208
+ url: string;
209
+ hostUrl?: string;
210
+ package?: string;
211
+ visible: boolean;
212
+ packed?: boolean;
213
+ module?: string;
214
+
215
+ }
216
+
217
+ export interface IFilePathResult {
218
+
219
+ files: IFilePath[];
220
+
221
+ }
222
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-client",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
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.34",
22
- "@web-atoms/web-controls": "^2.4.6",
22
+ "@web-atoms/web-controls": "^2.4.15",
23
23
  "reflect-metadata": "^0.1.13",
24
24
  "tinycolor2": "^1.6.0"
25
25
  },
@@ -1,9 +1,11 @@
1
1
  import EventScope from "@web-atoms/core/dist/core/EventScope";
2
- import { IMailboxContact, IMailboxContactEmail } from "../../model/model";
2
+ import { IEmail, IMailboxContact, IMailboxContactEmail } from "../../model/model";
3
3
 
4
4
  export const CommonEvents = {
5
5
 
6
6
  onThreadMarkedAsRead: EventScope.create<IMailboxContactEmail>(),
7
7
 
8
- onThreadMarkedAsBlocked: EventScope.create<IMailboxContact>()
8
+ onThreadMarkedAsBlocked: EventScope.create<IMailboxContact>(),
9
+
10
+ onDraftDeleted: EventScope.create<IEmail>()
9
11
  };
@@ -31,7 +31,7 @@ const itemCss = styled.css `
31
31
  border-radius: 10px;
32
32
  padding: 10px;
33
33
  margin-right: 20%;
34
- overflow: hidden;
34
+ contain: content;
35
35
  position: relative;
36
36
  background-color: canvas;
37
37
  &[data-sent=true] {
@@ -81,8 +81,6 @@ export default class ConversationPage extends ContentPage {
81
81
 
82
82
  private mails: IMailboxContactEmail[] = [];
83
83
 
84
- private draft: IEmail = null;
85
-
86
84
  private search: string = "";
87
85
  private version = 1;
88
86
 
@@ -193,11 +191,9 @@ export default class ConversationPage extends ContentPage {
193
191
  </div>
194
192
  </PopupActionButton>;
195
193
 
196
- this.draft = await this.conversationService.getDraft(this.parameters);
197
-
198
194
  this.footerRenderer = () => <MiniComposeBox
199
195
  mailboxContact={this.parameters}
200
- draft={this.draft} />;
196
+ />;
201
197
  }
202
198
 
203
199
  @Action({ onEvent: "click"})
@@ -334,4 +330,13 @@ export default class ConversationPage extends ContentPage {
334
330
  async unblockSender() {
335
331
  await this.conversationService.block(this.parameters);
336
332
  }
333
+
334
+ @Action({
335
+ onEvent: "delete-draft",
336
+ confirm: "Are you sure you want to delete this draft?"
337
+ })
338
+ async deleteDraft(mce: IMailboxContactEmail) {
339
+ await this.conversationService.delete(mce.email);
340
+ this.mails.remove(mce);
341
+ }
337
342
  }
@@ -11,6 +11,9 @@ import { IUploadedFile } from "../../../services/files/LocalFileService";
11
11
  import AtomRepeater from "@web-atoms/web-controls/dist/basic/AtomRepeater";
12
12
  import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
13
13
  import { AtomBinder } from "@web-atoms/core/dist/core/AtomBinder";
14
+ import { CommonEvents } from "../../../common/events/CommonEvents";
15
+ import MailService from "./service/MailService";
16
+ import DateTime from "@web-atoms/date-time/dist/DateTime";
14
17
 
15
18
  const css = styled.css `
16
19
  display: grid;
@@ -42,6 +45,9 @@ export default class MiniComposeBox extends AtomControl {
42
45
  @InjectProperty
43
46
  private conversationService: ConversationService;
44
47
 
48
+ @InjectProperty
49
+ private mailService: MailService;
50
+
45
51
  constructor(app, e) {
46
52
  super(app, e);
47
53
  this.element.className = css;
@@ -49,6 +55,9 @@ export default class MiniComposeBox extends AtomControl {
49
55
  }
50
56
 
51
57
  async init() {
58
+
59
+ this.draft = await this.conversationService.getDraft(this.mailboxContact);
60
+
52
61
  this.render(<div>
53
62
  <textarea
54
63
  data-element="editor"
@@ -62,7 +71,7 @@ export default class MiniComposeBox extends AtomControl {
62
71
  data-element="send"
63
72
  class="fa-solid fa-angle-double-right send"
64
73
  style-display={Bind.oneWay(() => !!this.typedMessage)}
65
- event-click={() => this.sendMessage()}
74
+ data-click-event="send-email"
66
75
  />
67
76
  <AtomRepeater
68
77
  items={Bind.oneWay(() => this.draft?.attachments)}
@@ -72,6 +81,13 @@ export default class MiniComposeBox extends AtomControl {
72
81
  </div>);
73
82
  }
74
83
 
84
+ @Action({ onEvent: CommonEvents.onDraftDeleted })
85
+ async refreshDraft() {
86
+ this.draft ??= Email.create({
87
+ attachments: []
88
+ });
89
+ }
90
+
75
91
  @Action({ onEvent: "input", defer: 500, blockMultipleExecution: true })
76
92
  async onChanged() {
77
93
  if (!this.typedMessage) {
@@ -84,12 +100,20 @@ export default class MiniComposeBox extends AtomControl {
84
100
  await this.save();
85
101
  }
86
102
 
87
- sendMessage(): any {
88
- throw new Error("Method not implemented.");
103
+ @Action({
104
+ onEvent: "send-email"
105
+ })
106
+ async sendEmail() {
107
+ this.draft.status = "scheduled";
108
+ this.draft.dateSent = DateTime.now;
109
+ await this.mailService.send(this.draft);
110
+ this.draft ??= Email.create({
111
+ attachments: []
112
+ });
89
113
  }
90
114
 
91
115
  @Action({})
92
- private async sendAudioMessage() {
116
+ async sendAudioMessage() {
93
117
  const uploadedFile = await AudioRecorder.show<IUploadedFile>();
94
118
  this.draft ??= Email.create({
95
119
  attachments: []
@@ -231,4 +231,12 @@ export default class ConversationService {
231
231
  CommonEvents.onThreadMarkedAsBlocked.dispatchEvent(thread);
232
232
  }
233
233
 
234
+ async delete(email: IEmail) {
235
+ const { emailID } = email;
236
+ await this.entityService.delete(Email.create({
237
+ emailID
238
+ }));
239
+ CommonEvents.onDraftDeleted.dispatchEvent(email);
240
+ }
241
+
234
242
  }