mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 20:49:16 +00:00
added remainder of details
This commit is contained in:
parent
a0bb8d5c6c
commit
1317c6f6d7
BIN
net/web/src/images/team.png
Normal file
BIN
net/web/src/images/team.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -1,10 +1,14 @@
|
|||||||
import avatar from 'images/avatar.png';
|
import avatar from 'images/avatar.png';
|
||||||
import appstore from 'images/appstore.png';
|
import appstore from 'images/appstore.png';
|
||||||
import solution from 'images/solution.png';
|
import solution from 'images/solution.png';
|
||||||
|
import team from 'images/team.png';
|
||||||
|
|
||||||
export function Logo({ url, width, height, radius, img }) {
|
export function Logo({ url, width, height, radius, img }) {
|
||||||
return (
|
return (
|
||||||
<div style={{ borderRadius: radius, overflow: 'hidden' }}>
|
<div style={{ borderRadius: radius, overflow: 'hidden' }}>
|
||||||
|
{ img === 'team' && (
|
||||||
|
<img src={team} alt="direct logo" width={width} height={height} />
|
||||||
|
)}
|
||||||
{ img === 'appstore' && (
|
{ img === 'appstore' && (
|
||||||
<img src={appstore} alt="group logo" width={width} height={height} />
|
<img src={appstore} alt="group logo" width={width} height={height} />
|
||||||
)}
|
)}
|
||||||
|
@ -4,7 +4,7 @@ import { CardSelectWrapper } from './CardSelect.styled';
|
|||||||
import { SelectItem } from './selectItem/SelectItem';
|
import { SelectItem } from './selectItem/SelectItem';
|
||||||
import { useCardSelect } from './useCardSelect.hook';
|
import { useCardSelect } from './useCardSelect.hook';
|
||||||
|
|
||||||
export function CardSelect({ filter, unknown, select, selected }) {
|
export function CardSelect({ filter, unknown, select, selected, markup }) {
|
||||||
|
|
||||||
const { state, actions } = useCardSelect(filter);
|
const { state, actions } = useCardSelect(filter);
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ export function CardSelect({ filter, unknown, select, selected }) {
|
|||||||
<CardSelectWrapper>
|
<CardSelectWrapper>
|
||||||
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.cards} gutter="0"
|
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.cards} gutter="0"
|
||||||
renderItem={item => (
|
renderItem={item => (
|
||||||
<SelectItem item={item} select={select} selected={selected} />
|
<SelectItem item={item} select={select} selected={selected} markup={markup} />
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</CardSelectWrapper>
|
</CardSelectWrapper>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Switch } from 'antd';
|
import { Switch, Tooltip } from 'antd';
|
||||||
import { SelectItemWrapper } from './SelectItem.styled';
|
import { SelectItemWrapper, Markup } from './SelectItem.styled';
|
||||||
import { useSelectItem } from './useSelectItem.hook';
|
import { useSelectItem } from './useSelectItem.hook';
|
||||||
import { Logo } from 'logo/Logo';
|
import { Logo } from 'logo/Logo';
|
||||||
|
|
||||||
export function SelectItem({ item, select, selected }) {
|
export function SelectItem({ item, select, selected, markup }) {
|
||||||
|
|
||||||
const { state, actions } = useSelectItem(item, selected);
|
const { state, actions } = useSelectItem(item, selected, markup);
|
||||||
const profile = item?.data?.cardProfile;
|
const profile = item?.data?.cardProfile;
|
||||||
const detail = item?.data?.cardDetail;
|
const detail = item?.data?.cardDetail;
|
||||||
|
|
||||||
@ -16,18 +16,31 @@ export function SelectItem({ item, select, selected }) {
|
|||||||
return profile?.handle;
|
return profile?.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onSelect = () => {
|
||||||
|
if (select) {
|
||||||
|
select(item.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectItemWrapper onClick={() => select(item.id)}>
|
<SelectItemWrapper onClick={onSelect}>
|
||||||
<Logo url={state.logo} width={32} height={32} radius={8} />
|
<div class={ state.className }>
|
||||||
<div class="details">
|
<Logo url={state.logo} width={32} height={32} radius={8} />
|
||||||
<div class="name">{ profile?.name }</div>
|
<div class="details">
|
||||||
<div class="handle">{ handle() }</div>
|
<div class="name">{ profile?.name }</div>
|
||||||
</div>
|
<div class="handle">{ handle() }</div>
|
||||||
{ select && (
|
|
||||||
<div class="switch">
|
|
||||||
<Switch checked={state.selected} onChange={() => select(item.id)} size="small" />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{ select && (
|
||||||
|
<div class="switch">
|
||||||
|
<Switch checked={state.selected} onChange={onSelect} size="small" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{ state.markup && (
|
||||||
|
<Tooltip placement="left" title="channel host">
|
||||||
|
<Markup />
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</SelectItemWrapper>
|
</SelectItemWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,27 @@ import styled from 'styled-components';
|
|||||||
import Colors from 'constants/Colors';
|
import Colors from 'constants/Colors';
|
||||||
|
|
||||||
export const SelectItemWrapper = styled.div`
|
export const SelectItemWrapper = styled.div`
|
||||||
height: 48px;
|
.active {
|
||||||
width: 100%;
|
cursor: pointer;
|
||||||
display: flex;
|
height: 48px;
|
||||||
align-items: center;
|
width: 100%;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: ${Colors.selectHover};
|
background-color: ${Colors.selectHover};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.passive {
|
||||||
|
height: 48px;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details {
|
.details {
|
||||||
@ -41,3 +52,12 @@ export const SelectItemWrapper = styled.div`
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export const Markup = styled.div`
|
||||||
|
background-color: ${Colors.connected};
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
margin-right: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { useContext, useState, useEffect } from 'react';
|
import { useContext, useState, useEffect } from 'react';
|
||||||
import { CardContext } from 'context/CardContext';
|
import { CardContext } from 'context/CardContext';
|
||||||
|
|
||||||
export function useSelectItem(item, selected) {
|
export function useSelectItem(item, selected, markup) {
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
logo: null,
|
logo: null,
|
||||||
selected: false,
|
selected: false,
|
||||||
busy: false,
|
busy: false,
|
||||||
|
className: 'passive',
|
||||||
|
markup: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const card = useContext(CardContext);
|
const card = useContext(CardContext);
|
||||||
@ -16,7 +18,12 @@ export function useSelectItem(item, selected) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateState({ selected: selected.has(item.id) });
|
if (selected) {
|
||||||
|
updateState({ className: 'active', selected: selected.has(item.id) });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateState({ className: 'passive', markup: item.id === markup });
|
||||||
|
}
|
||||||
}, [selected]);
|
}, [selected]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -17,7 +17,7 @@ export function useCardSelect(filter) {
|
|||||||
let contacts = Array.from(card.state.cards.values());
|
let contacts = Array.from(card.state.cards.values());
|
||||||
let filtered = contacts.filter(filter);
|
let filtered = contacts.filter(filter);
|
||||||
updateState({ cards: filtered });
|
updateState({ cards: filtered });
|
||||||
}, [card]);
|
}, [card, filter]);
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { ChannelItemWrapper } from './ChannelItem.styled';
|
import { Tooltip } from 'antd';
|
||||||
|
import { ChannelItemWrapper, Markup } from './ChannelItem.styled';
|
||||||
import { Logo } from 'logo/Logo';
|
import { Logo } from 'logo/Logo';
|
||||||
import { AppstoreFilled, SolutionOutlined } from '@ant-design/icons';
|
import { AppstoreFilled, SolutionOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
@ -39,7 +40,9 @@ export function ChannelItem({ item, openChannel }) {
|
|||||||
<div class="message">{ item.message }</div>
|
<div class="message">{ item.message }</div>
|
||||||
</div>
|
</div>
|
||||||
{ item.updated && (
|
{ item.updated && (
|
||||||
<div class="markup"></div>
|
<Tooltip placement="right" title="new message">
|
||||||
|
<Markup />
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -55,15 +55,15 @@ export const ChannelItemWrapper = styled.div`
|
|||||||
color: ${Colors.disabled};
|
color: ${Colors.disabled};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.markup {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: ${Colors.background};
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Markup = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: ${Colors.background};
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
margin-right: 16px;
|
||||||
`;
|
`;
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
|
import { Space } from 'antd';
|
||||||
import { DetailsWrapper } from './Details.styled';
|
import { DetailsWrapper } from './Details.styled';
|
||||||
import { DoubleRightOutlined } from '@ant-design/icons';
|
import { DoubleRightOutlined } from '@ant-design/icons';
|
||||||
import { useDetails } from './useDetails.hook';
|
import { useDetails } from './useDetails.hook';
|
||||||
import { Logo } from 'logo/Logo';
|
import { Logo } from 'logo/Logo';
|
||||||
|
import { EditOutlined } from '@ant-design/icons';
|
||||||
|
import { CardSelect } from '../cardSelect/CardSelect';
|
||||||
|
|
||||||
export function Details({ cardId, channelId, closeDetails, closeConversation, openContact }) {
|
export function Details({ cardId, channelId, closeDetails, closeConversation, openContact }) {
|
||||||
|
|
||||||
const { state, actions } = useDetails(cardId, channelId);
|
const { state, actions } = useDetails(cardId, channelId);
|
||||||
|
|
||||||
|
console.log(state.contacts);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DetailsWrapper>
|
<DetailsWrapper>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
@ -16,8 +21,51 @@ export function Details({ cardId, channelId, closeDetails, closeConversation, op
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" onClick={closeDetails}>
|
<div class="content" onClick={closeDetails}>
|
||||||
<div class="details">
|
<div class="description">
|
||||||
<Logo url={state.logo} width={48} height={48} radius={4} img={state.img} />
|
<div class="logo">
|
||||||
|
<Logo width={72} height={72} radius={4} img={state.img} />
|
||||||
|
</div>
|
||||||
|
<div class="stats">
|
||||||
|
{ state.host && (
|
||||||
|
<div class="subject edit">
|
||||||
|
<Space>
|
||||||
|
<div>{ state.subject }</div>
|
||||||
|
<EditOutlined />
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{ !state.host && (
|
||||||
|
<div class="subject">{ state.subject }</div>
|
||||||
|
)}
|
||||||
|
{ state.host && (
|
||||||
|
<div class="host">host</div>
|
||||||
|
)}
|
||||||
|
{ !state.host && (
|
||||||
|
<div class="host">guest</div>
|
||||||
|
)}
|
||||||
|
<div class="created">{ state.started }</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{ state.host && (
|
||||||
|
<div class="button">Delete Channel</div>
|
||||||
|
)}
|
||||||
|
{ state.host && (
|
||||||
|
<div class="button">Edit Membership</div>
|
||||||
|
)}
|
||||||
|
{ !state.host && (
|
||||||
|
<div class="button">Leave Channel</div>
|
||||||
|
)}
|
||||||
|
<div class="label">Members</div>
|
||||||
|
<div class="members">
|
||||||
|
<CardSelect filter={(item) => {
|
||||||
|
console.log("CHECK: ", item.id, state.contacts);
|
||||||
|
if(state.contacts.includes(item.id)) {
|
||||||
|
console.log("YES");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}} unknown={0}
|
||||||
|
markup={cardId} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DetailsWrapper>
|
</DetailsWrapper>
|
||||||
|
@ -38,9 +38,77 @@ export const DetailsWrapper = styled.div`
|
|||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
padding-top: 16px;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid ${Colors.divider};
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: scroll;
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
width: 144px;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: ${Colors.white};
|
||||||
|
background-color: ${Colors.primary};
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 40%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
.edit {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.host {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.created {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -7,6 +7,12 @@ export function useDetails(cardId, channelId) {
|
|||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
logo: null,
|
logo: null,
|
||||||
img: null,
|
img: null,
|
||||||
|
subject: null,
|
||||||
|
server: null,
|
||||||
|
startedDate: null,
|
||||||
|
startedTime: null,
|
||||||
|
host: null,
|
||||||
|
contacts: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const card = useContext(CardContext);
|
const card = useContext(CardContext);
|
||||||
@ -17,7 +23,7 @@ export function useDetails(cardId, channelId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let logo, img;
|
let img, subject, host, started;
|
||||||
let chan;
|
let chan;
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
const cardChan = card.state.cards.get(cardId);
|
const cardChan = card.state.cards.get(cardId);
|
||||||
@ -28,23 +34,41 @@ export function useDetails(cardId, channelId) {
|
|||||||
else {
|
else {
|
||||||
chan = channel.state.channels.get(channelId);
|
chan = channel.state.channels.get(channelId);
|
||||||
}
|
}
|
||||||
console.log(chan);
|
|
||||||
|
|
||||||
if (chan) {
|
if (chan) {
|
||||||
if (chan.contacts?.length == 0) {
|
if (chan.contacts?.length == 0) {
|
||||||
img = 'solution';
|
img = 'solution';
|
||||||
logo = null;
|
subject = 'Private';
|
||||||
}
|
}
|
||||||
else if (chan.contacts?.length > 1) {
|
else if (chan.contacts?.length > 1) {
|
||||||
img = 'appstore'
|
img = 'appstore'
|
||||||
logo = null;
|
subject = 'Group';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
img = null;
|
img = 'team';
|
||||||
logo = card.actions.getImageUrl(chan.contacts[0]?.id);
|
subject = 'Direct'
|
||||||
|
}
|
||||||
|
const parsed = JSON.parse(chan.data.channelDetail.data);
|
||||||
|
if (parsed.subject) {
|
||||||
|
subject = parsed.subject;
|
||||||
|
}
|
||||||
|
const date = new Date(chan.data.channelDetail.created * 1000);
|
||||||
|
const now = new Date();
|
||||||
|
if(now.getTime() - date.getTime() < 86400000) {
|
||||||
|
started = date.toLocaleTimeString([], {hour: 'numeric', minute:'2-digit'});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
started = date.toLocaleDateString("en-US");
|
||||||
|
}
|
||||||
|
if (chan.cardId) {
|
||||||
|
host = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
host = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateState({ logo, img });
|
updateState({ img, subject, host, started,
|
||||||
|
contacts: chan.contacts.map((contact) => contact?.id) });
|
||||||
}, [cardId, channelId, card, channel]);
|
}, [cardId, channelId, card, channel]);
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
|
Loading…
Reference in New Issue
Block a user