Skip to content

Commit

Permalink
Merge pull request #174 from RunOnFlux/development
Browse files Browse the repository at this point in the history
v1.4.0
  • Loading branch information
TheTrunk authored Apr 22, 2024
2 parents ce01a2c + 3fd5933 commit 5235615
Show file tree
Hide file tree
Showing 20 changed files with 659 additions and 56 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ssp-wallet",
"description": "Secure. Simple. Powerful.",
"private": true,
"version": "1.3.0",
"version": "1.4.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.3.0",
"version": "1.4.0",
"manifest_version": 3,
"name": "SSP Wallet",
"short_name": "SSP",
Expand Down
17 changes: 11 additions & 6 deletions src/components/AutoLogout/AutoLogout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { useEffect, useRef } from 'react';

import { useNavigate } from 'react-router-dom';

import { setSSPInitialState, setInitialStateForAllChains, setPasswordBlobInitialState } from '../../store';
import {
setSSPInitialState,
setInitialStateForAllChains,
setPasswordBlobInitialState,
setInitialContactsState,
} from '../../store';

import { useAppDispatch } from '../../hooks';

Expand All @@ -28,9 +33,8 @@ function AutoLogout() {
if (chrome?.storage?.session) {
try {
const curTime = new Date().getTime();
const resp: lastActivity = await chrome.storage.session.get(
'lastActivity',
);
const resp: lastActivity =
await chrome.storage.session.get('lastActivity');
if (typeof resp.lastActivity === 'number') {
if (resp.lastActivity + tenMins < curTime) {
logout();
Expand Down Expand Up @@ -77,7 +81,7 @@ function AutoLogout() {
console.log(error);
}
}
continueLogout()
continueLogout();
})();
};

Expand All @@ -88,9 +92,10 @@ function AutoLogout() {
setTimeout(() => {
setInitialStateForAllChains();
dispatch(setSSPInitialState());
dispatch(setInitialContactsState());
dispatch(setPasswordBlobInitialState());
}, 100);
}
};

return <></>;
}
Expand Down
11 changes: 11 additions & 0 deletions src/components/Contacts/Contacts.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.contact-name {
width: 215px;
word-break: break-all;
padding: 16px 10px !important;
}

.contact-address {
width: 145px;
word-break: break-all;
padding: 16px 10px !important;
}
32 changes: 32 additions & 0 deletions src/components/Contacts/Contacts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Button, Space } from 'antd';
import { useTranslation } from 'react-i18next';
import ContactsTable from './ContactsTable.tsx';
import ManageContact from './ManageContact.tsx';
import { useState } from 'react';

function Contacts() {
const { t } = useTranslation(['home']);
const [addOpen, setAddOpen] = useState(false);

const addContact = () => {
setAddOpen(true);
};

const manageContactAction = () => {
setAddOpen(false);
};

return (
<div>
<ContactsTable />
<Space size={'large'} style={{ marginTop: 16, marginBottom: 8 }}>
<Button type="primary" size="middle" onClick={() => addContact()}>
{t('home:contacts.create_new_contact')}
</Button>
</Space>
{addOpen && <ManageContact openAction={manageContactAction} />}
</div>
);
}

export default Contacts;
194 changes: 194 additions & 0 deletions src/components/Contacts/ContactsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { Table, Empty, message, Flex, Popconfirm, Button } from 'antd';
import { NoticeType } from 'antd/es/message/interface';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { useEffect, useState } from 'react';
import localForage from 'localforage';
const { Column } = Table;
import './Contacts.css';
import { useTranslation } from 'react-i18next';
import ManageContact from './ManageContact.tsx';
import { useAppSelector, useAppDispatch } from '../../hooks';
import { contact } from '../../types';
import { setContacts } from '../../store';

