Refactoring to see if (and how easy) it is to use the same chat component (with its properties) in 2 different contextes.

This commit is contained in:
Eric van der Vlist 2022-10-11 23:18:23 +02:00
parent 9bb2f48d4a
commit dca68e17e4
2 changed files with 15 additions and 134 deletions

View File

@ -1,11 +1,7 @@
import { locationOutline } from 'ionicons/icons';
import React, { useId } from 'react'; import React, { useId } from 'react';
import { useSelector } from 'react-redux';
import { geoPoint, lat2tile, lon2tile, Point } from '../../lib/geo'; import { geoPoint, lat2tile, lon2tile, Point } from '../../lib/geo';
import { MapState } from '../../store/map';
import { getSTile } from './Reticle';
import { tileProviders } from './tile'; import { tileProviders } from './tile';
interface AvatarForLocationProps { interface AvatarForLocationProps {

View File

@ -12,24 +12,12 @@ import {
IonSpinner, IonSpinner,
} from '@ionic/react'; } from '@ionic/react';
import React, { Fragment, useRef, useState } from 'react'; import React, { Fragment, useRef, useState } from 'react';
import {
MainContainer,
Sidebar,
ConversationList,
Conversation,
ConversationHeader,
ChatContainer,
MessageList,
Message,
Avatar,
} from '@chatscope/chat-ui-kit-react';
import '@chatscope/chat-ui-kit-styles/dist/default/styles.min.css';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import i18n from '../../i18n'; import i18n from '../../i18n';
import { geoPoint } from '../../lib/geo'; import { geoPoint } from '../../lib/geo';
import { MapState } from '../../store/map'; import { MapState } from '../../store/map';
import AvatarForLocation from './AvatarForLocation'; import OsmNotesChat from './OsmNotesChat';
const LocationInfo: React.FC<{}> = () => { const LocationInfo: React.FC<{}> = () => {
const scope = useSelector((state: { map: MapState }) => state.map.scope); const scope = useSelector((state: { map: MapState }) => state.map.scope);
@ -72,10 +60,17 @@ const LocationInfo: React.FC<{}> = () => {
console.log(`address: ${JSON.stringify(data)}`); console.log(`address: ${JSON.stringify(data)}`);
setAddress(data); setAddress(data);
}; };
const roughDistance = (a: geoPoint, b: geoPoint): number => {
const pseudoDistanceInDegrees = Math.sqrt(
(a.lat - b.lat) ** 2 + (a.lon - b.lon) ** 2
);
const metresPerDegree =
111111 * Math.cos((scope.center.lat * Math.PI) / 180);
return pseudoDistanceInDegrees * metresPerDegree;
};
const findNotes = async () => { const findNotes = async () => {
setNotes(undefined); setNotes(undefined);
setNoteIndex(0);
const metresPerDegree = const metresPerDegree =
111111 * Math.cos((scope.center.lat * Math.PI) / 180); 111111 * Math.cos((scope.center.lat * Math.PI) / 180);
const deltaDegrees = 5000 / metresPerDegree; const deltaDegrees = 5000 / metresPerDegree;
@ -109,15 +104,6 @@ const LocationInfo: React.FC<{}> = () => {
findNotes(); findNotes();
}; };
const roughDistance = (a: geoPoint, b: geoPoint): number => {
const pseudoDistanceInDegrees = Math.sqrt(
(a.lat - b.lat) ** 2 + (a.lon - b.lon) ** 2
);
const metresPerDegree =
111111 * Math.cos((scope.center.lat * Math.PI) / 180);
return pseudoDistanceInDegrees * metresPerDegree;
};
const localDate = (isoDate: string) => { const localDate = (isoDate: string) => {
const date = new Date(isoDate); const date = new Date(isoDate);
const format = new Intl.DateTimeFormat(i18n.getLanguage(), { const format = new Intl.DateTimeFormat(i18n.getLanguage(), {
@ -127,32 +113,12 @@ const LocationInfo: React.FC<{}> = () => {
return format.format(date); return format.format(date);
}; };
const [noteIndex, setNoteIndex] = useState(0); const osmNotesChat =
const conversationClickHandlerFactory = (index: number) => (event: any) => { notes !== undefined && notes.features.length ? (
setNoteIndex(index); <OsmNotesChat notes={notes} />
}; ) : (
<></>
const AvatarForFeature: React.FC<{
feature: any;
size: number;
as: any;
}> = (props: { feature: any; size: number; as: any }) => {
const distance = roughDistance(scope.center, {
lon: props.feature.geometry.coordinates[0],
lat: props.feature.geometry.coordinates[1],
});
return (
<Avatar size={props.size <= 50 ? 'sm' : 'lg'}>
<AvatarForLocation
location={{
lon: props.feature.geometry.coordinates[0],
lat: props.feature.geometry.coordinates[1],
}}
size={props.size}
/>
</Avatar>
); );
};
return ( return (
<IonModal <IonModal
@ -210,88 +176,7 @@ const LocationInfo: React.FC<{}> = () => {
{notes === undefined && <IonSpinner name='lines' />} {notes === undefined && <IonSpinner name='lines' />}
</IonLabel> </IonLabel>
</IonListHeader> </IonListHeader>
{notes !== undefined && notes.features.length > 0 && ( {osmNotesChat}
<div style={{ position: 'relative' }}>
<MainContainer responsive>
<Sidebar position='left' id='chat-sidebar'>
<ConversationList>
{notes
.features!.slice(0, 5)
.map((feature: any, index: number) => (
<Conversation
onClick={conversationClickHandlerFactory(index)}
key={feature.properties.id}
name={i18n.locationInfo!.at!(
roughDistance(scope.center, {
lon: feature.geometry.coordinates[0],
lat: feature.geometry.coordinates[1],
})
)}
info={feature.properties.status}
>
<AvatarForFeature
feature={feature}
size={42}
as={Avatar}
/>
</Conversation>
))}
</ConversationList>
</Sidebar>
<ChatContainer>
<ConversationHeader>
<AvatarForFeature
feature={notes.features[noteIndex]}
size={68}
as={Avatar}
/>
<ConversationHeader.Content>
<span
style={{
alignSelf: 'flex-center',
}}
>
{i18n.locationInfo!.at!(
roughDistance(scope.center, {
lon: notes.features[noteIndex].geometry
.coordinates[0],
lat: notes.features[noteIndex].geometry
.coordinates[1],
})
)}
</span>
</ConversationHeader.Content>
</ConversationHeader>
<MessageList>
{noteIndex < notes.features.length &&
notes.features[noteIndex].properties.comments.map(
(comment: any, index: number) => (
<Message
key={`${notes.features[noteIndex].properties.id}/${index}`}
model={{
direction: 'incoming',
position: 'single',
sender: comment.user,
sentTime: comment.date,
payload: comment.html,
}}
>
<Message.Header
sender={comment.user}
sentTime={comment.date}
/>
<Message.Footer sentTime={comment.action} />
<Avatar>
{comment.user ? comment.user : '??'}
</Avatar>
</Message>
)
)}
</MessageList>
</ChatContainer>
</MainContainer>
</div>
)}
</IonList> </IonList>
</IonContent> </IonContent>
</IonModal> </IonModal>