Merge pull request #3030 from ethereum/nht

scroll functionality for FP and GS sections in home tab
pull/3032/head
Liana Husikyan 2 years ago committed by GitHub
commit 8ca42451b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx
  2. 11
      libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
  3. 57
      libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx
  4. 64
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
  5. 6
      libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx
  6. 2
      libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx
  7. 2
      libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx
  8. 2
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css

@ -2,15 +2,24 @@
import React from 'react' import React from 'react'
const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => { const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => {
const { carouselState: { currentSlide, totalItems } } = rest const { carouselState: { currentSlide, totalItems, itemWidth, containerWidth } } = rest
return ( return (
<div className="mt-1 d-flex justify-content-end carousel-button-group"> <div className="mt-1 d-flex justify-content-end carousel-button-group">
<button className={currentSlide === 0 ? 'disable py-1 border btn' : 'py-1 border btn'} onClick={() => previous()}> <button
className={currentSlide === 0 ? 'disable py-1 border btn' : 'py-1 border btn'}
disabled={currentSlide === 0}
onClick={() => previous()}
>
<i className="fas fa-angle-left"></i> <i className="fas fa-angle-left"></i>
</button> </button>
<button className={currentSlide + 1 === totalItems ? 'disable py-1 border btn' : 'py-1 border btn'} onClick={() => { <button
className={
((totalItems - currentSlide) * itemWidth + 5) < containerWidth ? 'disable py-1 border btn' : 'py-1 border btn'}
onClick={() => {
if (currentSlide + 1 < totalItems) goToSlide(currentSlide + 1) if (currentSlide + 1 < totalItems) goToSlide(currentSlide + 1)
}} > }}
disabled ={((totalItems - currentSlide) * itemWidth + 5) < containerWidth}
>
<i className="fas fa-angle-right"></i> <i className="fas fa-angle-right"></i>
</button> </button>
</div> </div>

@ -43,7 +43,8 @@ function HomeTabFeatured() {
<img src={"assets/img/bgRemi.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img> <img src={"assets/img/bgRemi.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img>
<div className="h6 w-50 p-4" style={{ flex: "1" }}> <div className="h6 w-50 p-4" style={{ flex: "1" }}>
<h5>JUMP INTO WEB3</h5> <h5>JUMP INTO WEB3</h5>
<span>The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.</span> <p>The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.</p>
<a className="remixui_home_text" target="__blank" href="https://remix-project.org">More</a>
</div> </div>
</div> </div>
<div className="d-flex"> <div className="d-flex">
@ -51,7 +52,10 @@ function HomeTabFeatured() {
<div className="h6 p-4" style={{ flex: "1" }}> <div className="h6 p-4" style={{ flex: "1" }}>
<h5>REMIX REWARDS</h5> <h5>REMIX REWARDS</h5>
<p style={{ fontStyle: 'italic' }}>NFTs for our users!</p> <p style={{ fontStyle: 'italic' }}>NFTs for our users!</p>
<span>Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second Remixer user NFT badge to give to any other user of their choice</span> <p>
Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second Remixer user NFT badge to give to any other user of their choice.
</p>
<a className="remixui_home_text" target="__blank" href="https://rewards.remix.ethereum.eth.limo">More</a>
</div> </div>
</div> </div>
<div className="d-flex"> <div className="d-flex">
@ -59,7 +63,8 @@ function HomeTabFeatured() {
<div className="h6 p-4" style={{ flex: "1" }}> <div className="h6 p-4" style={{ flex: "1" }}>
<h5>BETA TESTING</h5> <h5>BETA TESTING</h5>
<p style={{ fontStyle: 'italic' }}>Our community supports us.</p> <p style={{ fontStyle: 'italic' }}>Our community supports us.</p>
<span>You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!</span> <p>You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!</p>
<a className="remixui_home_text" target="__blank" href="https://rewards.remix.ethereum.eth.limo">More</a>
</div> </div>
</div> </div>
</Carousel> </Carousel>

@ -1,17 +1,17 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useEffect, useState, useRef, useContext } from 'react' import React, { useEffect, useRef, useContext } from 'react'
import PluginButton from './pluginButton' import PluginButton from './pluginButton'
import { ThemeContext, themes } from '../themeContext' import { ThemeContext } from '../themeContext'
import Carousel from 'react-multi-carousel' import Carousel from 'react-multi-carousel'
import 'react-multi-carousel/lib/styles.css' import 'react-multi-carousel/lib/styles.css'
import CustomNavButtons from './customNavButtons' import CustomNavButtons from './customNavButtons'
const itemsToShow = 5
declare global { declare global {
interface Window { interface Window {
_paq: any _paq: any
} }
} }
const _paq = window._paq = window._paq || [] //eslint-disable-line const _paq = window._paq = window._paq || [] //eslint-disable-line
interface HomeTabFeaturedPluginsProps { interface HomeTabFeaturedPluginsProps {
plugin: any plugin: any
} }
@ -20,16 +20,40 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
const themeFilter = useContext(ThemeContext) const themeFilter = useContext(ThemeContext)
const carouselRef = useRef(null) const carouselRef = useRef(null)
const carouselRefDiv = useRef(null)
// Todo doesn't work
useEffect(() => { useEffect(() => {
window.addEventListener("scroll", handleScroll) document.addEventListener("wheel", handleScroll)
return () => { return () => {
window.removeEventListener("scroll", handleScroll) document.removeEventListener("wheel", handleScroll)
} }
}, []) }, [])
function isDescendant(parent, child) {
let node = child.parentNode;
while (node != null) {
if (node === parent) {
return true;
}
node = node.parentNode;
}
return false;
}
const handleScroll = (e) => { const handleScroll = (e) => {
if (isDescendant(carouselRefDiv.current, e.target)) {
e.stopPropagation()
let nextSlide = 0
if (e.wheelDelta < 0) {
nextSlide = carouselRef.current.state.currentSlide + 1;
if ((carouselRef.current.state.totalItems - carouselRef.current.state.currentSlide) * carouselRef.current.state.itemWidth + 5 < carouselRef.current.state.containerWidth) return // 5 is approx margins
carouselRef.current.goToSlide(nextSlide)
} else {
nextSlide = carouselRef.current.state.currentSlide - 1;
if (nextSlide < 0) nextSlide = 0
carouselRef.current.goToSlide(nextSlide)
}
}
} }
const startSolidity = async () => { const startSolidity = async () => {
@ -61,17 +85,30 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
return ( return (
<div className="pl-2 w-100" id="hTFeaturedPlugins"> <div className="pl-2 w-100" id="hTFeaturedPlugins">
<label className="" style={{fontSize: "1.2rem"}}>Featured Plugins</label> <label className="" style={{fontSize: "1.2rem"}}>Featured Plugins</label>
<div className="w-100 d-flex flex-column"> <div ref={carouselRefDiv} className="w-100 d-flex flex-column">
<ThemeContext.Provider value={ themeFilter }> <ThemeContext.Provider value={ themeFilter }>
<Carousel <Carousel
ref={carouselRef} ref={carouselRef}
focusOnSelect focusOnSelect={true}
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} customButtonGroup={
<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />
}
arrows={false} arrows={false}
swipeable={false} swipeable={false}
draggable={true} draggable={true}
showDots={false} showDots={false}
responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }} responsive={
{
superLargeDesktop: {
breakpoint: { max: 4000, min: 3000 },
items: itemsToShow
},
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: itemsToShow
}
}
}
renderButtonGroupOutside={true} renderButtonGroupOutside={true}
ssr={true} // means to render carousel on server-side. ssr={true} // means to render carousel on server-side.
keyBoardControl={true} keyBoardControl={true}

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useEffect, useState, useRef, useContext } from 'react' import React, { useEffect, useRef, useContext } from 'react'
import { ThemeContext, themes } from '../themeContext' import { ThemeContext} from '../themeContext'
import Carousel from 'react-multi-carousel' import Carousel from 'react-multi-carousel'
import WorkspaceTemplate from './workspaceTemplate' import WorkspaceTemplate from './workspaceTemplate'
import 'react-multi-carousel/lib/styles.css' import 'react-multi-carousel/lib/styles.css'
@ -11,13 +11,48 @@ declare global {
} }
} }
const _paq = window._paq = window._paq || [] //eslint-disable-line const _paq = window._paq = window._paq || [] //eslint-disable-line
interface HomeTabGetStartedProps { interface HomeTabGetStartedProps {
plugin: any plugin: any
} }
function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) { function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
const themeFilter = useContext(ThemeContext) const themeFilter = useContext(ThemeContext)
const carouselRef = useRef(null)
const carouselRefDiv = useRef(null)
useEffect(() => {
document.addEventListener("wheel", handleScroll)
return () => {
document.removeEventListener("wheel", handleScroll)
}
}, [])
function isDescendant(parent, child) {
let node = child.parentNode;
while (node != null) {
if (node === parent) {
return true;
}
node = node.parentNode;
}
return false;
}
const handleScroll = (e) => {
if (isDescendant(carouselRefDiv.current, e.target)) {
e.stopPropagation()
let nextSlide = 0
if (e.wheelDelta < 0) {
nextSlide = carouselRef.current.state.currentSlide + 1;
if ((carouselRef.current.state.totalItems - carouselRef.current.state.currentSlide) * carouselRef.current.state.itemWidth + 5 < carouselRef.current.state.containerWidth) return // 5 is approx margins
carouselRef.current.goToSlide(nextSlide)
} else {
nextSlide = carouselRef.current.state.currentSlide - 1;
if (nextSlide < 0) nextSlide = 0
carouselRef.current.goToSlide(nextSlide)
}
}
}
const createWorkspace = async (templateName) => { const createWorkspace = async (templateName) => {
await plugin.appManager.activatePlugin('filePanel') await plugin.appManager.activatePlugin('filePanel')
@ -36,16 +71,31 @@ function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
</span> </span>
- Project Templates - Project Templates
</label> </label>
<div className="w-100 d-flex flex-column"> <div ref={carouselRefDiv} className="w-100 d-flex flex-column">
<ThemeContext.Provider value={ themeFilter }> <ThemeContext.Provider value={ themeFilter }>
<Carousel <Carousel
focusOnSelect ref={carouselRef}
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} focusOnSelect={true}
customButtonGroup={
<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />
}
arrows={false} arrows={false}
swipeable={false} swipeable={false}
draggable={true} draggable={true}
showDots={false} showDots={false}
responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }} responsive={
{
superLargeDesktop: {
breakpoint: { max: 4000, min: 3000 },
items: 5
},
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 5,
partialVisibilityGutter: 0
}
}
}
renderButtonGroupOutside={true} renderButtonGroupOutside={true}
ssr={true} // means to render carousel on server-side. ssr={true} // means to render carousel on server-side.
keyBoardControl={true} keyBoardControl={true}

@ -50,20 +50,20 @@ function HomeTabLearn ({plugin}: HomeTabLearnProps) {
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Basics }})}> <button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Basics }})}>
<label className="float-left" style={{fontSize: "1rem"}}>Remix Basics</label> <label className="m-0 float-left" style={{fontSize: "1rem"}}>Remix Basics</label>
{(state.visibleTutorial === VisibleTutorial.Basics) && <div className="pt-2 d-flex flex-column text-left"> {(state.visibleTutorial === VisibleTutorial.Basics) && <div className="pt-2 d-flex flex-column text-left">
<span>Introduction to Remix's interface and concepts used in Ethereum, as well as the basics of Solidity.</span> <span>Introduction to Remix's interface and concepts used in Ethereum, as well as the basics of Solidity.</span>
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('basics')}>Get Started</button> <button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('basics')}>Get Started</button>
</div>} </div>}
</button> </button>
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Intermediate }})}> <button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Intermediate }})}>
<label className="float-left" style={{fontSize: "1rem"}}>Remix Intermediate</label> <label className="m-0 float-left" style={{fontSize: "1rem"}}>Remix Intermediate</label>
{(state.visibleTutorial === VisibleTutorial.Intermediate) && <div className="pt-2 d-flex flex-column text-left">Using the web3.js to interact with a contract. Using Recorder tool. {(state.visibleTutorial === VisibleTutorial.Intermediate) && <div className="pt-2 d-flex flex-column text-left">Using the web3.js to interact with a contract. Using Recorder tool.
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('useofweb3js')}>Get Started</button> <button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('useofweb3js')}>Get Started</button>
</div>} </div>}
</button> </button>
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Advanced }})}> <button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Advanced }})}>
<label className="float-left" style={{fontSize: "1rem"}}>Remix Advanced</label> <label className="m-0 float-left" style={{fontSize: "1rem"}}>Remix Advanced</label>
{(state.visibleTutorial === VisibleTutorial.Advanced) && <div className="pt-2 d-flex flex-column text-left">Learn the Proxy Pattern and working with Libraries in Remix. Learn to use the Debugger. {(state.visibleTutorial === VisibleTutorial.Advanced) && <div className="pt-2 d-flex flex-column text-left">Learn the Proxy Pattern and working with Libraries in Remix. Learn to use the Debugger.
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('deploylibraries')}>Get Started</button> <button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('deploylibraries')}>Get Started</button>
</div>} </div>}

