Skip to content

Commit 82156d1

Browse files
committed
Update react qs
1 parent 2ae8dde commit 82156d1

File tree

10 files changed

+409
-98
lines changed

10 files changed

+409
-98
lines changed

src/pages/quickstart/MediaStep/index.tsx

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ interface MediaStepProps {
1010
}
1111

1212
const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true }) => {
13-
const [isLoading, setIsLoading] = useState(false); // Start with false for lazy loading
13+
const [isLoading, setIsLoading] = useState(true); // Start loading immediately
1414
const [hasError, setHasError] = useState(false);
1515
const [isPlaying, setIsPlaying] = useState(false);
16-
const [shouldLoad, setShouldLoad] = useState(false);
1716
const videoRef = useRef<HTMLVideoElement>(null);
1817
const imageRef = useRef<HTMLImageElement>(null);
1918

@@ -47,42 +46,18 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
4746
setIsPlaying(false);
4847
}, []);
4948

50-
const startLoading = useCallback(() => {
51-
if (!shouldLoad) {
52-
setShouldLoad(true);
53-
setIsLoading(true);
54-
setHasError(false);
55-
setIsPlaying(false);
56-
}
57-
}, [shouldLoad]);
5849

59-
// Lazy loading effect - only load when visible
60-
useEffect(() => {
61-
if (isVisible && !shouldLoad) {
62-
// Auto-load YouTube videos (they're lightweight), but require manual loading for local videos
63-
if (type === 'youtube') {
64-
const timer = setTimeout(() => {
65-
startLoading();
66-
}, 200); // Small delay for YouTube
67-
return () => clearTimeout(timer);
68-
}
69-
// Local videos and images still require manual loading
70-
}
71-
}, [isVisible, shouldLoad, startLoading, type]);
50+
51+
7252

7353
// Reset when URL changes
7454
useEffect(() => {
75-
setShouldLoad(false);
76-
setIsLoading(false);
55+
setIsLoading(true);
7756
setHasError(false);
7857
setIsPlaying(false);
7958
}, [url]);
8059

