@orderly.network/ui-notification 2.8.10 → 2.8.11-alpha.1

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.
package/dist/index.js CHANGED
@@ -7,7 +7,6 @@ var types = require('@orderly.network/types');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var utc = require('@date-fns/utc');
9
9
  var dateFns = require('date-fns');
10
- var immer = require('immer');
11
10
  var hooks = require('@orderly.network/hooks');
12
11
  var reactApp = require('@orderly.network/react-app');
13
12
 
@@ -141,12 +140,14 @@ var AnnouncementItem = (props) => {
141
140
  return t("notification.listing");
142
141
  case types.AnnouncementType.Maintenance:
143
142
  return t("notification.maintenance");
143
+ case types.AnnouncementType.Vote:
144
+ return t("notification.vote");
144
145
  default:
145
146
  return t("notification.general");
146
147
  }
147
148
  }, [props.type, t]);
148
149
  const action = react.useMemo(() => {
149
- if (props.type === types.AnnouncementType.Campaign && typeof props.url === "string" && props.url !== "" && typeof props.onItemClick === "function") {
150
+ if ((props.type === types.AnnouncementType.Campaign || props.type === types.AnnouncementType.Vote) && typeof props.url === "string" && props.url !== "" && typeof props.onItemClick === "function") {
150
151
  return /* @__PURE__ */ jsxRuntime.jsxs(
151
152
  ui.Flex,
152
153
  {
@@ -329,29 +330,8 @@ var CampaignContentCard = ({ message, coverImage, url, onItemClick }) => {
329
330
  };
330
331
  var MaintenanceContentCard = ({ message, startTime, endTime }) => {
331
332
  const { t } = i18n.useTranslation();
332
- const formattedMessage = react.useMemo(() => {
333
- const hours = dateFns.differenceInHours(endTime, startTime);
334
- const minutes = dateFns.differenceInMinutes(endTime, startTime) - hours * 60;
335
- const startUtc = new utc.UTCDate(startTime);
336
- const endUtc = new utc.UTCDate(endTime);
337
- const startTimeFormatted = dateFns.format(startUtc, "HH:mm");
338
- const endTimeFormatted = dateFns.format(endUtc, "hh:mm a");
339
- if (hours > 0) {
340
- return t("notification.maintenanceDuration.hours", {
341
- hours: minutes > 0 ? (hours + minutes / 60).toFixed(1) : hours,
342
- startTimeFormatted,
343
- endTimeFormatted
344
- });
345
- }
346
- return t("notification.maintenanceDuration.minutes", {
347
- minutes,
348
- startTimeFormatted,
349
- endTimeFormatted
350
- });
351
- }, [startTime, endTime, t]);
352
333
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-flex-col oui-gap-1", children: [
353
334
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", intensity: 54, children: t("notification.recentlyUpdated") }),
354
- /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { itemAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", weight: "bold", children: formattedMessage }) }),
355
335
  message && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", intensity: 80, as: "div", className: "oui-mt-2", children: message })
356
336
  ] });
357
337
  };
@@ -385,6 +365,31 @@ var ListingContentCard = ({ message, updateTime }) => {
385
365
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "sm", weight: "bold", children: message })
386
366
  ] });
387
367
  };
368
+ var CommunityVoteContentCard = ({ message, url, onItemClick }) => {
369
+ const { t } = i18n.useTranslation();
370
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-flex-col oui-gap-2", children: [
371
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "sm", weight: "bold", children: message }),
372
+ typeof url === "string" && url !== "" && typeof onItemClick === "function" && /* @__PURE__ */ jsxRuntime.jsxs(
373
+ "button",
374
+ {
375
+ className: "oui-flex oui-items-center oui-gap-1",
376
+ onClick: () => onItemClick(url),
377
+ children: [
378
+ /* @__PURE__ */ jsxRuntime.jsx(
379
+ ui.Text,
380
+ {
381
+ size: "xs",
382
+ color: "buy",
383
+ className: "oui-bg-clip-text oui-text-transparent oui-gradient-brand",
384
+ children: t("notification.joinNow")
385
+ }
386
+ ),
387
+ /* @__PURE__ */ jsxRuntime.jsx(ArrowRightShortIcon, { size: 18, color: "success" })
388
+ ]
389
+ }
390
+ )
391
+ ] });
392
+ };
388
393
  var NotificationHeader = (props) => {
389
394
  const { t } = i18n.useTranslation();
390
395
  const { expanded } = props;
@@ -406,6 +411,8 @@ var NotificationHeader = (props) => {
406
411
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "sm", color: "buy", children: t("notification.listing") });
407
412
  case types.AnnouncementType.Maintenance:
