mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 11:20:17 -04:00
organize code for optimal path, ensure miles are used
This commit is contained in:
parent
fa5a9df5da
commit
052236e20a
|
@ -1,10 +1,9 @@
|
||||||
import CancelIcon from '@material-ui/icons/Cancel';
|
import CancelIcon from '@material-ui/icons/Cancel';
|
||||||
import CheckIcon from '@material-ui/icons/Check';
|
import CheckIcon from '@material-ui/icons/Check';
|
||||||
import EmojiPeopleIcon from '@material-ui/icons/EmojiPeople';
|
import EmojiPeopleIcon from '@material-ui/icons/EmojiPeople';
|
||||||
import { useEffect } from 'react';
|
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { useCallback, useContext, useMemo, useState } from 'react';
|
|
||||||
import { lightgrey } from '../../lib/colors';
|
import { lightgrey } from '../../lib/colors';
|
||||||
import furthestPoint from '../../lib/furthestpoint';
|
import { Location } from '../../lib/estimateoptimalpath';
|
||||||
import {
|
import {
|
||||||
useCancelCarpoolRequest,
|
useCancelCarpoolRequest,
|
||||||
useInvitationState,
|
useInvitationState,
|
||||||
|
@ -15,9 +14,33 @@ import { useMe } from '../hooks';
|
||||||
import { IEvent } from '../types';
|
import { IEvent } from '../types';
|
||||||
import UIButton from '../UI/UIButton';
|
import UIButton from '../UI/UIButton';
|
||||||
import UILink from '../UI/UILink';
|
import UILink from '../UI/UILink';
|
||||||
import EventContext from './EventContext';
|
import useOptimalPath from '../useOptimalPath';
|
||||||
import estimateOptimalPath, { Location } from '../../lib/estimateoptimalpath';
|
|
||||||
import usePlace from '../usePlace';
|
import usePlace from '../usePlace';
|
||||||
|
import EventContext from './EventContext';
|
||||||
|
|
||||||
|
function useMemberLocations(members: IEvent['carpools'][0]['members']) {
|
||||||
|
const { signups } = useContext(EventContext);
|
||||||
|
|
||||||
|
return useMemo(
|
||||||
|
() =>
|
||||||
|
members
|
||||||
|
.map((member) => {
|
||||||
|
const signup = signups[member.id];
|
||||||
|
if (!signup) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (signup.latitude === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
latitude: signup.latitude,
|
||||||
|
longitude: signup.longitude,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(Boolean) as Location[],
|
||||||
|
[members, signups]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function CarpoolRow({
|
function CarpoolRow({
|
||||||
carpool,
|
carpool,
|
||||||
|
@ -32,8 +55,6 @@ function CarpoolRow({
|
||||||
const cancelCarpoolRequest = useCancelCarpoolRequest();
|
const cancelCarpoolRequest = useCancelCarpoolRequest();
|
||||||
const sendCarpoolRequest = useSendCarpoolRequest();
|
const sendCarpoolRequest = useSendCarpoolRequest();
|
||||||
|
|
||||||
const { signups } = useContext(EventContext);
|
|
||||||
|
|
||||||
const sendButton = useCallback(() => {
|
const sendButton = useCallback(() => {
|
||||||
sendCarpoolRequest(carpool.id);
|
sendCarpoolRequest(carpool.id);
|
||||||
}, [sendCarpoolRequest, carpool.id]);
|
}, [sendCarpoolRequest, carpool.id]);
|
||||||
|
@ -49,53 +70,25 @@ function CarpoolRow({
|
||||||
|
|
||||||
const myLocation = usePlace(myPlaceId);
|
const myLocation = usePlace(myPlaceId);
|
||||||
|
|
||||||
const extraDistance = useMemo(() => {
|
const memberLocations = useMemberLocations(carpool.members);
|
||||||
if (!myLocation) {
|
|
||||||
console.log('!myLocation');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculates the minimum distance if I'm in the carpool
|
const pathInCarpool = useOptimalPath(memberLocations, {
|
||||||
// and subtracts the distance if I'm not in the carpool
|
latitude,
|
||||||
|
longitude,
|
||||||
|
});
|
||||||
|
|
||||||
const memberLocations = carpool.members
|
const pathNotInCarpool = useOptimalPath(
|
||||||
.map((member) => {
|
myLocation ? [...memberLocations, myLocation] : [],
|
||||||
const signup = signups[member.id];
|
{
|
||||||
if (!signup) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
latitude: signup.latitude,
|
|
||||||
longitude: signup.longitude,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter(Boolean) as Location[];
|
|
||||||
|
|
||||||
const { maxLocation: driverLocation } = furthestPoint(memberLocations, {
|
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const passengerLocations = memberLocations.filter(
|
const extraDistance =
|
||||||
(location) => location !== driverLocation
|
myLocation && pathInCarpool && pathNotInCarpool
|
||||||
);
|
? pathInCarpool.distance - pathNotInCarpool.distance
|
||||||
|
: null;
|
||||||
const { distance: distanceInCarpool } = estimateOptimalPath({
|
|
||||||
from: driverLocation,
|
|
||||||
waypoints: [...passengerLocations, myLocation],
|
|
||||||
to: { latitude, longitude },
|
|
||||||
});
|
|
||||||
|
|
||||||
const { distance: distanceNotInCarpool } = estimateOptimalPath({
|
|
||||||
from: driverLocation,
|
|
||||||
waypoints: passengerLocations,
|
|
||||||
to: { latitude, longitude },
|
|
||||||
});
|
|
||||||
|
|
||||||
return distanceInCarpool - distanceNotInCarpool;
|
|
||||||
}, [carpool.members, latitude, longitude, myLocation, signups]);
|
|
||||||
|
|
||||||
console.log(carpool.id, extraDistance);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -113,20 +106,16 @@ function CarpoolRow({
|
||||||
>
|
>
|
||||||
{/* <div> */}
|
{/* <div> */}
|
||||||
<span
|
<span
|
||||||
style={{ fontWeight: 600, cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.location.href = '/carpools/' + carpool.id;
|
window.location.href = '/carpools/' + carpool.id;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{carpool.name} {extraDistance !== null && '+ ' + extraDistance}
|
<b>{carpool.name}</b>
|
||||||
|
{extraDistance !== null && ' +' + extraDistance.toFixed(1) + ' miles'}
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
{/* <div style={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
<CallMergeIcon style={{ marginRight: '1rem' }} />{' '}
|
|
||||||
<b>{carpool.extraDistance} miles</b>
|
|
||||||
</div> */}
|
|
||||||
{/* </div> */}
|
|
||||||
{!inCarpoolAlready && (
|
{!inCarpoolAlready && (
|
||||||
<>
|
<>
|
||||||
{inviteState === 'none' ? (
|
{inviteState === 'none' ? (
|
||||||
|
|
|
@ -28,7 +28,7 @@ function EventSignup({
|
||||||
hasCarpool,
|
hasCarpool,
|
||||||
} = useContext(EventContext);
|
} = useContext(EventContext);
|
||||||
|
|
||||||
let extraDistance = useMemo(() => {
|
const extraDistance = useMemo(() => {
|
||||||
if (myPlaceDetails != null && !(latitude === null || longitude === null)) {
|
if (myPlaceDetails != null && !(latitude === null || longitude === null)) {
|
||||||
const myLatitude = myPlaceDetails.latitude;
|
const myLatitude = myPlaceDetails.latitude;
|
||||||
const myLongitude = myPlaceDetails.longitude;
|
const myLongitude = myPlaceDetails.longitude;
|
||||||
|
@ -90,8 +90,10 @@ function EventSignup({
|
||||||
}}
|
}}
|
||||||
key={user.id}
|
key={user.id}
|
||||||
>
|
>
|
||||||
<b>{user.name}</b>
|
<span>
|
||||||
{extraDistance ? `: +${extraDistance.toFixed(1)} miles` : ''}
|
<b>{user.name}</b>
|
||||||
|
{extraDistance ? ` +${extraDistance.toFixed(1)} miles` : ''}
|
||||||
|
</span>
|
||||||
|
|
||||||
{!hasCarpool &&
|
{!hasCarpool &&
|
||||||
(isTentativelyInvited ? (
|
(isTentativelyInvited ? (
|
||||||
|
|
32
src/components/useOptimalPath.ts
Normal file
32
src/components/useOptimalPath.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import estimateOptimalPath, { Location } from '../lib/estimateoptimalpath';
|
||||||
|
import furthestPoint from '../lib/furthestpoint';
|
||||||
|
|
||||||
|
export default function useOptimalPath(
|
||||||
|
memberLocations: Location[],
|
||||||
|
destination: Location
|
||||||
|
) {
|
||||||
|
return useMemo(() => {
|
||||||
|
if (memberLocations.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// O(n)
|
||||||
|
const { maxLocation: driverLocation } = furthestPoint(
|
||||||
|
memberLocations,
|
||||||
|
destination
|
||||||
|
);
|
||||||
|
|
||||||
|
// O(n)
|
||||||
|
const passengerLocations = memberLocations.filter(
|
||||||
|
(location) => location !== driverLocation
|
||||||
|
);
|
||||||
|
|
||||||
|
// O(n)
|
||||||
|
return estimateOptimalPath({
|
||||||
|
from: driverLocation!,
|
||||||
|
waypoints: passengerLocations,
|
||||||
|
to: destination,
|
||||||
|
});
|
||||||
|
}, [destination, memberLocations]);
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ export default function furthestPoint(
|
||||||
destination: Location
|
destination: Location
|
||||||
) {
|
) {
|
||||||
let maxDistance = 0;
|
let maxDistance = 0;
|
||||||
let maxLocation = { latitude: 0, longitude: 0 };
|
let maxLocation = null;
|
||||||
for (let i = 0; i < locations.length; i++) {
|
for (let i = 0; i < locations.length; i++) {
|
||||||
let distance = getDistance(locations[i], destination);
|
let distance = getDistance(locations[i], destination);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Location } from './estimateoptimalpath';
|
import { Location } from './estimateoptimalpath';
|
||||||
import latlongdist from './latlongdist';
|
import latlongdist, { R_miles } from './latlongdist';
|
||||||
|
|
||||||
export default function getDistance(...locations: Location[]): number {
|
export default function getDistance(...locations: Location[]): number {
|
||||||
let distance = 0;
|
let distance = 0;
|
||||||
|
@ -10,7 +10,8 @@ export default function getDistance(...locations: Location[]): number {
|
||||||
from.latitude,
|
from.latitude,
|
||||||
from.longitude,
|
from.longitude,
|
||||||
to.latitude,
|
to.latitude,
|
||||||
to.longitude
|
to.longitude,
|
||||||
|
R_miles
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return distance;
|
return distance;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user