@ -23,7 +23,7 @@ function PluginButton ({ imgPath, envID, envText, callback, l2, description, rem
onClick={() => callback()} onClick={() => callback()}
> >
<img className="px-2 mb-2 align-self-center remixui_home_envLogo" id={envID} src={imgPath} alt="" style={ { filter: themeFilter.filter } } /> <img className="px-2 mb-2 align-self-center remixui_home_envLogo" id={envID} src={imgPath} alt="" style={ { filter: themeFilter.filter } } />
<div className="h-100 d-flex flex-column"> <div className="mb-2 h-100 d-flex flex-column">
<label className="text-uppercase text-dark remixui_home_cursorStyle">{envText}</label> <label className="text-uppercase text-dark remixui_home_cursorStyle">{envText}</label>
<div className="remixui_home_envLogoDescription">{description}</div> <div className="remixui_home_envLogoDescription">{description}</div>
</div> </div>

@ -16,7 +16,7 @@ function WorkspaceTemplate ({ gsID, workspaceTitle, description, callback }: Wor
data-id={'landingPageStart' + gsID} data-id={'landingPageStart' + gsID}
onClick={() => callback()} onClick={() => callback()}
> >
<div className="w-100 p-2 h-100 align-items-start d-flex flex-column"> <div className="mb-2 w-100 p-2 h-100 align-items-start d-flex flex-column">
<label className="h6 pb-1 text-uppercase text-dark remixui_home_cursorStyle">{workspaceTitle}</label> <label className="h6 pb-1 text-uppercase text-dark remixui_home_cursorStyle">{workspaceTitle}</label>
<div className="remixui_home_gtDescription">{description}</div> <div className="remixui_home_gtDescription">{description}</div>
</div> </div>

@ -1,11 +1,9 @@
.remixui_home_text { .remixui_home_text {
cursor: pointer;
font-size: 0.8rem; font-size: 0.8rem;
font-weight: normal; font-weight: normal;
max-width: 300px; max-width: 300px;
} }
.remixui_home_text:hover { .remixui_home_text:hover {
cursor: pointer;
text-decoration: underline; text-decoration: underline;
} }
.remixui_home_homeContainer { .remixui_home_homeContainer {

Loading…
Cancel
Save