You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
5.3 KiB
TypeScript
202 lines
5.3 KiB
TypeScript
5 years ago
|
// SPDX-FileCopyrightText: © 2017 EteSync Authors
|
||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||
|
|
||
4 years ago
|
import * as React from "react";
|
||
|
import moment from "moment";
|
||
7 years ago
|
|
||
4 years ago
|
import { List, ListItem, ListDivider as Divider } from "../widgets/List";
|
||
|
import IconHome from "@material-ui/icons/Home";
|
||
|
import IconDate from "@material-ui/icons/DateRange";
|
||
|
import CommunicationCall from "@material-ui/icons/Call";
|
||
|
import CommunicationChatBubble from "@material-ui/icons/ChatBubble";
|
||
|
import CommunicationEmail from "@material-ui/icons/Email";
|
||
|
import CopyIcon from "../icons/Copy";
|
||
7 years ago
|
|
||
4 years ago
|
import PimItemHeader from "../components/PimItemHeader";
|
||
7 years ago
|
|
||
4 years ago
|
import { ContactType } from "../pim-types";
|
||
|
import { IconButton, Avatar } from "@material-ui/core";
|
||
7 years ago
|
|
||
7 years ago
|
class Contact extends React.PureComponent {
|
||
6 years ago
|
public props: {
|
||
5 years ago
|
item?: ContactType;
|
||
7 years ago
|
};
|
||
|
|
||
6 years ago
|
public render() {
|
||
7 years ago
|
if (this.props.item === undefined) {
|
||
4 years ago
|
throw Error("Contact should be defined!");
|
||
7 years ago
|
}
|
||
|
|
||
7 years ago
|
const contact = this.props.item;
|
||
7 years ago
|
const name = contact.fn;
|
||
7 years ago
|
|
||
4 years ago
|
const revProp = contact.comp.getFirstProperty("rev");
|
||
7 years ago
|
const lastModified = (revProp) ?
|
||
4 years ago
|
"Modified: " + moment(revProp.getFirstValue().toJSDate()).format("LLLL") : undefined;
|
||
7 years ago
|
|
||
6 years ago
|
const lists = [];
|
||
7 years ago
|
|
||
7 years ago
|
function getAllType(
|
||
|
propName: string,
|
||
|
props: any,
|
||
7 years ago
|
valueToHref?: (value: string, type: string) => string,
|
||
|
primaryTransform?: (value: string, type: string) => string,
|
||
|
secondaryTransform?: (value: string, type: string) => string) {
|
||
7 years ago
|
|
||
|
return contact.comp.getAllProperties(propName).map((prop, idx) => {
|
||
7 years ago
|
const type = prop.toJSON()[1].type;
|
||
5 years ago
|
const values = prop.getValues().map((val) => {
|
||
|
const primaryText = primaryTransform ? primaryTransform(val, type) : val;
|
||
|
const clipboardButton = (
|
||
|
<IconButton
|
||
|
onClick={(e) => {
|
||
|
e.preventDefault();
|
||
|
(window as any).navigator.clipboard.writeText(primaryText);
|
||
|
}}
|
||
|
>
|
||
5 years ago
|
<CopyIcon />
|
||
5 years ago
|
</IconButton>
|
||
|
);
|
||
|
|
||
|
return (
|
||
|
<ListItem
|
||
|
key={idx}
|
||
|
href={valueToHref ? valueToHref(val, type) : undefined}
|
||
|
primaryText={primaryText}
|
||
|
rightIcon={clipboardButton}
|
||
|
secondaryText={secondaryTransform ? secondaryTransform(val, type) : type}
|
||
|
{...props}
|
||
|
/>
|
||
|
);
|
||
|
});
|
||
7 years ago
|
return values;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
lists.push(getAllType(
|
||
4 years ago
|
"tel",
|
||
7 years ago
|
{
|
||
|
leftIcon: <CommunicationCall />,
|
||
|
},
|
||
4 years ago
|
(x) => ("tel:" + x)
|
||
7 years ago
|
));
|
||
7 years ago
|
|
||
7 years ago
|
lists.push(getAllType(
|
||
4 years ago
|
"email",
|
||
7 years ago
|
{
|
||
6 years ago
|
leftIcon: <CommunicationEmail />,
|
||
7 years ago
|
},
|
||
4 years ago
|
(x) => ("mailto:" + x)
|
||
7 years ago
|
));
|
||
|
|
||
|
lists.push(getAllType(
|
||
4 years ago
|
"impp",
|
||
7 years ago
|
{
|
||
6 years ago
|
leftIcon: <CommunicationChatBubble />,
|
||
7 years ago
|
},
|
||
|
(x) => x,
|
||
4 years ago
|
(x) => (x.substring(x.indexOf(":") + 1)),
|
||
|
(x) => (x.substring(0, x.indexOf(":")))
|
||
7 years ago
|
));
|
||
|
|
||
7 years ago
|
lists.push(getAllType(
|
||
4 years ago
|
"adr",
|
||
7 years ago
|
{
|
||
6 years ago
|
leftIcon: <IconHome />,
|
||
|
}
|
||
7 years ago
|
));
|
||
|
|
||
|
lists.push(getAllType(
|
||
4 years ago
|
"bday",
|
||
7 years ago
|
{
|
||
6 years ago
|
leftIcon: <IconDate />,
|
||
7 years ago
|
},
|
||
|
undefined,
|
||
4 years ago
|
((x: any) => moment(x.toJSDate()).format("dddd, LL")),
|
||
|
() => "Birthday"
|
||
7 years ago
|
));
|
||
|
|
||
7 years ago
|
lists.push(getAllType(
|
||
4 years ago
|
"anniversary",
|
||
7 years ago
|
{
|
||
6 years ago
|
leftIcon: <IconDate />,
|
||
7 years ago
|
},
|
||
|
undefined,
|
||
4 years ago
|
((x: any) => moment(x.toJSDate()).format("dddd, LL")),
|
||
|
() => "Anniversary"
|
||
7 years ago
|
));
|
||
|
|
||
4 years ago
|
const skips = ["tel", "email", "impp", "adr", "bday", "anniversary", "rev",
|
||
|
"prodid", "uid", "fn", "n", "version", "photo", "note"];
|
||
7 years ago
|
const theRest = contact.comp.getAllProperties().filter((prop) => (
|
||
7 years ago
|
skips.indexOf(prop.name) === -1
|
||
5 years ago
|
)).map((prop, idx) => {
|
||
7 years ago
|
const values = prop.getValues().map((_val) => {
|
||
|
const val = (_val instanceof String) ? _val : _val.toString();
|
||
|
return (
|
||
|
<ListItem
|
||
|
key={idx}
|
||
6 years ago
|
insetChildren
|
||
7 years ago
|
primaryText={val}
|
||
7 years ago
|
secondaryText={prop.name}
|
||
|
/>
|
||
|
);
|
||
|
});
|
||
|
return values;
|
||
|
});
|
||
7 years ago
|
|
||
4 years ago
|
{
|
||
4 years ago
|
const note = contact.comp.getFirstPropertyValue("note");
|
||
4 years ago
|
const item = (
|
||
|
<ListItem
|
||
|
key="note"
|
||
|
insetChildren
|
||
|
secondaryText="note"
|
||
|
>
|
||
4 years ago
|
<pre style={{ wordWrap: "break-word", whiteSpace: "pre-wrap", overflowX: "auto" }}>{note}</pre>
|
||
4 years ago
|
</ListItem>
|
||
|
);
|
||
|
theRest.push([item]);
|
||
|
}
|
||
|
|
||
6 years ago
|
function listIfNotEmpty(items: JSX.Element[][]) {
|
||
7 years ago
|
if (items.length > 0) {
|
||
|
return (
|
||
7 years ago
|
<React.Fragment>
|
||
7 years ago
|
<List>
|
||
|
{items}
|
||
|
</List>
|
||
7 years ago
|
<List>
|
||
6 years ago
|
<Divider inset />
|
||
7 years ago
|
</List>
|
||
7 years ago
|
</React.Fragment>
|
||
7 years ago
|
);
|
||
|
} else {
|
||
|
return undefined;
|
||
|
}
|
||
|
}
|
||
|
|
||
4 years ago
|
const contactImageSrc = contact.comp.getFirstProperty("photo")?.getFirstValue();
|
||
4 years ago
|
|
||
7 years ago
|
return (
|
||
|
<div>
|
||
4 years ago
|
<PimItemHeader text={name} rightItem={contactImageSrc && (<Avatar style={{ width: "3em", height: "3em" }} src={contactImageSrc} />)}>
|
||
7 years ago
|
{lastModified && (
|
||
4 years ago
|
<span style={{ fontSize: "90%" }}>{lastModified}</span>
|
||
7 years ago
|
)}
|
||
|
</PimItemHeader>
|
||
7 years ago
|
{lists.map((list, idx) => (
|
||
|
<React.Fragment key={idx}>
|
||
|
{listIfNotEmpty(list)}
|
||
|
</React.Fragment>
|
||
5 years ago
|
))}
|
||
7 years ago
|
<List>
|
||
|
{theRest}
|
||
|
</List>
|
||
|
</div>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
7 years ago
|
|
||
7 years ago
|
export default Contact;
|