@go-mailer/easy-email-extensions 5.0.7 → 5.0.8

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.
@@ -1,5 +1,6 @@
1
1
  import { IBlockData } from '@go-mailer/easy-email-core';
2
2
  export declare const CountdownBlockType = "go-mailer-countdown";
3
+ export declare const COUNTDOWN_API_URL = "http://localhost:4010/images/countdown";
3
4
  export type ICountdownBlock = IBlockData<{
4
5
  endDate: string;
5
6
  timezone: string;
@@ -11,7 +12,9 @@ export type ICountdownBlock = IBlockData<{
11
12
  height: string;
12
13
  link: string;
13
14
  'container-background-color': string;
15
+ /** Cached GIF URL returned by the countdown API — used in the render. */
16
+ gifUrl: string;
14
17
  }, Record<string, never>>;
15
- /** Build the Sendtric animated GIF URL from block attributes. */
16
- export declare function buildCountdownUrl(attrs: ICountdownBlock['attributes']): string;
18
+ /** POST to the countdown API and return the GIF URL. */
19
+ export declare function fetchCountdownGif(endDate: string): Promise<string>;
17
20
  export declare const CountdownBlock: import("@go-mailer/easy-email-core").IBlock<ICountdownBlock>;
package/lib/index2.js CHANGED
@@ -34390,6 +34390,8 @@ function ImageUploader(props) {
34390
34390
  const [isUploading, setIsUploading] = useState(false);
34391
34391
  const uploadHandlerRef = useRef(props.uploadHandler);
34392
34392
  const onChange = props.onChange;
34393
+ const valueRef = useRef(props.value);
34394
+ valueRef.current = props.value;
34393
34395
  const onUpload = useCallback(() => {
34394
34396
  if (isUploading) {
34395
34397
  return Message$1.warning(t("Uploading..."));
@@ -34417,12 +34419,12 @@ function ImageUploader(props) {
34417
34419
  if (!props.autoTrigger || !uploadHandlerRef.current)
34418
34420
  return;
34419
34421
  const handler = () => {
34420
- if (!props.value)
34422
+ if (!valueRef.current)
34421
34423
  onUpload();
34422
34424
  };
34423
34425
  EventManager.on(EventType.BLOCK_CLICK, handler);
34424
34426
  return () => EventManager.off(EventType.BLOCK_CLICK, handler);
34425
- }, [props.autoTrigger, props.value, onUpload]);
34427
+ }, [props.autoTrigger, onUpload]);
34426
34428
  const onPaste = useCallback(
34427
34429
  (e2) => __async(this, null, function* () {
34428
34430
  if (!uploadHandlerRef.current)
@@ -39418,9 +39420,19 @@ const fullWidthOnMobileAdapter = {
39418
39420
  return "true";
39419
39421
  }
39420
39422
  };
39421
- function Image$3() {
39423
+ function Image$2() {
39424
+ var _a2;
39422
39425
  const { focusIdx: focusIdx2 } = useFocusIdx();
39423
39426
  const { onUploadImage } = useEditorProps();
39427
+ const { focusBlock: focusBlock2, change } = useBlock();
39428
+ const src = (_a2 = focusBlock2 == null ? void 0 : focusBlock2.attributes) == null ? void 0 : _a2.src;
39429
+ const prevSrcRef = React__default.useRef(src);
39430
+ React__default.useEffect(() => {
39431
+ if (src && src !== prevSrcRef.current) {
39432
+ change(`${focusIdx2}.attributes.height`, "auto");
39433
+ }
39434
+ prevSrcRef.current = src;
39435
+ }, [src, focusIdx2, change]);
39424
39436
  return /* @__PURE__ */ React__default.createElement(AttributesPanelWrapper, {
39425
39437
  style: { padding: 0 }
39426
39438
  }, /* @__PURE__ */ React__default.createElement(CollapseWrapper, {
@@ -40472,7 +40484,7 @@ const blocks = {
40472
40484
  [BasicType.SECTION]: Section,
40473
40485
  [BasicType.COLUMN]: Column,
40474
40486
  [BasicType.TEXT]: Text,
40475
- [BasicType.IMAGE]: Image$3,
40487
+ [BasicType.IMAGE]: Image$2,
40476
40488
  [BasicType.GROUP]: Group,
40477
40489
  [BasicType.BUTTON]: Button,
40478
40490
  [BasicType.DIVIDER]: Divider,
@@ -40489,7 +40501,7 @@ const blocks = {
40489
40501
  [BasicType.SOCIAL]: Social,
40490
40502
  [BasicType.TABLE]: Table,
40491
40503
  [AdvancedType.TEXT]: Text,
40492
- [AdvancedType.IMAGE]: Image$3,
40504
+ [AdvancedType.IMAGE]: Image$2,
40493
40505
  [AdvancedType.BUTTON]: Button,
40494
40506
  [AdvancedType.DIVIDER]: Divider,
40495
40507
  [AdvancedType.SPACER]: Spacer,
@@ -42715,7 +42727,7 @@ function getDirectionFormDropPosition(position) {
42715
42727
  return "bottom";
42716
42728
  return "";
42717
42729
  }
42718
- const { Image: Image$2 } = components;
42730
+ const { Image: Image$1 } = components;
42719
42731
  const VideoBlockType = "go-mailer-video";
42720
42732
  const VIDEO_PLACEHOLDER_SRC = `data:image/svg+xml,${encodeURIComponent(
42721
42733
  `<svg xmlns="http://www.w3.org/2000/svg" width="600" height="100" viewBox="0 0 600 100">
@@ -42750,7 +42762,7 @@ const VideoBlock = createCustomBlock({
42750
42762
  render: ({ data, idx, mode }) => {
42751
42763
  const { src, href, width, height } = data.attributes;
42752
42764
  const effectiveSrc = mode === "testing" && !src ? VIDEO_PLACEHOLDER_SRC : src;
42753
- return /* @__PURE__ */ React__default.createElement(Image$2, {
42765
+ return /* @__PURE__ */ React__default.createElement(Image$1, {
42754
42766
  "css-class": mode === "testing" ? getPreviewClassName(idx, data.type) : "",
42755
42767
  src: effectiveSrc,
42756
42768
  href: href || void 0,
@@ -42763,88 +42775,6 @@ const VideoBlock = createCustomBlock({
42763
42775
  });
42764
42776
  }
42765
42777
  });
42766
- const { Image: Image$1 } = components;
42767
- const CountdownBlockType = "go-mailer-countdown";
42768
- function buildCountdownUrl(attrs) {
42769
- const { endDate, timezone, backgroundColor, textColor, fontSize, format } = attrs;
42770
- if (!endDate)
42771
- return "";
42772
- const d2 = new Date(endDate);
42773
- if (isNaN(d2.getTime()))
42774
- return "";
42775
- const params = new URLSearchParams({
42776
- language: "en",
42777
- timezone,
42778
- year: String(d2.getFullYear()),
42779
- month: String(d2.getMonth() + 1),
42780
- day: String(d2.getDate()),
42781
- hour: String(d2.getHours()),
42782
- minute: String(d2.getMinutes()),
42783
- second: String(d2.getSeconds()),
42784
- textcolor: textColor.replace("#", ""),
42785
- bg: backgroundColor.replace("#", ""),
42786
- size: String(fontSize),
42787
- format
42788
- });
42789
- return `https://www.sendtric.com/countdown/image?${params.toString()}`;
42790
- }
42791
- function defaultEndDate() {
42792
- const d2 = new Date();
42793
- d2.setDate(d2.getDate() + 7);
42794
- d2.setSeconds(0, 0);
42795
- return d2.toISOString().slice(0, 16);
42796
- }
42797
- const COUNTDOWN_PLACEHOLDER_SRC = `data:image/svg+xml,${encodeURIComponent(
42798
- `<svg xmlns="http://www.w3.org/2000/svg" width="600" height="100" viewBox="0 0 600 100">
42799
- <rect width="600" height="100" fill="#f4f2ef"/>
42800
- <rect x="1" y="1" width="598" height="98" rx="4" fill="none" stroke="#dedad6" stroke-width="1.5" stroke-dasharray="8 4"/>
42801
- <g transform="translate(278,26)">
42802
- <rect width="44" height="32" rx="3" fill="none" stroke="#c8c4c0" stroke-width="1.5"/>
42803
- <text x="22" y="21" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#c8c4c0">00</text>
42804
- </g>
42805
- <text x="300" y="72" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" font-weight="500" fill="#b5b1ac">Set a deadline to activate countdown</text>
42806
- </svg>`
42807
- )}`;
42808
- const CountdownBlock = createCustomBlock({
42809
- name: "Countdown",
42810
- type: CountdownBlockType,
42811
- validParentType: [BasicType.COLUMN, "advanced_column"],
42812
- create: (payload) => {
42813
- const defaultData = {
42814
- type: CountdownBlockType,
42815
- data: { value: {} },
42816
- attributes: {
42817
- endDate: defaultEndDate(),
42818
- timezone: "UTC",
42819
- backgroundColor: "ffffff",
42820
- textColor: "333333",
42821
- fontSize: "30",
42822
- format: "DHMS",
42823
- width: "600px",
42824
- height: "100px",
42825
- link: "",
42826
- "container-background-color": "#ffffff"
42827
- },
42828
- children: []
42829
- };
42830
- return mergeBlock(defaultData, payload);
42831
- },
42832
- render: ({ data, idx, mode }) => {
42833
- const attrs = data.attributes;
42834
- const effectiveSrc = mode === "testing" ? COUNTDOWN_PLACEHOLDER_SRC : buildCountdownUrl(attrs) || "";
42835
- return /* @__PURE__ */ React__default.createElement(Image$1, {
42836
- "css-class": mode === "testing" ? getPreviewClassName(idx, data.type) : "",
42837
- src: effectiveSrc,
42838
- href: attrs.link || void 0,
42839
- target: "_blank",
42840
- width: attrs.width,
42841
- height: attrs.height || void 0,
42842
- padding: "0px",
42843
- align: "center",
42844
- "container-background-color": attrs["container-background-color"]
42845
- });
42846
- }
42847
- });
42848
42778
  let iconsMap = {
42849
42779
  [BasicType.TEXT]: "icon-text",
42850
42780
  [BasicType.SECTION]: "icon-section",
@@ -42875,8 +42805,7 @@ let iconsMap = {
42875
42805
  [AdvancedType.COLUMN]: "icon-column",
42876
42806
  [AdvancedType.GROUP]: "icon-group",
42877
42807
  [AdvancedType.HERO]: "icon-hero",
42878
- [VideoBlockType]: "icon-img",
42879
- [CountdownBlockType]: "icon-number"
42808
+ [VideoBlockType]: "icon-img"
42880
42809
  };
42881
42810
  function getIconNameByBlockType(type) {
42882
42811
  return lodash.exports.get(iconsMap, type) || "icon-number";
@@ -47072,29 +47001,6 @@ const SvgAccordion = () => /* @__PURE__ */ React__default.createElement("svg", {
47072
47001
  strokeLinecap: "round",
47073
47002
  strokeLinejoin: "round"
47074
47003
  }));
47075
- const SvgCountdown = () => /* @__PURE__ */ React__default.createElement("svg", {
47076
- width: "18",
47077
- height: "18",
47078
- viewBox: "0 0 18 18",
47079
- fill: "none"
47080
- }, /* @__PURE__ */ React__default.createElement("circle", {
47081
- cx: "9",
47082
- cy: "10",
47083
- r: "6.5",
47084
- stroke: "currentColor",
47085
- strokeWidth: "1.4"
47086
- }), /* @__PURE__ */ React__default.createElement("path", {
47087
- d: "M9 7v3.5l2.5 1.5",
47088
- stroke: "currentColor",
47089
- strokeWidth: "1.4",
47090
- strokeLinecap: "round",
47091
- strokeLinejoin: "round"
47092
- }), /* @__PURE__ */ React__default.createElement("path", {
47093
- d: "M6.5 2.5h5",
47094
- stroke: "currentColor",
47095
- strokeWidth: "1.4",
47096
- strokeLinecap: "round"
47097
- }));
47098
47004
  const SvgVideo = () => /* @__PURE__ */ React__default.createElement("svg", {
47099
47005
  width: "18",
47100
47006
  height: "18",
@@ -47168,8 +47074,7 @@ const SVG_ICON_MAP = {
47168
47074
  [AdvancedType.ACCORDION]: SvgAccordion,
47169
47075
  [BasicType.SECTION]: SvgSection,
47170
47076
  [AdvancedType.SECTION]: SvgSection,
47171
- "go-mailer-video": SvgVideo,
47172
- "go-mailer-countdown": SvgCountdown
47077
+ "go-mailer-video": SvgVideo
47173
47078
  };
47174
47079
  function BlockSvgIcon({ type }) {
47175
47080
  var _a2;
@@ -53357,8 +53262,18 @@ const presetBlocks = [
53357
53262
  })
53358
53263
  ];
53359
53264
  function VideoPanel() {
53265
+ var _a2;
53360
53266
  const { focusIdx: focusIdx2 } = useFocusIdx();
53361
53267
  const { onUploadImage } = useEditorProps();
53268
+ const { focusBlock: focusBlock2, change } = useBlock();
53269
+ const src = (_a2 = focusBlock2 == null ? void 0 : focusBlock2.attributes) == null ? void 0 : _a2.src;
53270
+ const prevSrcRef = React__default.useRef(src);
53271
+ React__default.useEffect(() => {
53272
+ if (src && src !== prevSrcRef.current) {
53273
+ change(`${focusIdx2}.attributes.height`, "auto");
53274
+ }
53275
+ prevSrcRef.current = src;
53276
+ }, [src, focusIdx2, change]);
53362
53277
  return /* @__PURE__ */ React__default.createElement(AttributesPanelWrapper, {
53363
53278
  style: { padding: 0 }
53364
53279
  }, /* @__PURE__ */ React__default.createElement(CollapseWrapper, {
@@ -53402,109 +53317,9 @@ function VideoPanel() {
53402
53317
  )
53403
53318
  })))));
53404
53319
  }
53405
- const TIMEZONE_OPTIONS = [
53406
- "UTC",
53407
- "America/New_York",
53408
- "America/Chicago",
53409
- "America/Denver",
53410
- "America/Los_Angeles",
53411
- "America/Toronto",
53412
- "America/Vancouver",
53413
- "America/Sao_Paulo",
53414
- "Europe/London",
53415
- "Europe/Paris",
53416
- "Europe/Berlin",
53417
- "Europe/Moscow",
53418
- "Asia/Dubai",
53419
- "Asia/Kolkata",
53420
- "Asia/Singapore",
53421
- "Asia/Tokyo",
53422
- "Asia/Shanghai",
53423
- "Australia/Sydney"
53424
- ].map((tz) => ({ label: tz, value: tz }));
53425
- const FORMAT_OPTIONS = [
53426
- { label: "Days \xB7 Hours \xB7 Minutes \xB7 Seconds", value: "DHMS" },
53427
- { label: "Hours \xB7 Minutes \xB7 Seconds", value: "HMS" },
53428
- { label: "Minutes \xB7 Seconds", value: "MS" }
53429
- ];
53430
- function DateTimeField({ name: name2 }) {
53431
- const { input: input2 } = useField(name2, { parse: (v2) => v2 });
53432
- return /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement("label", {
53433
- style: { fontSize: 11, fontWeight: 500, color: "#6b6660", display: "block", marginBottom: 3 }
53434
- }, "End date & time"), /* @__PURE__ */ React__default.createElement("input", {
53435
- type: "datetime-local",
53436
- value: input2.value || "",
53437
- onChange: (e2) => input2.onChange(e2.target.value),
53438
- style: {
53439
- width: "100%",
53440
- height: 32,
53441
- padding: "0 8px",
53442
- border: "1px solid rgba(26,24,20,0.14)",
53443
- borderRadius: 7,
53444
- fontSize: 13,
53445
- background: "#f7f5f2",
53446
- color: "#1a1814",
53447
- boxSizing: "border-box",
53448
- outline: "none"
53449
- }
53450
- }));
53451
- }
53452
- function CountdownPanel() {
53453
- const { focusIdx: focusIdx2 } = useFocusIdx();
53454
- return /* @__PURE__ */ React__default.createElement(AttributesPanelWrapper, {
53455
- style: { padding: 0 }
53456
- }, /* @__PURE__ */ React__default.createElement(CollapseWrapper, {
53457
- defaultActiveKey: ["schedule", "style", "dimension", "link"]
53458
- }, /* @__PURE__ */ React__default.createElement(Collapse$1.Item, {
53459
- name: "schedule",
53460
- header: t("Schedule")
53461
- }, /* @__PURE__ */ React__default.createElement(Space$1, {
53462
- direction: "vertical"
53463
- }, /* @__PURE__ */ React__default.createElement(DateTimeField, {
53464
- name: `${focusIdx2}.attributes.endDate`
53465
- }), /* @__PURE__ */ React__default.createElement(SelectField, {
53466
- label: t("Timezone"),
53467
- name: `${focusIdx2}.attributes.timezone`,
53468
- options: TIMEZONE_OPTIONS
53469
- }), /* @__PURE__ */ React__default.createElement(SelectField, {
53470
- label: t("Format"),
53471
- name: `${focusIdx2}.attributes.format`,
53472
- options: FORMAT_OPTIONS
53473
- }))), /* @__PURE__ */ React__default.createElement(Collapse$1.Item, {
53474
- name: "style",
53475
- header: t("Style")
53476
- }, /* @__PURE__ */ React__default.createElement(Space$1, {
53477
- direction: "vertical"
53478
- }, /* @__PURE__ */ React__default.createElement(ColorPickerField, {
53479
- label: t("Background"),
53480
- name: `${focusIdx2}.attributes.backgroundColor`
53481
- }), /* @__PURE__ */ React__default.createElement(ColorPickerField, {
53482
- label: t("Text color"),
53483
- name: `${focusIdx2}.attributes.textColor`
53484
- }))), /* @__PURE__ */ React__default.createElement(Collapse$1.Item, {
53485
- name: "dimension",
53486
- header: t("Dimension")
53487
- }, /* @__PURE__ */ React__default.createElement(Space$1, {
53488
- direction: "vertical"
53489
- }, /* @__PURE__ */ React__default.createElement(Width, {
53490
- pixelMode: true
53491
- }), /* @__PURE__ */ React__default.createElement(Height, null), /* @__PURE__ */ React__default.createElement(Padding, {
53492
- showResetAll: true
53493
- }))), /* @__PURE__ */ React__default.createElement(Collapse$1.Item, {
53494
- name: "link",
53495
- header: t("Link")
53496
- }, /* @__PURE__ */ React__default.createElement(TextField, {
53497
- label: t("Click URL"),
53498
- name: `${focusIdx2}.attributes.link`,
53499
- placeholder: "https://",
53500
- helpText: t("Where to send recipients when they click the countdown.")
53501
- }))));
53502
- }
53503
53320
  const FONT = "'Inter', 'DM Sans', -apple-system, sans-serif";
53504
53321
  BlockManager.registerBlocks({ [VideoBlockType]: VideoBlock });
53505
53322
  BlockAttributeConfigurationManager.add({ [VideoBlockType]: VideoPanel });
53506
- BlockManager.registerBlocks({ [CountdownBlockType]: CountdownBlock });
53507
- BlockAttributeConfigurationManager.add({ [CountdownBlockType]: CountdownPanel });
53508
53323
  const IcoEdit = () => /* @__PURE__ */ React__default.createElement("svg", {
53509
53324
  width: "14",
53510
53325
  height: "14",
@@ -53611,8 +53426,7 @@ const defaultCategories = [
53611
53426
  { type: AdvancedType.WRAPPER },
53612
53427
  { type: AdvancedType.NAVBAR },
53613
53428
  { type: AdvancedType.ACCORDION },
53614
- { type: VideoBlockType },
53615
- { type: CountdownBlockType }
53429
+ { type: VideoBlockType }
53616
53430
  ]
53617
53431
  },
53618
53432
  {