Better presentation of OSM notes.

This commit is contained in:
Eric van der Vlist 2022-10-10 19:13:14 +02:00
parent bdc527ae05
commit 6c0d3bfb11
4 changed files with 292 additions and 29 deletions

157
package-lock.json generated
View File

@ -20,6 +20,8 @@
"@capacitor/haptics": "4.0.1",
"@capacitor/keyboard": "4.0.1",
"@capacitor/status-bar": "4.0.1",
"@chatscope/chat-ui-kit-react": "^1.9.7",
"@chatscope/chat-ui-kit-styles": "^1.4.0",
"@ionic/react": "^6.2.6",
"@ionic/react-router": "^6.2.6",
"@openpgp/asmcrypto.js": "^2.3.2",
@ -35,6 +37,7 @@
"@types/react-dom": "^18.0.6",
"@types/react-router": "^5.1.11",
"@types/react-router-dom": "^5.1.7",
"avatar-initials": "^5.0.0",
"buffer": "^6.0.3",
"cordova-plugin-geolocation": "^4.1.0",
"crypto-browserify": "^3.12.0",
@ -2137,6 +2140,30 @@
"@capacitor/core": "^4.0.0"
}
},
"node_modules/@chatscope/chat-ui-kit-react": {
"version": "1.9.7",
"resolved": "https://registry.npmjs.org/@chatscope/chat-ui-kit-react/-/chat-ui-kit-react-1.9.7.tgz",
"integrity": "sha512-1Yj9ktmP/U576M9MFhBJ4me/HHMCcosBrJDCtZePnFShquAQIUPB2kOeNy+zMNIAYqYHkzj7VEm2DZfRxaFLFw==",
"dependencies": {
"@chatscope/chat-ui-kit-styles": "^1.2.0",
"@fortawesome/fontawesome-free": "^5.12.1",
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/react-fontawesome": "^0.1.8",
"classnames": "^2.2.6",
"prop-types": "^15.7.2"
},
"peerDependencies": {
"prop-types": "^15.7.2",
"react": "^16.12.0 || ^17.0.0 || ^18.2.0",
"react-dom": "^16.12.0 || ^17.0.0 || ^18.2.0"
}
},
"node_modules/@chatscope/chat-ui-kit-styles": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@chatscope/chat-ui-kit-styles/-/chat-ui-kit-styles-1.4.0.tgz",
"integrity": "sha512-016mBJD3DESw7Nh+lkKcPd22xG92ghA0VpIXIbjQtmXhC7Ve6wRazTy8z1Ahut+Tbv179+JxrftuMngsj/yV8Q=="
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
@ -2491,6 +2518,60 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@fortawesome/fontawesome-common-types": {
"version": "0.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz",
"integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/fontawesome-free": {
"version": "5.15.4",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",
"integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/fontawesome-svg-core": {
"version": "1.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz",
"integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-solid-svg-icons": {
"version": "5.15.4",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz",
"integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/react-fontawesome": {
"version": "0.1.19",
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz",
"integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@fortawesome/fontawesome-svg-core": "~1 || ~6",
"react": ">=16.x"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
@ -5553,6 +5634,14 @@
"postcss": "^8.1.0"
}
},
"node_modules/avatar-initials": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/avatar-initials/-/avatar-initials-5.0.0.tgz",
"integrity": "sha512-4fgzwu70faLzVIAXguRryGjJhfIz9XmXwTQTXUNTg1E+6Pf9dfuhr/1Hvs6mOrw7p0yEGnYKkBjniECxhXSbxw==",
"engines": {
"node": ">= 12"
}
},
"node_modules/axe-core": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz",
@ -6393,6 +6482,11 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
},
"node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clean-css": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
@ -21151,6 +21245,25 @@
"integrity": "sha512-BmEyOf3m/hAf8bO4hCX0m5gpQPSgd05mGYl+9E841WUZeJjcYlmiG/EBshAUb2uGCVtyNaG36yPXB0r0Ypg+rw==",
"requires": {}
},
"@chatscope/chat-ui-kit-react": {
"version": "1.9.7",
"resolved": "https://registry.npmjs.org/@chatscope/chat-ui-kit-react/-/chat-ui-kit-react-1.9.7.tgz",
"integrity": "sha512-1Yj9ktmP/U576M9MFhBJ4me/HHMCcosBrJDCtZePnFShquAQIUPB2kOeNy+zMNIAYqYHkzj7VEm2DZfRxaFLFw==",
"requires": {
"@chatscope/chat-ui-kit-styles": "^1.2.0",
"@fortawesome/fontawesome-free": "^5.12.1",
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/react-fontawesome": "^0.1.8",
"classnames": "^2.2.6",
"prop-types": "^15.7.2"
}
},
"@chatscope/chat-ui-kit-styles": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@chatscope/chat-ui-kit-styles/-/chat-ui-kit-styles-1.4.0.tgz",
"integrity": "sha512-016mBJD3DESw7Nh+lkKcPd22xG92ghA0VpIXIbjQtmXhC7Ve6wRazTy8z1Ahut+Tbv179+JxrftuMngsj/yV8Q=="
},
"@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
@ -21340,6 +21453,40 @@
}
}
},
"@fortawesome/fontawesome-common-types": {
"version": "0.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz",
"integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg=="
},
"@fortawesome/fontawesome-free": {
"version": "5.15.4",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",
"integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="
},
"@fortawesome/fontawesome-svg-core": {
"version": "1.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz",
"integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
}
},
"@fortawesome/free-solid-svg-icons": {
"version": "5.15.4",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz",
"integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
}
},
"@fortawesome/react-fontawesome": {
"version": "0.1.19",
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz",
"integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==",
"requires": {
"prop-types": "^15.8.1"
}
},
"@humanwhocodes/config-array": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
@ -23733,6 +23880,11 @@
"postcss-value-parser": "^4.2.0"
}
},
"avatar-initials": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/avatar-initials/-/avatar-initials-5.0.0.tgz",
"integrity": "sha512-4fgzwu70faLzVIAXguRryGjJhfIz9XmXwTQTXUNTg1E+6Pf9dfuhr/1Hvs6mOrw7p0yEGnYKkBjniECxhXSbxw=="
},
"axe-core": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz",
@ -24359,6 +24511,11 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
},
"classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"clean-css": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",