// name, ip, tier, status
function ContactsTable() {
const dispatch = useAppDispatch();
const { t } = useTranslation(['home', 'common']);
const { activeChain } = useAppSelector((state) => state.sspState);
const { contacts } = useAppSelector((state) => state.contacts);
const [contactsByName, setContactsByName] = useState(contacts[activeChain]);
const [manageOpen, setManageOpen] = useState(false);
const [manageContactId, setManageContactId] = useState<number>(-1);

const [messageApi, contextHolder] = message.useMessage();
const displayMessage = (type: NoticeType, content: string) => {
void messageApi.open({
type,
content,
});
};

useEffect(() => {
setManageOpen(manageContactId !== -1);
}, [manageContactId]);

const editContact = (id: number) => {
setManageContactId(id);
};

const deleteContact = (id: number) => {
const adjustedChainContacts: contact[] = [];
contacts[activeChain]?.forEach((contact: contact) => {
if (contact.id !== id) {
adjustedChainContacts.push(contact);
}
});

const completeContacts = {
...contacts,
[activeChain]: adjustedChainContacts,
};

// save
dispatch(setContacts(completeContacts));
void (async function () {
try {
await localForage.setItem('contacts', completeContacts);
} catch (error) {
console.log(error);
}
})();
console.log('delete contact', id);
};

// on chain change and on load, sort contacts and set it
useEffect(() => {
console.log(contacts[activeChain]);
const contactsCopy = [...contacts[activeChain]] || [];
const sortedContacts = contactsCopy.sort((a, b) => {
if (a.name > b.name) return 1;
else if (a.name < b.name) return -1;
else return 0;
});
setContactsByName(sortedContacts);
}, [contacts, activeChain]);

const manageContactAction = (status: boolean) => {
setManageOpen(false);
setManageContactId(-1);
if (status === true) {
displayMessage('success', t('home:contacts.contacts_updated'));
}
};

const renderAddress = (name: string) => {
if (name.length > 16)
return (
<>
{name.substring(0, 7)}...{name.substring(name.length - 6) || '---'}
</>
);

return <>{name || '---'}</>;
};

const renderName = (name: string, record: contact) => {
return (
<>
{name ||
new Date(record.id).toLocaleDateString() +
' ' +
new Date(record.id).toLocaleTimeString()}
</>
);
};

return (
<>
{contextHolder}
<Table
className="adjustedWidth"
locale={{
emptyText: (
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={<span>{t('home:contacts.no_contacts')}</span>}
/>
),
}}
pagination={false}
showHeader={false}
rowKey="address"
bordered={false}
loading={false}
dataSource={contactsByName}
expandable={{
showExpandColumn: false,
expandedRowRender: (record) => (
<div>
<p style={{ margin: 0, wordBreak: 'break-all' }}>
{t('common:name')}:{' '}
{record.name ||
new Date(record.id).toLocaleDateString() +
' ' +
new Date(record.id).toLocaleTimeString()}
</p>
<p style={{ wordBreak: 'break-all' }}>
{t('common:address')}: {record.address}
</p>
<p
style={{
marginBottom: 20,
wordBreak: 'break-all',
fontSize: 10,
}}
>
{t('home:contacts.created_at')}{' '}
{new Date(record.id).toLocaleDateString() +
' ' +
new Date(record.id).toLocaleTimeString()}
</p>
<Flex gap="small">
<Button size="middle" onClick={() => editContact(record.id)}>
{t('common:edit')}
</Button>
<Popconfirm
title={t('home:contacts.delete_contact')}
overlayStyle={{ maxWidth: 360, margin: 10 }}
okText={t('common:delete')}
cancelText={t('common:cancel')}
onConfirm={() => {
void deleteContact(record.id);
}}
icon={<QuestionCircleOutlined style={{ color: 'orange' }} />}
>
<Button size="middle">{t('common:delete')}</Button>
</Popconfirm>
</Flex>
</div>
),
expandRowByClick: true,
}}
>
<Column
title={t('common:name')}
dataIndex="name"
className="contact-name"
render={(name: string, row: contact) => renderName(name, row)}
/>
<Column
title={t('common:address')}
dataIndex="address"
className="contact-address"
render={(name: string) => renderAddress(name)}
/>
</Table>
{manageOpen && (
<ManageContact openAction={manageContactAction} id={manageContactId} />
)}
</>
);
}

export default ContactsTable;
Loading

0 comments on commit 5235615

Please sign in to comment.