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