Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow to upload larger images without cropping any part of the image #102

Merged
merged 31 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7659e81
Allow to upload larger images without cropping any part of the image
AfonsoMartins26 Jul 23, 2024
17c64ad
Code formating
AfonsoMartins26 Jul 23, 2024
8e8f300
improvements
AfonsoMartins26 Jul 28, 2024
7eb03b4
Improvements from last review
AfonsoMartins26 Jul 29, 2024
2fb28fc
orientation default to vertical
AfonsoMartins26 Jul 30, 2024
988f474
chages done
AfonsoMartins26 Aug 6, 2024
af1b22e
Image too big in mobile
AfonsoMartins26 Aug 8, 2024
e78625c
Not complete
AfonsoMartins26 Aug 19, 2024
01c169d
Not complete
AfonsoMartins26 Aug 22, 2024
3511e02
it's still not working
AfonsoMartins26 Aug 29, 2024
f5829fd
it's working but was some white lines
AfonsoMartins26 Sep 1, 2024
647272d
Format code
AfonsoMartins26 Sep 1, 2024
182a0d4
Final code
AfonsoMartins26 Sep 2, 2024
2ca6360
Format code
AfonsoMartins26 Sep 2, 2024
d03807f
Lint code
AfonsoMartins26 Sep 2, 2024
52a4cd0
experimental elim
AfonsoMartins26 Sep 3, 2024
39db750
Update next.config.js
AfonsoMartins26 Sep 3, 2024
582cf87
experimental elim
AfonsoMartins26 Sep 3, 2024
dd77a41
mobile version not complete
AfonsoMartins26 Sep 4, 2024
bee0b1a
Mobile code complete
AfonsoMartins26 Sep 5, 2024
aad6ac1
text fix for mobile
AfonsoMartins26 Sep 6, 2024
5b6b144
format code
AfonsoMartins26 Sep 6, 2024
acc9c7a
change popup width and height mobile
AfonsoMartins26 Sep 10, 2024
8b6b49e
Long text fix mobile
AfonsoMartins26 Sep 11, 2024
918792f
popup wrapper padding
AfonsoMartins26 Sep 11, 2024
14f0382
Requested changes
AfonsoMartins26 Sep 11, 2024
295da4e
Format code
AfonsoMartins26 Sep 11, 2024
a45e096
Problem Solved?
AfonsoMartins26 Sep 14, 2024
61a683b
Merge branch 'main' into am/Modal
AfonsoMartins26 Sep 14, 2024
6419de8
remove useMemo
AfonsoMartins26 Sep 16, 2024
8ce63f5
Format code
AfonsoMartins26 Sep 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 60 additions & 31 deletions components/Marker/Marker.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useMemo } from 'react';
import Image from 'next/image';
import { useState, useMemo, useEffect } from 'react';
import { Marker as MarkerContainer, Popup } from 'react-leaflet';
import { IPin } from '~/lib/types';
import { getRelativeTimeString, getNameString, getDistance } from '~/lib/utils';
import { getIcon, getFullDateString } from './utils';
import AuthorIcon from '../AuthorIcon';

import styles from './style.module.css';
import localStyles from './style.module.css';
import 'styles/globals.css';
import Image from 'next/image';

