@primestyleai/tryon 1.2.2 → 1.3.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.
@@ -119,6 +119,7 @@ function PrimeStyleTryon({
119
119
  const [resultImageUrl, setResultImageUrl] = useState(null);
120
120
  const [errorMessage, setErrorMessage] = useState(null);
121
121
  const [dragOver, setDragOver] = useState(false);
122
+ const [countdown, setCountdown] = useState(20);
122
123
  const fileInputRef = useRef(null);
123
124
  const apiRef = useRef(null);
124
125
  const sseRef = useRef(null);
@@ -138,6 +139,21 @@ function PrimeStyleTryon({
138
139
  if (pollingRef.current) clearInterval(pollingRef.current);
139
140
  };
140
141
  }, [apiUrl]);
142
+ useEffect(() => {
143
+ if (view === "processing") {
144
+ setCountdown(20);
145
+ const interval = setInterval(() => {
146
+ setCountdown((prev) => {
147
+ if (prev <= 1) {
148
+ clearInterval(interval);
149
+ return 0;
150
+ }
151
+ return prev - 1;
152
+ });
153
+ }, 1e3);
154
+ return () => clearInterval(interval);
155
+ }
156
+ }, [view]);
141
157
  useEffect(() => {
142
158
  return () => {
143
159
  if (previewUrl) URL.revokeObjectURL(previewUrl);
@@ -464,13 +480,38 @@ function PrimeStyleTryon({
464
480
  }
465
481
  ),
466
482
  /* @__PURE__ */ jsx(UploadIcon, {}),
467
- /* @__PURE__ */ jsx("p", { className: cx("ps-tryon-upload-text", cn.uploadText), children: "Drop your photo here or click to upload" }),
483
+ /* @__PURE__ */ jsx("p", { className: cx("ps-tryon-upload-text", cn.uploadText), children: "Drop or upload your full body photo!" }),
468
484
  /* @__PURE__ */ jsx("p", { className: cx("ps-tryon-upload-hint", cn.uploadHint), children: "JPEG, PNG or WebP (max 10MB)" })
469
485
  ]
470
486
  }
471
487
  ) }),
472
488
  view === "processing" && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-processing", children: [
473
- /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-spinner", cn.spinner) }),
489
+ countdown > 0 ? /* @__PURE__ */ jsxs("div", { className: "ps-tryon-countdown-ring", children: [
490
+ /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 120 120", children: [
491
+ /* @__PURE__ */ jsx(
492
+ "circle",
493
+ {
494
+ className: "ps-tryon-countdown-track",
495
+ cx: "60",
496
+ cy: "60",
497
+ r: "52"
498
+ }
499
+ ),
500
+ /* @__PURE__ */ jsx(
501
+ "circle",
502
+ {
503
+ className: "ps-tryon-countdown-progress",
504
+ cx: "60",
505
+ cy: "60",
506
+ r: "52",
507
+ style: {
508
+ strokeDashoffset: `${countdown / 20 * 326.73}`
509
+ }
510
+ }
511
+ )
512
+ ] }),
513
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-countdown-number", children: countdown })
514
+ ] }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-done-pulse", children: /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-spinner", cn.spinner) }) }),
474
515
  /* @__PURE__ */ jsx(
475
516
  "p",
476
517
  {
@@ -478,7 +519,7 @@ function PrimeStyleTryon({
478
519
  "ps-tryon-processing-text",
479
520
  cn.processingText
480
521
  ),
481
- children: "Generating your try-on..."
522
+ children: countdown > 0 ? "Generating your try-on..." : "Almost there..."
482
523
  }
483
524
  ),
484
525
  /* @__PURE__ */ jsx(
@@ -488,7 +529,7 @@ function PrimeStyleTryon({
488
529
  "ps-tryon-processing-sub",
489
530
  cn.processingSubText
490
531
  ),
491
- children: "This usually takes 15-20 seconds"
532
+ children: countdown > 0 ? "This usually takes 15-20 seconds" : "Finishing up your look"
492
533
  }
493
534
  )
494
535
  ] }),
@@ -750,6 +791,52 @@ function PrimeStyleTryon({
750
791
  margin: 0 auto 16px;
751
792
  }
752
793
  @keyframes ps-spin { to { transform: rotate(360deg); } }
794
+
795
+ .ps-tryon-countdown-ring {
796
+ position: relative;
797
+ width: 100px;
798
+ height: 100px;
799
+ margin: 0 auto 20px;
800
+ }
801
+ .ps-tryon-countdown-ring svg {
802
+ width: 100%;
803
+ height: 100%;
804
+ transform: rotate(-90deg);
805
+ }
806
+ .ps-tryon-countdown-track {
807
+ fill: none;
808
+ stroke: #333;
809
+ stroke-width: 4;
810
+ }
811
+ .ps-tryon-countdown-progress {
812
+ fill: none;
813
+ stroke: var(--ps-loader, #bb945c);
814
+ stroke-width: 4;
815
+ stroke-linecap: round;
816
+ stroke-dasharray: 326.73;
817
+ transition: stroke-dashoffset 1s linear;
818
+ }
819
+ .ps-tryon-countdown-number {
820
+ position: absolute;
821
+ inset: 0;
822
+ display: flex;
823
+ align-items: center;
824
+ justify-content: center;
825
+ font-size: 28px;
826
+ font-weight: 700;
827
+ color: #fff;
828
+ font-variant-numeric: tabular-nums;
829
+ }
830
+
831
+ .ps-tryon-done-pulse {
832
+ animation: ps-fade-scale-in 0.4s ease both;
833
+ margin-bottom: 4px;
834
+ }
835
+ @keyframes ps-fade-scale-in {
836
+ from { opacity: 0; transform: scale(0.8); }
837
+ to { opacity: 1; transform: scale(1); }
838
+ }
839
+
753
840
  .ps-tryon-processing-text { font-size: 14px; color: #fff; margin: 0 0 4px; }
754
841
  .ps-tryon-processing-sub { font-size: 12px; color: #999; margin: 0; }
755
842
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "1.2.2",
3
+ "version": "1.3.1",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",