-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[404; Landing; Loading] Replace tractor image with people images (#3064)
- Loading branch information
1 parent
5b6ba18
commit 7dbca7d
Showing
12 changed files
with
267 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { Dialog, IconButton, Typography } from "@mui/material"; | ||
import { type ReactElement, useState } from "react"; | ||
|
||
import ccIcon from "resources/cc-by-sa.png"; | ||
|
||
export interface ImageMetadata { | ||
name: string; | ||
nameHref?: string; | ||
by: string; | ||
byHref?: string; | ||
license: string; | ||
licenseHref?: string; | ||
cropped?: boolean; | ||
} | ||
|
||
interface ImageAttributionsButtonProps { | ||
images: ImageMetadata[]; | ||
width?: number; | ||
} | ||
|
||
/** Icon button for image attributions (assumes CC BY-SA) */ | ||
export default function ImageAttributionsButton( | ||
props: ImageAttributionsButtonProps | ||
): ReactElement { | ||
const [open, setOpen] = useState(false); | ||
return ( | ||
<> | ||
<IconButton | ||
aria-label="show image attribution" | ||
onClick={() => setOpen(true)} | ||
> | ||
<img | ||
alt="CreativeCommons-Attribution-ShareAlike" | ||
src={ccIcon} | ||
style={{ width: props.width || 60 }} | ||
/> | ||
</IconButton> | ||
<Dialog open={open} onClose={() => setOpen(false)}> | ||
{props.images.map((image, index) => ( | ||
<ImageAttribution key={index} {...image} /> | ||
))} | ||
</Dialog> | ||
</> | ||
); | ||
} | ||
|
||
/** Typography with attribution info and links for an image */ | ||
function ImageAttribution(props: ImageMetadata): ReactElement { | ||
const nameLink = props.nameHref ? ( | ||
<a href={props.nameHref} rel="noreferrer" target="_blank"> | ||
{props.name} | ||
</a> | ||
) : ( | ||
props.name | ||
); | ||
const byLink = props.byHref ? ( | ||
<a href={props.byHref} rel="noreferrer" target="_blank"> | ||
{props.by} | ||
</a> | ||
) : ( | ||
props.by | ||
); | ||
const licenseLink = props.licenseHref ? ( | ||
<a href={props.licenseHref} rel="noreferrer" target="_blank"> | ||
{props.license} | ||
</a> | ||
) : ( | ||
props.license | ||
); | ||
return ( | ||
<Typography> | ||
{'• "'} | ||
{nameLink} | ||
{'" by '} | ||
{byLink} | ||
{props.cropped ? ", cropped" : ""} | ||
{", "} | ||
{licenseLink} | ||
</Typography> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { type AnimationOptionsWithOverrides, animate } from "motion"; | ||
import { type CSSProperties, type ReactElement, useEffect } from "react"; | ||
|
||
import ImageAttributions, { | ||
ImageMetadata, | ||
} from "components/HarvestThreshWinnow/ImageAttributions"; | ||
import imageLicenses from "resources/HTW-licenses.json"; | ||
import harvest from "resources/HTW1-harvest-Ethiopia.jpg"; | ||
import thresh from "resources/HTW2-thresh-Bangladesh.jpg"; | ||
import winnow from "resources/HTW3-winnow-India.jpg"; | ||
|
||
enum ImageAlt { | ||
License = "CC BY-SA 4.0 license", | ||
Harvest = "Harvesting in Ethiopia", | ||
Thresh = "Threshing in Bangladesh", | ||
Winnow = "Winnowing in India", | ||
} | ||
|
||
enum ImageId { | ||
License = "image-license", | ||
Harvest = "harvest-image", | ||
Thresh = "thresh-image", | ||
Winnow = "winnow-image", | ||
} | ||
|
||
const imageMetadata: ImageMetadata[] = [ | ||
imageLicenses.harvest, | ||
imageLicenses.thresh, | ||
imageLicenses.winnow, | ||
]; | ||
|
||
interface HarvestThreshWinnowProps { | ||
loading?: boolean; | ||
maxSize?: number; | ||
} | ||
|
||
// Opacity of the 3 images, each fading in then fading out while the next fades in. | ||
const opacityKeyframes1 = [0, 0.5, 1, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0]; | ||
const opacityKeyframes2 = [0, 0, 0, 0, 0.5, 1, 1, 0.5, 0, 0, 0, 0, 0]; | ||
const opacityKeyframes3 = [0, 0, 0, 0, 0, 0, 0, 0.5, 1, 1, 0.5, 0, 0]; | ||
|
||
/** A custom harvest-thresh-winnow image */ | ||
export default function HarvestThreshWinnow( | ||
props: HarvestThreshWinnowProps | ||
): ReactElement { | ||
useEffect(() => { | ||
if (props.loading) { | ||
const options: AnimationOptionsWithOverrides = { | ||
duration: 7, | ||
easing: "linear", | ||
repeat: Infinity, | ||
}; | ||
animate(`#${ImageId.License}`, { opacity: opacityKeyframes1 }, options); | ||
animate(`#${ImageId.Harvest}`, { opacity: opacityKeyframes1 }, options); | ||
animate(`#${ImageId.Thresh}`, { opacity: opacityKeyframes2 }, options); | ||
animate(`#${ImageId.Winnow}`, { opacity: opacityKeyframes3 }, options); | ||
} | ||
}, [props.loading]); | ||
|
||
const size = Math.min( | ||
0.75 * window.innerHeight, | ||
0.25 * window.innerWidth, | ||
props.maxSize || 1000 | ||
); | ||
|
||
const imageStyle: CSSProperties = { | ||
border: "1px solid black", | ||
borderRadius: size, | ||
position: "relative", | ||
width: size, | ||
}; | ||
|
||
const overlap = 0.23; | ||
|
||
return ( | ||
<div style={{ height: size, position: "relative", margin: 10 }}> | ||
<img | ||
alt={ImageAlt.Harvest} | ||
id={ImageId.Harvest} | ||
src={harvest} | ||
style={{ ...imageStyle, left: overlap * size }} | ||
/> | ||
<img | ||
alt={ImageAlt.Thresh} | ||
id={ImageId.Thresh} | ||
src={thresh} | ||
style={{ ...imageStyle }} | ||
/> | ||
<img | ||
alt={ImageAlt.Winnow} | ||
id={ImageId.Winnow} | ||
src={winnow} | ||
style={{ ...imageStyle, right: overlap * size }} | ||
/> | ||
<div | ||
id={ImageId.License} | ||
style={{ | ||
// Use -10 to offset the button padding | ||
bottom: -10, | ||
left: 0.2 * size - 10, | ||
position: "absolute", | ||
}} | ||
> | ||
<ImageAttributions images={imageMetadata} width={0.15 * size} /> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,23 @@ | ||
import { Typography } from "@mui/material"; | ||
import { animate } from "motion"; | ||
import { ReactElement, useEffect } from "react"; | ||
import { Box, Typography } from "@mui/material"; | ||
import { type ReactElement } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
|
||
import tractor from "resources/tractor.png"; | ||
import HarvestThreshWinnow from "components/HarvestThreshWinnow"; | ||
|
||
/** A custom loading page */ | ||
export default function Loading(): ReactElement { | ||
const { t } = useTranslation(); | ||
|
||
useEffect(() => { | ||
const half = window.innerWidth * 0.75; | ||
animate( | ||
"#loading-tractor", | ||
{ transform: [`translateX(${half}px)`, `translateX(-${half}px)`] }, | ||
{ duration: 10, repeat: Infinity, easing: "linear" } | ||
); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<Typography variant="h4" style={{ textAlign: "center" }}> | ||
{t("generic.loadingTitle")} | ||
</Typography> | ||
<img | ||
src={tractor} | ||
alt="Tractor" | ||
id="loading-tractor" | ||
style={{ width: "50%", margin: "0% 25%" }} | ||
/> | ||
<Typography variant="h5" style={{ textAlign: "center" }}> | ||
{t("generic.loadingText")} | ||
</Typography> | ||
</> | ||
<Box | ||
alignItems="center" | ||
display="flex" | ||
flexDirection="column" | ||
justifyContent="center" | ||
rowGap={3} | ||
> | ||
<Typography variant="h4">{t("generic.loadingTitle")}</Typography> | ||
<HarvestThreshWinnow loading /> | ||
<Typography variant="h5">{t("generic.loadingText")}</Typography> | ||
</Box> | ||
); | ||
} |
Oops, something went wrong.