View File

@ -15,6 +15,8 @@
"@capacitor/haptics": "4.0.1",
"@capacitor/keyboard": "4.0.1",
"@capacitor/status-bar": "4.0.1",
"@chatscope/chat-ui-kit-react": "^1.9.7",
"@chatscope/chat-ui-kit-styles": "^1.4.0",
"@ionic/react": "^6.2.6",
"@ionic/react-router": "^6.2.6",
"@openpgp/asmcrypto.js": "^2.3.2",
@ -30,6 +32,7 @@
"@types/react-dom": "^18.0.6",
"@types/react-router": "^5.1.11",
"@types/react-router-dom": "^5.1.7",
"avatar-initials": "^5.0.0",
"buffer": "^6.0.3",
"cordova-plugin-geolocation": "^4.1.0",
"crypto-browserify": "^3.12.0",

View File

@ -14,6 +14,20 @@ import {
IonAccordion,
} from '@ionic/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 AvatarInitial from 'avatar-initials';
import { useSelector } from 'react-redux';
import i18n from '../../i18n';
import { geoPoint } from '../../lib/geo';
@ -103,6 +117,11 @@ const LocationInfo: React.FC<{}> = () => {
return format.format(date);
};
const [noteIndex, setNoteIndex] = useState(0);
const conversationClickHandlerFactory = (index: number) => (event: any) => {
setNoteIndex(index);
};
return (
<IonModal
trigger='information-request'
@ -160,40 +179,123 @@ const LocationInfo: React.FC<{}> = () => {
</IonLabel>
</IonListHeader>
{notes !== undefined && (
<IonAccordionGroup>
{notes.features.map((feature: any) => (
<IonAccordion key={feature.properties.id}>
<IonItem slot='header'>
<IonLabel>
{i18n.locationInfo!.at!(
<MainContainer>
<Sidebar position='left'>
<ConversationList>
{notes.features!.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],
})
)}
</IonLabel>
</IonItem>
<div className='ion-padding' slot='content'>
<IonList lines='full' class='ion-no-margin'>
<IonListHeader lines='full'>
<IonLabel>
{i18n.locationInfo!.created}
{localDate(feature.properties.date_created)}
{', '}
{feature.properties.status === 'open'
? i18n.locationInfo.status?.opened
: i18n.locationInfo.status?.closed}
{'.'}
</IonLabel>
</IonListHeader>
{feature.properties.comments.map((comment: any) => (
<IonItem>{comment.html}</IonItem>
info={feature.properties.status}
>
<Avatar
src={AvatarInitial.initialAvatar({
size: 100,
initials: Math.round(
roughDistance(scope.center, {
lon: feature.geometry.coordinates[0],
lat: feature.geometry.coordinates[1],
})
),
initial_fg: '#888888',
initial_bg: '#f4f6f7',
initial_size: 25, // Defaults to height / 2
initial_weight: 500,
initial_font_family:
"'Lato', 'Lato-Regular', 'Helvetica Neue'",
})}
/>
</Conversation>
))}
</IonList>
</div>
</IonAccordion>
))}
</IonAccordionGroup>
</ConversationList>
</Sidebar>
<ChatContainer>
<ConversationHeader>
<ConversationHeader.Content>
<span
style={{
color: '#ec1212',
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>
<Avatar
src={AvatarInitial.initialAvatar({
size: 100,
initials: Math.round(
roughDistance(scope.center, {
lon: notes.features[noteIndex].geometry
.coordinates[0],
lat: notes.features[noteIndex].geometry
.coordinates[1],
})
),
initial_fg: '#888888',
initial_bg: '#f4f6f7',
initial_size: 25, // Defaults to height / 2
initial_weight: 500,
initial_font_family:
"'Lato', 'Lato-Regular', 'Helvetica Neue'",
})}
name={i18n.locationInfo!.at!(
roughDistance(scope.center, {
lon: notes.features[noteIndex].geometry.coordinates[0],
lat: notes.features[noteIndex].geometry.coordinates[1],
})
)}
/>
</ConversationHeader>
<MessageList>
{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}
/>
<Avatar
src={AvatarInitial.initialAvatar({
size: 100,
initials: comment.user ? comment.user : '??',
initial_fg: '#888888',
initial_bg: '#f4f6f7',
initial_size: 0, // Defaults to height / 2
initial_weight: 500,
initial_font_family:
"'Lato', 'Lato-Regular', 'Helvetica Neue'",
})}
name={comment.user ? comment.user : 'anonymous'}
/>
</Message>
)
)}
</MessageList>
</ChatContainer>
</MainContainer>
)}
</IonList>
</IonContent>

View File

@ -0,0 +1 @@
declare module 'avatar-initials';