const Marker = ({
type,
Expand All @@ -15,47 +15,76 @@ const Marker = ({
country,
author,
photo,
date
date,
orientation
}: IPin) => {
const icon = getIcon(type);

const icon = useMemo(() => getIcon(type), [type]);
const name = useMemo(() => getNameString(author), [author]);

const [imageOrientation, setImageOrientation] = useState(
joaodiaslobo marked this conversation as resolved.
Show resolved Hide resolved
orientation || 'vertical'
);

const handleImageLoad = (img: HTMLImageElement): void => {
setImageOrientation(img.width > img.height ? 'horizontal' : 'vertical');
};

const popupClassName = useMemo(() => {
const isMobile = window.innerWidth <= 500;

if (isMobile) {
return imageOrientation === 'horizontal' ? '401:250' : '351:550';
} else {
return imageOrientation === 'horizontal' ? '651:400' : '301:470';
}
}, [imageOrientation]);

joaodiaslobo marked this conversation as resolved.
Show resolved Hide resolved
useEffect(() => {
if (orientation || !photo) return;
const img = new window.Image();
img.src = photo;
img.onload = () => handleImageLoad(img);
}, [photo, orientation]);

const [width, height] = useMemo(
() => popupClassName.split(':').map(Number),
[popupClassName]
);

return (
<MarkerContainer
icon={icon}
position={coordinates}
title={`${name} at ${city}`}
>
<Popup>
<div>
<div className={styles.background}>
<div className={styles.text}>
<h1 className={styles.title}>
{city}, {country}
</h1>
<span className={styles.light}>
<i className="bi bi-calendar"></i> {getFullDateString(date)} (
{getRelativeTimeString(date)})
</span>
<br />
<span className={styles.light}>
<i className="bi bi-signpost-fill"></i>{' '}
{Math.round(getDistance(coordinates))} km away
</span>
<br />
<span>
<AuthorIcon author={author} /> {name}
</span>
</div>
</div>
<Popup className={localStyles.popup}>
<div className={localStyles.imageContainer} style={{ width, height }}>
<Image
alt={`${name} at ${city}`}
src={photo}
width={width}
height={height}
layout="fill"
objectFit="cover"
className={styles.image}
className={localStyles.roundedImage}
/>
<div className={localStyles.textOverlay}>
<h1 className={localStyles.title}>
{city}, {country}
</h1>
<span className={localStyles.light}>
<i className="bi bi-calendar"></i> {getFullDateString(date)} (
{getRelativeTimeString(date)})
</span>
<br />
<span className={localStyles.light}>
<i className="bi bi-signpost-fill"></i>{' '}
{Math.round(getDistance(coordinates))} km away
</span>
<br />
<span>
<AuthorIcon author={author} /> {name}
</span>
</div>
</div>
</Popup>
</MarkerContainer>
Expand Down
70 changes: 49 additions & 21 deletions components/Marker/style.module.css
Original file line number Diff line number Diff line change
@@ -1,41 +1,69 @@
.background {
.imageContainer {
position: relative;
border-radius: 10px;
overflow: hidden;
}

.popup {
overflow: hidden;
border-radius: 10px;
}

.image {
object-fit: cover;
border-radius: 10px;
}

.textOverlay {
position: absolute;
z-index: 1;
bottom: 0px;
left: 0px;
bottom: 0;
left: 0;
right: 0;
z-index: 2;
padding: 20px;
background: linear-gradient(
360deg,
rgba(0, 0, 0, 0.7) 0%,
rgba(255, 255, 255, 0) 55%
);
width: 100%;
height: 95%;
border-radius: 10px;
}

.text {
position: absolute;
z-index: 2;
color: white;
bottom: 20px;
left: 20px;
right: 20px;
text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.6);
font-weight: 500;
font-family: Inter, sans-serif;
line-height: 1.6;
color: white;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}

.title {
margin: 0 0 10px;
font-size: 25px;
line-height: 1.2;
}

.light {
font-weight: 400;
font-size: 14px;
opacity: 1;
}

.image {
border-radius: 10px;
overflow: hidden;
z-index: 0;
@media (max-width: 500px) {
.title {
margin: 0 0 10px;
font-size: 20px;
line-height: 1;
}

.light {
font-size: 12px;
opacity: 1;
}
}
.horizontal img {
width: 651px !important;
height: 400px !important;
}

.vertical img {
width: 301px !important;
height: 470px !important;
}
1 change: 1 addition & 0 deletions lib/types/pin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export interface IPin {
photo: string;
type?: EPinType;
streetview?: string;
orientation?: string;
}
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/basic-features/typescript for more information.
84 changes: 84 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 56 additions & 2 deletions styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,67 @@ body {
border-radius: 10px;
background: rgba(0, 0, 0, 0.2);
}

::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.4);
}

.leaflet-popup-content {
width: 301px;
height: 470px;
width: auto !important;
max-width: none !important;
margin: 0 !important;
padding: 0 !important;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 10px;
overflow: hidden;
}

.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white !important;
border: none !important;
border-radius: 12px;
padding: 0px;
}

.leaflet-popup-content-wrapper img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
display: block;
border-radius: 10px;
border: none !important;
}

@media (max-width: 500px) {
.leaflet-popup-content-wrapper {
margin: 0 !important;
padding: 0 !important;
}

.horizontal .leaflet-popup-content-wrapper {
width: 401px !important;
height: 250px !important;
}

.vertical .leaflet-popup-content-wrapper {
width: 351px !important;
height: 550px !important;
}
}

.textOverlay {
padding: 10px;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.5);
color: white;
border-radius: 0 0 15px 15px;
}

.custom-marker-cluster {
Expand Down
Loading