@stokr/components-library 3.0.39 → 3.0.41

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.
@@ -5,7 +5,7 @@ import { Text } from "../Text/Text.styles.js";
5
5
  import { Button } from "../Button/Button.styles.js";
6
6
  import { ComponentWrapper } from "../ComponentWrapper/ComponentWrapper.styles.js";
7
7
  import { ModalWrapper, ModalInner } from "../Modal/Modal.styles.js";
8
- import QRCode from "react-qr-code";
8
+ import { QRCodeSVG } from "qrcode.react";
9
9
  import { Row, Column } from "../Grid/Grid.styles.js";
10
10
  import stdin_default$1 from "../CryptoAddress/CryptoAddress.js";
11
11
  import { useMobileView } from "../../utils/customHooks.js";
@@ -24,11 +24,10 @@ const Connect2FA = (props) => {
24
24
  /* @__PURE__ */ jsx(Column, { part: 8, children: /* @__PURE__ */ jsxs(ModalInner, { children: [
25
25
  totpData && /* @__PURE__ */ jsxs(ComponentWrapper, { center: true, noPaddingHorizontal: true, children: [
26
26
  !isMobile && /* @__PURE__ */ jsx(
27
- QRCode,
27
+ QRCodeSVG,
28
28
  {
29
29
  size: 180,
30
- value: totpData?.totpUri,
31
- viewBox: `0 0 256 256`
30
+ value: totpData?.totpUri
32
31
  }
33
32
  ),
34
33
  /* @__PURE__ */ jsx(
@@ -13,7 +13,7 @@ import { getConfig, getPlatformURL } from "../../runtime-config.js";
13
13
  import { navigateToHref } from "../../routing/navigate-app.js";
14
14
  const LoginWithOTP = ({ withBackground, useRelativePathForMenu = false }) => {
15
15
  const navigate = useNavigate();
16
- const { loginUser, waitingFor2fa, firebaseError, loginUserWithTotp, reset2faFlow } = useContext(AuthContext);
16
+ const { loginUser, waitingFor2fa, firebaseError, loginUserWithTotp, reset2faFlow, logoutUser } = useContext(AuthContext);
17
17
  const [isModalOpen, setIsModalOpen] = useState({
18
18
  login: true,
19
19
  enter2fa: false,
@@ -79,6 +79,7 @@ const LoginWithOTP = ({ withBackground, useRelativePathForMenu = false }) => {
79
79
  clearPopupError();
80
80
  setIsActionLoading(void 0);
81
81
  },
82
+ logoutUser,
82
83
  onFormSend: async ({ email, password }) => {
83
84
  clearPopupError();
84
85
  setIsActionLoading("login");
@@ -45,7 +45,6 @@ const Button = styled.button.withConfig({
45
45
  user-select: none;
46
46
  cursor: pointer;
47
47
  transition:
48
- color 0.2s,
49
48
  background-color 0.2s,
50
49
  border-color 0.2s;
51
50
 
@@ -1,6 +1,6 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
- import { useRef, useEffect } from "react";
3
+ import { useRef, useState, useCallback, useEffect } from "react";
4
4
  import { useInView } from "react-intersection-observer";
5
5
  const VideoContainer = styled.div`
6
6
  position: relative;
@@ -16,14 +16,41 @@ const VideoBackground = styled.video`
16
16
  top: 0;
17
17
  left: 0;
18
18
  `;
19
- const now = Date.now();
19
+ const CLOUDINARY_BASE = "https://res.cloudinary.com/stokr/video/upload";
20
+ const CLOUDINARY_VERSION = "v1745923531";
21
+ const CLOUDINARY_PUBLIC_ID = "Static/Hero_section_video_kuatj1";
22
+ const VIDEO_SRC_DESKTOP = `${CLOUDINARY_BASE}/f_auto,q_auto:good,vc_auto,w_1920,c_limit/${CLOUDINARY_VERSION}/${CLOUDINARY_PUBLIC_ID}.mp4`;
23
+ const VIDEO_SRC_MOBILE = `${CLOUDINARY_BASE}/f_auto,q_auto:good,vc_auto,w_1280,c_limit/${CLOUDINARY_VERSION}/${CLOUDINARY_PUBLIC_ID}.mp4`;
24
+ const VIDEO_POSTER = `${CLOUDINARY_BASE}/so_0,f_auto,q_auto:good,w_1920,c_limit/${CLOUDINARY_VERSION}/${CLOUDINARY_PUBLIC_ID}.jpg`;
25
+ const shouldLoadVideo = () => {
26
+ if (typeof navigator === "undefined") return true;
27
+ const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
28
+ if (conn) {
29
+ if (conn.saveData) return false;
30
+ if (conn.effectiveType && ["slow-2g", "2g"].includes(conn.effectiveType)) return false;
31
+ }
32
+ if (typeof window !== "undefined" && window.matchMedia) {
33
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return false;
34
+ }
35
+ return true;
36
+ };
20
37
  const HeroVideoBlock = () => {
21
38
  const videoRef = useRef(null);
22
39
  const lastTimeRef = useRef(0);
23
- const lastVisibleTime = useRef(now);
24
- const playVideo = () => {
25
- if (!videoRef.current) return;
40
+ const lastVisibleTime = useRef(0);
41
+ const visibilityTimeoutRef = useRef(null);
42
+ const hasTriggeredLoadRef = useRef(false);
43
+ const [shouldAutoplay] = useState(() => shouldLoadVideo());
44
+ const playVideo = useCallback(() => {
45
+ if (!videoRef.current || !shouldAutoplay) return;
26
46
  const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
47
+ if (!hasTriggeredLoadRef.current) {
48
+ hasTriggeredLoadRef.current = true;
49
+ try {
50
+ videoRef.current.load();
51
+ } catch (_e) {
52
+ }
53
+ }
27
54
  if (videoRef.current.currentTime > 0) {
28
55
  lastTimeRef.current = videoRef.current.currentTime;
29
56
  }
@@ -40,7 +67,7 @@ const HeroVideoBlock = () => {
40
67
  }
41
68
  });
42
69
  }
43
- };
70
+ }, [shouldAutoplay]);
44
71
  const handleVisibilityChange = (isVisible) => {
45
72
  if (isVisible) {
46
73
  lastVisibleTime.current = Date.now();
@@ -59,13 +86,13 @@ const HeroVideoBlock = () => {
59
86
  }
60
87
  });
61
88
  useEffect(() => {
62
- let visibilityTimeoutId;
63
89
  const handleDocVisibilityChange = () => {
64
90
  if (document.visibilityState === "visible") {
65
91
  lastVisibleTime.current = Date.now();
66
- if (visibilityTimeoutId != null) clearTimeout(visibilityTimeoutId);
67
- visibilityTimeoutId = setTimeout(() => {
92
+ if (visibilityTimeoutRef.current) clearTimeout(visibilityTimeoutRef.current);
93
+ visibilityTimeoutRef.current = setTimeout(() => {
68
94
  playVideo();
95
+ visibilityTimeoutRef.current = null;
69
96
  }, 300);
70
97
  } else if (videoRef.current) {
71
98
  lastTimeRef.current = videoRef.current.currentTime;
@@ -74,29 +101,27 @@ const HeroVideoBlock = () => {
74
101
  document.addEventListener("visibilitychange", handleDocVisibilityChange);
75
102
  playVideo();
76
103
  return () => {
77
- if (visibilityTimeoutId != null) clearTimeout(visibilityTimeoutId);
104
+ if (visibilityTimeoutRef.current) clearTimeout(visibilityTimeoutRef.current);
78
105
  document.removeEventListener("visibilitychange", handleDocVisibilityChange);
79
106
  };
80
- }, []);
107
+ }, [playVideo]);
81
108
  return /* @__PURE__ */ jsx("div", { ref: windowViewportRef, children: /* @__PURE__ */ jsx(VideoContainer, { children: /* @__PURE__ */ jsx(
82
109
  VideoBackground,
83
110
  {
84
111
  ref: videoRef,
85
- autoPlay: true,
112
+ autoPlay: shouldAutoplay,
86
113
  muted: true,
87
114
  loop: true,
88
115
  playsInline: true,
89
- preload: "metadata",
116
+ preload: "none",
117
+ disableRemotePlayback: true,
118
+ poster: VIDEO_POSTER,
90
119
  "data-vsc-ignore": "true",
91
120
  fetchPriority: "high",
92
- children: /* @__PURE__ */ jsx(
93
- "source",
94
- {
95
- src: "https://res.cloudinary.com/stokr/video/upload/f_auto,q_auto:best/v1745923531/Static/Hero_section_video_kuatj1.mp4",
96
- type: "video/mp4",
97
- fetchPriority: "high"
98
- }
99
- )
121
+ children: shouldAutoplay && /* @__PURE__ */ jsxs(Fragment, { children: [
122
+ /* @__PURE__ */ jsx("source", { src: VIDEO_SRC_MOBILE, type: "video/mp4", media: "(max-width: 767px)" }),
123
+ /* @__PURE__ */ jsx("source", { src: VIDEO_SRC_DESKTOP, type: "video/mp4", media: "(min-width: 768px)" })
124
+ ] })
100
125
  }
101
126
  ) }) });
102
127
  };
@@ -27,7 +27,9 @@ class Layout extends React__default.PureComponent {
27
27
  noFooter,
28
28
  noHeader,
29
29
  noLogout,
30
- useRelativePathForMenu = false
30
+ useRelativePathForMenu = false,
31
+ logoutUser = () => {
32
+ }
31
33
  } = this.props;
32
34
  return /* @__PURE__ */ jsx(ThemeProvider, { theme: { ...theme }, children: /* @__PURE__ */ jsxs(PageWrapper, { children: [
33
35
  /* @__PURE__ */ jsx(GlobalStyle, {}),
@@ -40,7 +42,8 @@ class Layout extends React__default.PureComponent {
40
42
  signupHandler,
41
43
  siteTitle: title,
42
44
  noLogout,
43
- useRelativePathForMenu
45
+ useRelativePathForMenu,
46
+ logoutUser
44
47
  }
45
48
  ),
46
49
  /* @__PURE__ */ jsx(
@@ -64,7 +67,8 @@ Layout.propTypes = {
64
67
  progress: PropTypes.bool,
65
68
  footerColor: PropTypes.string,
66
69
  children: PropTypes.node.isRequired,
67
- useRelativePathForMenu: PropTypes.bool
70
+ useRelativePathForMenu: PropTypes.bool,
71
+ logoutUser: PropTypes.func
68
72
  };
69
73
  ProgressStatusContext.Consumer;
70
74
  export {
@@ -24,10 +24,10 @@ const StepsProgressSignup = (props) => {
24
24
  isActive: isActiveStep("/verify-identity")
25
25
  },
26
26
  {
27
- id: "taxId",
28
- handleClick: () => navigate("/taxid"),
27
+ id: "self-certification",
28
+ handleClick: () => navigate("/self-certification"),
29
29
  isDone: !!taxId,
30
- isActive: isActiveStep("/taxid")
30
+ isActive: isActiveStep("/self-certification")
31
31
  },
32
32
  {
33
33
  id: "ampID",
@@ -35,14 +35,14 @@ class Auth {
35
35
  */
36
36
  static setAccessToken(token, options = {}) {
37
37
  this.logout();
38
- const cookieDomain = getCookieDomain();
38
+ const cookieOptions = getCookieDomain();
39
39
  const raw = options?.expiresInMs;
40
40
  const expiresInMs = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : Number(DEFAULT_TOKEN_EXPIRY_MS) || 60 * 60 * 1e3;
41
41
  const expiresAtMs = Date.now() + expiresInMs;
42
42
  const expiresInDays = expiresInMs / (24 * 60 * 60 * 1e3);
43
- cookieDomain.expires = expiresInDays;
44
- Cookies.set("STOKR_ACCESS_TOKEN", token, cookieDomain);
45
- Cookies.set("STOKR_ACCESS_TOKEN_EXPIRES", String(expiresAtMs), cookieDomain);
43
+ const finalOptions = { ...cookieOptions, expires: expiresInDays };
44
+ Cookies.set("STOKR_ACCESS_TOKEN", token, finalOptions);
45
+ Cookies.set("STOKR_ACCESS_TOKEN_EXPIRES", String(expiresAtMs), finalOptions);
46
46
  }
47
47
  static getAccessToken() {
48
48
  return Cookies.get("STOKR_ACCESS_TOKEN");
@@ -58,6 +58,10 @@ class Auth {
58
58
  const cookieDomain = getCookieDomain();
59
59
  Cookies.remove("STOKR_ACCESS_TOKEN", cookieDomain);
60
60
  Cookies.remove("STOKR_ACCESS_TOKEN_EXPIRES", cookieDomain);
61
+ if (cookieDomain.domain) {
62
+ Cookies.remove("STOKR_ACCESS_TOKEN");
63
+ Cookies.remove("STOKR_ACCESS_TOKEN_EXPIRES");
64
+ }
61
65
  }
62
66
  static async login(email, password) {
63
67
  const auth = getFirebaseAuth();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stokr/components-library",
3
- "version": "3.0.39",
3
+ "version": "3.0.41",
4
4
  "description": "STOKR - Components Library",
5
5
  "author": "Bilal Hodzic <bilal@stokr.io>",
6
6
  "license": "MIT",
@@ -84,7 +84,6 @@
84
84
  "react-intersection-observer": "^10.0.2",
85
85
  "react-otp-input": "^3.1.0",
86
86
  "react-portal": "^4.2.2",
87
- "react-qr-code": "^2.0.12",
88
87
  "react-range": "^1.8.14",
89
88
  "react-select": "^5.7.0",
90
89
  "react-slick": "^0.31.0",