8160
const renderMedia = () => {
82-
// Don't render media until shouldLoad is true
83-
if (!shouldLoad) {
84-
return null;
85-
}
8661

8762
if (type === 'youtube') {
8863
const youtubeUrl = `https://www.youtube.com/embed/${youtubeId}?rel=0&modestbranding=1&showinfo=0${autoplay ? '&autoplay=1' : ''}${muted ? '&mute=1' : ''}`;
@@ -91,7 +66,7 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
9166
<iframe
9267
className={styles.youtubePlayer}
9368
src={youtubeUrl}
94-
title={step.title}
69+
title={`${type === 'youtube' ? 'YouTube video' : 'Video'} - ${caption || 'Media content'}`}
9570
frameBorder="0"
9671
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
9772
allowFullScreen
@@ -108,12 +83,12 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
10883
className={styles.videoPlayer}
10984
src={url}
11085
poster={poster}
111-
autoPlay={autoplay && isVisible} // Only autoplay if visible
86+
autoPlay={autoplay}
11287
loop={loop}
11388
muted={muted}
11489
controls
11590
playsInline
116-
preload="none" // Prevent preloading for performance
91+
preload="metadata" // Load metadata immediately
11792
onLoadedData={handleLoad}
11893
onError={handleError}
11994
onPlay={handlePlay}
@@ -130,8 +105,8 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
130105
ref={imageRef}
131106
className={styles.imageDisplay}
132107
src={url}
133-
alt={alt || step.title}
134-
loading="lazy" // Native lazy loading
108+
alt={alt || 'Image content'}
109+
loading="eager" // Load immediately
135110
onLoad={handleLoad}
136111
onError={handleError}
137112
/>
@@ -143,21 +118,7 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
143118

144119
return (
145120
<div className={classNames(styles.mediaContainer, className)}>
146-
{/* Placeholder State - before loading */}
147-
{!shouldLoad && (
148-
<div className={styles.mediaPlaceholder}>
149-
<div className={styles.placeholderIcon}>
150-
{type === 'youtube' ? '▶️' : type === 'video' ? '🎬' : '🖼️'}
151-
</div>
152-
<p>Click to load {type === 'youtube' ? 'YouTube video' : type}</p>
153-
<button
154-
className={styles.loadButton}
155-
onClick={startLoading}
156-
>
157-
Load {type === 'youtube' ? 'YouTube Video' : type}
158-
</button>
159-
</div>
160-
)}
121+
161122

162123
{/* Loading State */}
163124
{isLoading && !hasError && (
@@ -175,9 +136,8 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
175136
<button
176137
className={styles.retryButton}
177138
onClick={() => {
178-
setShouldLoad(false);
179-
// Reset and try again
180-
setTimeout(() => startLoading(), 100);
139+
setIsLoading(true);
140+
setHasError(false);
181141
}}
182142
>
183143
Retry
@@ -188,21 +148,21 @@ const MediaStep: React.FC<MediaStepProps> = ({ step, className, isVisible = true
188148
{/* Media Content */}
189149
<div
190150
className={classNames(styles.mediaContent, {
191-
[styles.hidden]: isLoading || hasError || !shouldLoad,
151+
[styles.hidden]: isLoading || hasError,
192152
[styles.playing]: isPlaying
193153
})}
194154
>
195155
{renderMedia()}
196156

197157
{/* Caption */}
198-
{caption && shouldLoad && (
158+
{caption && !isLoading && !hasError && (
199159
<div className={styles.mediaCaption}>
200160
<p>{caption}</p>
201161
</div>
202162
)}
203163

204164
{/* Video Play Status Indicator */}
205-
{type === 'video' && shouldLoad && (
165+
{type === 'video' && !isLoading && !hasError && (
206166
<div className={classNames(styles.playStatus, {
207167
[styles.visible]: isPlaying
208168
})}>

src/pages/quickstart/builder/embedded-wallets/react/stepContent/installation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Install the Web3Auth package in your project.
44

5-
> Additionally, for blockchain calls, we're using `wagmi` and its dependency, `@tanstack/react-query` for this example.
5+
Additionally, for blockchain calls, we're using `wagmi` for this example.
66

77
```bash npm2yarn
88
npm install --save @web3auth/modal wagmi @tanstack/react-query
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
### Fixing Bundler Issues
1+
### Troubleshooting
22

33
While using any web3 library in React, you may run into issues building. This issue occurs because some core packages like `eccrypto` have certain dependencies which are not present within the browser build environment.
44

55
> To solve this, please have a look at our troubleshooting pages about [Vite Issues](/troubleshooting/vite-issues)
6+
7+
:::info
8+
9+
If you face any problem anytime, you can always find help in the [**Web3Auth Community**](https://web3auth.io/community/c/help-pnp/pnp-web/7).
10+
11+
:::
Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
### Embedded Wallets React Quick Start
1+
### Web3Auth Embedded Wallets Quick Start
22

3-
Enable social login and wallet login in your React app using Web3Auth.
3+
Add social login and wallet connection functionality to your React app.
44

5-
Clone the React Quick Start Application
5+
Clone the Quick Start in your terminal.
66

7-
```shell
7+
```bash
88
npx degit Web3Auth/web3auth-examples/quick-starts/react-quick-start w3a-quick-start
99
```
10-
11-
:::info
12-
13-
If you face any problem anytime, you can always find help in the [**Web3Auth Community**](https://web3auth.io/community/c/help-pnp/pnp-web/7).
14-
15-
:::

src/pages/quickstart/builder/embedded-wallets/react/steps.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,6 @@ export default function getSteps(steps, files, replacementAggregator) {
1919
'Web3Auth Installation'
2020
),
2121
},
22-
{
23-
...STEPS.reactBundlerIssues,
24-
pointer: replacementAggregator.highlightRange(
25-
IBfileLinks.EW_REACT_INDEX_HTML,
26-
files[IBfileLinks.EW_REACT_INDEX_HTML],
27-
'Bundler Issues'
28-
),
29-
},
3022
{
3123
...STEPS.registerApp,
3224
pointer: replacementAggregator.highlightRange(
@@ -82,6 +74,14 @@ export default function getSteps(steps, files, replacementAggregator) {
8274
files[IBfileLinks.EW_REACT_APP_TSX],
8375
'Logout'
8476
),
77+
},
78+
{
79+
...STEPS.reactBundlerIssues,
80+
pointer: replacementAggregator.highlightRange(
81+
IBfileLinks.EW_REACT_INDEX_HTML,
82+
files[IBfileLinks.EW_REACT_INDEX_HTML],
83+
'Bundler Issues'
84+
),
8585
}
8686
)
8787
}

src/pages/quickstart/commonSteps/registerApp.mdx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
### Get your Client ID from the Web3Auth Dashboard
1+
---
2+
contentType: 'hybrid'
3+
mediaContent:
4+
type: 'image'
5+
url: '/img/web3auth-dashboard/web3auth-client-id.png'
6+
---
27

3-
import DashboardImage from '@site/static/img/web3auth-dashboard/project-details.png'
8+
### Get your Client ID from the Web3Auth Dashboard
49

510
Visit the Web3Auth Dashboard and create a new project. Use the Client ID of the project to start your integration.
611

src/pages/quickstart/index.tsx

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ export default function IntegrationBuilderPage(props: any) {
227227
return result;
228228
}, [builderOptions, files, stepIndex, showNavigationOverlay]);
229229
const [selectedFilename, setSelectedFilename] = useState(integration.filenames[0] || "");
230+
const [activeTab, setActiveTab] = useState<'media' | 'code'>('media');
230231

231232
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
232233
const ref = useRef(null);
@@ -242,6 +243,13 @@ export default function IntegrationBuilderPage(props: any) {
242243

243244
const { steps } = integration;
244245

246+
// Reset to media tab when step changes for hybrid content
247+
useEffect(() => {
248+
if (steps[stepIndex]?.contentType === 'hybrid') {
249+
setActiveTab('media');
250+
}
251+
}, [stepIndex, steps]);
252+
245253
// Navigation handlers with smooth scrolling to exact top
246254
const scrollToStep = useCallback((stepElementId: string) => {
247255
const stepsContainer = document.getElementById('steps-container');
@@ -778,26 +786,50 @@ export default function IntegrationBuilderPage(props: any) {
778786
isVisible={true} // Always visible when it's the active step
779787
/>
780788
) : steps[stepIndex]?.contentType === 'hybrid' ? (
781-
<div className={styles.hybridContainer}>
782-
<div className={styles.hybridMediaSection}>
783-
<MediaStep
784-
step={steps[stepIndex]}
785-
className={styles.hybridMediaStep}
786-
isVisible={true} // Always visible when it's the active step
787-
/>
789+
<div className={styles.hybridTabContainer}>
790+
{/* Tab Navigation */}
791+
<div className={styles.tabNavigation}>
792+
<button
793+
className={classNames(styles.tabButton, {
794+
[styles.tabButtonActive]: activeTab === 'media'
795+
})}
796+
onClick={() => setActiveTab('media')}
797+
>
798+
Media
799+
</button>
800+
<button
801+
className={classNames(styles.tabButton, {
802+
[styles.tabButtonActive]: activeTab === 'code'
803+
})}
804+
onClick={() => setActiveTab('code')}
805+
>
806+
Code
807+
</button>
788808
</div>
789-
<div className={styles.hybridCodeSection}>
790-
<IntegrationBuilderCodeView
791-
filenames={integration.filenames}
792-
fileContents={integration.files}
793-
highlight={
794-
steps[stepIndex]?.pointer?.filename === selectedFilename
795-
? steps[stepIndex]?.pointer?.range
796-
: undefined
797-
}
798-
selectedFilename={selectedFilename}
799-
onClickFilename={(filename: string) => setSelectedFilename(filename)}
800-
/>
809+
810+
{/* Tab Content */}
811+
<div className={styles.tabContent}>
812+
{activeTab === 'media' ? (
813+
<MediaStep
814+
step={steps[stepIndex]}
815+
className={styles.hybridMediaStep}
816+
isVisible={true} // Always visible when it's the active step
817+
/>
818+
) : (
819+
<div className={styles.hybridCodeView}>
820+
<IntegrationBuilderCodeView
821+
filenames={integration.filenames}
822+
fileContents={integration.files}
823+
highlight={
824+
steps[stepIndex]?.pointer?.filename === selectedFilename
825+
? steps[stepIndex]?.pointer?.range
826+
: undefined
827+
}
828+
selectedFilename={selectedFilename}
829+
onClickFilename={(filename: string) => setSelectedFilename(filename)}
830+
/>
831+
</div>
832+
)}
801833
</div>
802834
</div>
803835
) : (

src/pages/quickstart/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ReactNode } from 'react'
22

33
export interface IntegrationStep {
4+
title?: string // Optional title for the step
45
content?: ReactNode // Make optional for media-only steps
56
contentType?: 'text' | 'media' | 'hybrid' // Default: 'text'
67
mediaContent?: {

0 commit comments

Comments
 (0)