408
413
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "sm", color: "warning", children: t("notification.maintenanceTitle") });
414
+ case types.AnnouncementType.Vote:
415
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "sm", color: "inherit", children: t("notification.vote") });
409
416
  default:
410
417
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "sm", color: "inherit", children: t("notification.generalTitle") });
411
418
  }
@@ -514,6 +521,15 @@ var NotificationContent = (props) => {
514
521
  updateTime: message.updated_time ?? 0
515
522
  }
516
523
  );
524
+ case types.AnnouncementType.Vote:
525
+ return /* @__PURE__ */ jsxRuntime.jsx(
526
+ CommunityVoteContentCard,
527
+ {
528
+ message: message.message,
529
+ url: message.url ?? "",
530
+ onItemClick: props.onItemClick
531
+ }
532
+ );
517
533
  default:
518
534
  return /* @__PURE__ */ jsxRuntime.jsx(
519
535
  ListingContentCard,
@@ -594,28 +610,34 @@ var getTimeString = (timestamp) => {
594
610
  const time = dateFns.format(new utc.UTCDateMini(timestamp), "h:mm aa");
595
611
  return `${time} (UTC) on ${date}`;
596
612
  };
597
- var sortDataByUpdatedTime = (ori) => {
598
- return immer.produce(ori, (draft) => {
599
- if (Array.isArray(draft.rows)) {
600
- draft.rows.sort((a, b) => {
601
- if (a.updated_time && b.updated_time) {
602
- return b.updated_time - a.updated_time;
603
- }
604
- return 0;
605
- });
613
+ var sortDataByUpdatedTime = (list) => {
614
+ return list.sort((a, b) => {
615
+ if (a.updated_time && b.updated_time) {
616
+ return b.updated_time - a.updated_time;
617
+ }
618
+ return 0;
619
+ });
620
+ };
621
+ var filterDuplicateArrayById = (list) => {
622
+ const seenIds = /* @__PURE__ */ new Set();
623
+ const newList = [];
624
+ list.forEach((item) => {
625
+ if (!seenIds.has(item.announcement_id)) {
626
+ seenIds.add(item.announcement_id);
627
+ newList.push(item);
606
628
  }
607
629
  });
630
+ return newList;
608
631
  };
609
632
  var useAnnouncementData = () => {
633
+ const { t } = i18n.useTranslation();
610
634
  const ws = hooks.useWS();
611
- const [announcementStore, setStore] = hooks.useLocalStorage(
612
- ORDERLY_ANNOUNCEMENT_KEY,
613
- {}
614
- );
615
- const [tips, setTips] = react.useState({});
635
+ const { dataAdapter } = hooks.useOrderlyContext();
636
+ const [announcementStore, setAnnouncementStore] = hooks.useLocalStorage(ORDERLY_ANNOUNCEMENT_KEY, {});
637
+ const [tips, setTips] = react.useState([]);
638
+ const [maintenances, setMaintenances] = react.useState([]);
616
639
  const [maintenanceDialogInfo, setMaintenanceDialogInfo] = react.useState();
617
640
  const { startTime, endTime, status, brokerName } = hooks.useMaintenanceStatus();
618
- const { t } = i18n.useTranslation();
619
641
  const { data: announcements } = hooks.useQuery(
620
642
  `/v2/public/announcement`,
621
643
  {
@@ -627,162 +649,100 @@ var useAnnouncementData = () => {
627
649
  );
628
650
  const getMaintentTipsContent = (brokerName2, startDate, endDate) => t("maintenance.tips.description", { brokerName: brokerName2, startDate, endDate });
629
651
  const getMaintentDialogContent = (brokerName2, endDate) => t("maintenance.dialog.description", { brokerName: brokerName2, endDate });
652
+ react.useEffect(() => {
653
+ const startDate = startTime ? getTimeString(startTime) : "-";
654
+ const endDate = endTime ? getTimeString(endTime) : "-";
655
+ const dialogContent = status === hooks.MaintenanceStatus.Maintenance ? getMaintentDialogContent(brokerName, endDate) : void 0;
656
+ setMaintenanceDialogInfo(dialogContent);
657
+ if (startTime && endTime) {
658
+ setMaintenances([
659
+ {
660
+ announcement_id: maintentanceId,
661
+ type: types.AnnouncementType.Maintenance,
662
+ startTime,
663
+ endTime,
664
+ updated_time: startTime,
665
+ message: getMaintentTipsContent(brokerName, startDate, endDate)
666
+ }
667
+ ]);
668
+ } else {
669
+ setMaintenances([]);
670
+ }
671
+ }, [startTime, endTime, status, brokerName, t]);
672
+ react.useEffect(() => {
673
+ let list = [...maintenances ?? [], ...announcements?.rows ?? []];
674
+ if (typeof dataAdapter?.announcementList === "function") {
675
+ list = dataAdapter.announcementList(list);
676
+ }
677
+ const removedDuplicateList = filterDuplicateArrayById(list);
678
+ const sortedList = sortDataByUpdatedTime(removedDuplicateList);
679
+ setTips(sortedList);
680
+ }, [maintenances, announcements, dataAdapter?.announcementList]);
681
+ react.useEffect(() => {
682
+ if (!announcements?.rows) {
683
+ return;
684
+ }
685
+ const lastUpdateTime = announcements.last_updated_time ?? 0;
686
+ const firstTipTime = tips[0]?.updated_time ?? 0;
687
+ const updatedTime = Math.max(lastUpdateTime, firstTipTime);
688
+ const closedTime = announcementStore.lastUpdateTime ?? 0;
689
+ if (closedTime < updatedTime) {
690
+ setAnnouncementStore({ show: true, lastUpdateTime: updatedTime });
691
+ }
692
+ }, [announcements, tips]);
630
693
  react.useEffect(() => {
631
694
  const unsubscribe = ws.subscribe("announcement", {
632
695
  onMessage(message) {
633
696
  if (message) {
634
697
  setTips((prev) => {
635
- return immer.produce(prev, (draft) => {
636
- if (!Array.isArray(draft.rows)) {
637
- draft.rows = [];
638
- }
639
- const idx = draft.rows.findIndex(
640
- (tip) => tip.announcement_id === message.announcement_id
641
- );
642
- if (idx !== -1) {
643
- draft.rows.splice(idx, 1);
644
- }
645
- draft.rows.push({
646
- announcement_id: message.announcement_id,
647
- message: message.message,
648
- url: message.url,
649
- i18n: message.i18n,
650
- type: message.type,
651
- updated_time: message.updated_time
652
- });
653
- });
698
+ const list = prev.filter(
699
+ (item) => item.announcement_id !== message.announcement_id
700
+ );
701
+ const newTip = {
702
+ announcement_id: message.announcement_id,
703
+ message: message.message,
704
+ url: message.url,
705
+ i18n: message.i18n,
706
+ type: message.type,
707
+ updated_time: message.updated_time
708
+ };
709
+ return [...list, newTip];
654
710
  });
655
- setStore((prev) => ({ ...prev, show: true }));
711
+ setAnnouncementStore((prev) => ({ ...prev, show: true }));
656
712
  }
657
- },
658
- onError(err) {
659
713
  }
660
714
  });
661
715
  return () => {
662
716
  unsubscribe?.();
663
717
  };
664
718
  }, [ws]);
665
- react.useEffect(() => {
666
- if (!announcements?.rows) {
667
- return;
668
- }
669
- const apiTime = announcements.last_updated_time ?? 0;
670
- const cachedTime = announcementStore.lastUpdateTime ?? 0;
671
- if (cachedTime < apiTime) {
672
- setTips((prev) => ({ ...prev, rows: announcements?.rows }));
673
- setStore({ show: true, lastUpdateTime: apiTime });
674
- } else {
675
- setTips((prev) => {
676
- return immer.produce(prev, (draft) => {
677
- if (announcements?.rows?.length) {
678
- const existingIds = new Set(
679
- prev.rows?.map((tip) => tip.announcement_id)
680
- );
681
- const maintenanceTip = prev.rows?.find(
682
- (tip) => tip.announcement_id === maintentanceId
683
- );
684
- draft.rows = [];
685
- announcements.rows.forEach((item) => {
686
- if (!existingIds.has(item.announcement_id)) {
687
- draft.rows?.push(item);
688
- }
689
- });
690
- if (maintenanceTip) {
691
- draft.rows.unshift(maintenanceTip);
692
- }
693
- } else {
694
- const idx = draft.rows?.findIndex(
695
- (tip) => tip.announcement_id === maintentanceId
696
- );
697
- if (idx !== void 0 && idx !== -1) {
698
- draft.rows?.splice(idx, 1);
699
- }
700
- }
701
- });
702
- });
703
- }
704
- }, [announcements]);
705
- react.useEffect(() => {
706
- const startDate = startTime ? getTimeString(startTime) : "-";
707
- const endDate = endTime ? getTimeString(endTime) : "-";
708
- if (status === hooks.MaintenanceStatus.Maintenance) {
709
- setMaintenanceDialogInfo(getMaintentDialogContent(brokerName, endDate));
710
- return;
711
- }
712
- setMaintenanceDialogInfo(void 0);
713
- if (startTime && endTime) {
714
- setTips(
715
- (prev) => immer.produce(prev, (draft) => {
716
- if (!Array.isArray(draft.rows)) {
717
- draft.rows = [];
718
- }
719
- draft.rows = [
720
- {
721
- announcement_id: maintentanceId,
722
- type: types.AnnouncementType.Maintenance,
723
- /** @ts-ignore */
724
- startTime,
725
- /** @ts-ignore */
726
- endTime,
727
- message: getMaintentTipsContent(brokerName, startDate, endDate)
728
- },
729
- ...draft.rows.filter(
730
- (tip) => tip.type !== types.AnnouncementType.Maintenance
731
- )
732
- ];
733
- })
734
- );
735
- } else {
736
- setTips((prev) => {
737
- return immer.produce(prev, (draft) => {
738
- const index = draft.rows?.findIndex(
739
- (tip) => tip.announcement_id === maintentanceId
740
- );
741
- if (index !== void 0 && index !== -1) {
742
- draft.rows?.splice(index, 1);
743
- }
744
- });
745
- });
746
- }
747
- }, [startTime, endTime, status, brokerName, t]);
748
719
  return {
749
- tips: sortDataByUpdatedTime(tips),
750
- maintenanceDialogInfo
720
+ tips,
721
+ maintenanceDialogInfo,
722
+ announcementStore,
723
+ setAnnouncementStore
751
724
  };
752
725
  };
753
726
  var useAnnouncement = (options) => {
754
727
  const { showAnnouncement, setShowAnnouncement } = reactApp.useAppContext();
755
- const { dataAdapter } = hooks.useOrderlyContext();
756
- const { tips, maintenanceDialogInfo } = useAnnouncementData();
757
- const memoizedTips = react.useMemo(() => {
758
- if (typeof dataAdapter?.announcementList === "function") {
759
- return dataAdapter.announcementList(
760
- tips?.rows ?? types.EMPTY_LIST
761
- );
762
- }
763
- return tips?.rows ?? types.EMPTY_LIST;
764
- }, [dataAdapter?.announcementList, tips?.rows]);
765
- const [announcementStore, setStore] = hooks.useLocalStorage(
766
- ORDERLY_ANNOUNCEMENT_KEY,
767
- {}
768
- );
728
+ const {
729
+ tips,
730
+ maintenanceDialogInfo,
731
+ announcementStore,
732
+ setAnnouncementStore
733
+ } = useAnnouncementData();
769
734
  const closeTips = () => {
770
- setStore((prev) => ({ ...prev, show: false }));
735
+ setAnnouncementStore((prev) => ({ ...prev, show: false }));
771
736
  };
772
737
  react.useEffect(() => {
773
- const len = memoizedTips.length;
738
+ const len = tips.length;
774
739
  setShowAnnouncement(
775
740
  Boolean(len) && announcementStore.show && !options?.hideTips
776
741
  );
777
- }, [
778
- memoizedTips,
779
- announcementStore.show,
780
- options?.hideTips,
781
- setShowAnnouncement
782
- ]);
742
+ }, [tips, announcementStore.show, options?.hideTips, setShowAnnouncement]);
783
743
  return {
784
744
  maintenanceDialogInfo,
785
- tips: memoizedTips,
745
+ tips,
786
746
  closeTips,
787
747
  showAnnouncement
788
748
  };
@@ -815,8 +775,7 @@ var AnnouncementCenterWidget = (props) => {
815
775
  const { dataSource, current, setCurrent } = useAnnouncementCenterScript();
816
776
  const onItemClick = react.useCallback(
817
777
  (url) => {
818
- if (!url)
819
- return;
778
+ if (!url) return;
820
779
  props.onRouteChange(url);
821
780
  },
822
781
  [props.onRouteChange]
@@ -836,8 +795,7 @@ var AnnouncementCenterPage = (props) => {
836
795
  AnnouncementCenterWidget,
837
796
  {
838
797
  onRouteChange: (url) => {
839
- if (!url)
840
- return;
798
+ if (!url) return;
841
799
  props.routerAdapter?.onRouteChange({
842
800
  href: url,
843
801
  name: url,
@@ -853,5 +811,5 @@ exports.AnnouncementCenterUI = AnnouncementCenterUI;
853
811
  exports.AnnouncementItem = AnnouncementItem;
854
812
  exports.NotificationUI = NotificationUI;
855
813
  exports.useAnnouncement = useAnnouncement;
856
- //# sourceMappingURL=out.js.map
814
+ //# sourceMappingURL=index.js.map
857
815
  //# sourceMappingURL=index.js.map