mirror of
https://github.com/balzack/databag.git
synced 2025-02-15 04:59:16 +00:00
rendering card sidebar
This commit is contained in:
parent
f8824c6afe
commit
3276764f70
@ -14,7 +14,7 @@ import (
|
|||||||
func GetCardProfileImage(w http.ResponseWriter, r *http.Request) {
|
func GetCardProfileImage(w http.ResponseWriter, r *http.Request) {
|
||||||
var data []byte
|
var data []byte
|
||||||
|
|
||||||
account, code, err := BearerAppToken(r, false);
|
account, code, err := ParamAgentToken(r, false);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrResponse(w, code, err)
|
ErrResponse(w, code, err)
|
||||||
return
|
return
|
||||||
|
@ -46,6 +46,8 @@ func GetCards(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintMsg(response);
|
||||||
|
|
||||||
w.Header().Set("Card-Revision", strconv.FormatInt(account.CardRevision, 10))
|
w.Header().Set("Card-Revision", strconv.FormatInt(account.CardRevision, 10))
|
||||||
WriteResponse(w, response)
|
WriteResponse(w, response)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ type CardProfile struct {
|
|||||||
|
|
||||||
Location string `json:"location,omitempty"`
|
Location string `json:"location,omitempty"`
|
||||||
|
|
||||||
ImageSet bool `json:"imageSet,omitempty"`
|
ImageSet bool `json:"imageSet"`
|
||||||
|
|
||||||
Version string `json:"version,omitempty"`
|
Version string `json:"version,omitempty"`
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ export function getProfileImageUrl(token, revision) {
|
|||||||
return '/profile/image?agent=' + token + "&revision=" + revision
|
return '/profile/image?agent=' + token + "&revision=" + revision
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCardImageUrl(token, cardId, revision) {
|
||||||
|
return `/contact/cards/${cardId}/profile/image?agent=${token}&revision=${revision}`
|
||||||
|
}
|
||||||
|
|
||||||
export function getListingImageUrl(server, guid, revision) {
|
export function getListingImageUrl(server, guid, revision) {
|
||||||
return `https://${server}/account/listing/${guid}/image?revision=${revision}`
|
return `https://${server}/account/listing/${guid}/image?revision=${revision}`
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState, useRef } from 'react';
|
import { useEffect, useState, useRef } from 'react';
|
||||||
import { getCards, getCardProfile, getCardDetail, getListingImageUrl, getListing, setProfileImage, setProfileData, getProfileImageUrl, getAccountStatus, setAccountSearchable, getProfile, getGroups, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
|
import { getCards, getCardImageUrl, getCardProfile, getCardDetail, getListingImageUrl, getListing, setProfileImage, setProfileData, getProfileImageUrl, getAccountStatus, setAccountSearchable, getProfile, getGroups, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
|
||||||
|
|
||||||
async function updateAccount(token, updateData) {
|
async function updateAccount(token, updateData) {
|
||||||
let status = await getAccountStatus(token);
|
let status = await getAccountStatus(token);
|
||||||
@ -14,7 +14,12 @@ async function updateProfile(token, updateData) {
|
|||||||
async function updateGroups(token, revision, groupMap, updateData) {
|
async function updateGroups(token, revision, groupMap, updateData) {
|
||||||
let groups = await getGroups(token, revision);
|
let groups = await getGroups(token, revision);
|
||||||
for (let group of groups) {
|
for (let group of groups) {
|
||||||
groupMap.set(group.id, group);
|
if (group.data) {
|
||||||
|
groupMap.set(group.id, group);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
groupMap.delete(group.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateData({ groups: Array.from(groupMap.values()) });
|
updateData({ groups: Array.from(groupMap.values()) });
|
||||||
}
|
}
|
||||||
@ -22,48 +27,55 @@ async function updateGroups(token, revision, groupMap, updateData) {
|
|||||||
async function updateCards(token, revision, cardMap, updateData) {
|
async function updateCards(token, revision, cardMap, updateData) {
|
||||||
let cards = await getCards(token, revision);
|
let cards = await getCards(token, revision);
|
||||||
for (let card of cards) {
|
for (let card of cards) {
|
||||||
let cur = cardMap.get(card.id);
|
if (card.data) {
|
||||||
if (cur == null) {
|
let cur = cardMap.get(card.id);
|
||||||
cur = { id: card.id, data: {} }
|
if (cur == null) {
|
||||||
}
|
cur = { id: card.id, data: {} }
|
||||||
if (cur.data.DetailRevision != card.data.DetailRevision) {
|
|
||||||
if (card.data.CardDetail != null) {
|
|
||||||
cur.data.CardDetail = card.data.CardDetail;
|
|
||||||
}
|
}
|
||||||
else {
|
if (cur.data.detailRevision != card.data.detailRevision) {
|
||||||
cur.data.CardDetail = await getCardDetail(token, card.id);
|
if (card.data.cardDetail != null) {
|
||||||
|
cur.data.cardDetail = card.data.cardDetail;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cur.data.cardDetail = await getCardDetail(token, card.id);
|
||||||
|
}
|
||||||
|
cur.data.detailRevision = card.data.detailRevision;
|
||||||
}
|
}
|
||||||
cur.data.DetailRevision = card.data.DetailRevision;
|
if (cur.data.profileRevision != card.data.profileRevision) {
|
||||||
}
|
if (cur.data.cardProfile != null) {
|
||||||
if (cur.data.ProfileRevision != card.data.ProfileRevision) {
|
cur.data.cardProfile = card.data.cardProfile;
|
||||||
if (cur.data.CardProfile != null) {
|
}
|
||||||
cur.data.CardProfile = card.data.CardProfile;
|
else {
|
||||||
|
cur.data.cardProfile = await getCardProfile(token, card.id);
|
||||||
|
}
|
||||||
|
cur.data.profileRevision = card.data.profileRevision;
|
||||||
}
|
}
|
||||||
else {
|
if (cur.data.notifiedProfile != card.data.notifiedProfile) {
|
||||||
cur.data.CardProfile = await getCardProfile(token, card.id);
|
// update remote profile
|
||||||
|
cur.data.notifiedProfile = card.data.notifiedProfile;
|
||||||
}
|
}
|
||||||
cur.data.ProfileRevision = card.data.ProfileRevision;
|
if (cur.data.notifiedView != card.data.notifiedView) {
|
||||||
|
// update remote articles and channels
|
||||||
|
cur.data.notifiedArticle = card.data.notifiedArticle;
|
||||||
|
cur.data.notifiedChannel = card.data.notifiedChannel;
|
||||||
|
cur.data.notifiedView = card.data.notifiedView;
|
||||||
|
}
|
||||||
|
if (cur.data.notifiedArticle != card.data.notifiedArticle) {
|
||||||
|
// update remote articles
|
||||||
|
cur.data.notifiedArticle = card.data.notifiedArticle;
|
||||||
|
}
|
||||||
|
if (cur.data.notifiedChannel != card.data.notifiedChannel) {
|
||||||
|
// update remote channels
|
||||||
|
cur.data.notifiedChannel = card.data.notifiedChannel;
|
||||||
|
}
|
||||||
|
cur.revision = card.revision;
|
||||||
|
cardMap.set(card.id, cur);
|
||||||
}
|
}
|
||||||
if (cur.data.NotifiedProfile != card.data.NotifiedProfile) {
|
else {
|
||||||
// update remote profile
|
cardMap.delete(card.id);
|
||||||
cur.data.NotifiedProfile = card.data.NotifiedProfile;
|
|
||||||
}
|
}
|
||||||
if (cur.data.NotifiedView != card.data.NotifiedView) {
|
|
||||||
// update remote articles and channels
|
|
||||||
cur.data.NotifiedArticle = card.data.NotifiedArticle;
|
|
||||||
cur.data.NotifiedChannel = card.data.NotifiedChannel;
|
|
||||||
cur.data.NotifiedView = card.data.NotifiedView;
|
|
||||||
}
|
|
||||||
if (cur.data.NotifiedArticle != card.data.NotifiedArticle) {
|
|
||||||
// update remote articles
|
|
||||||
cur.data.NotifiedArticle = card.data.NotifiedArticle;
|
|
||||||
}
|
|
||||||
if (cur.data.NotifiedChannel != card.data.NotifiedChannel) {
|
|
||||||
// update remote channels
|
|
||||||
cur.data.NotifiedChannel = card.data.NotifiedChannel;
|
|
||||||
}
|
|
||||||
cur.revision = card.revision;
|
|
||||||
}
|
}
|
||||||
|
updateData({ cards: Array.from(cardMap.values()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function appCreate(username, password, updateState, setWebsocket) {
|
async function appCreate(username, password, updateState, setWebsocket) {
|
||||||
@ -140,6 +152,7 @@ export function useAppContext() {
|
|||||||
profileImageUrl: () => getProfileImageUrl(state.token, state.Data?.profile?.revision),
|
profileImageUrl: () => getProfileImageUrl(state.token, state.Data?.profile?.revision),
|
||||||
getRegistry: async (node) => getListing(node),
|
getRegistry: async (node) => getListing(node),
|
||||||
getRegistryImageUrl: (server, guid, revision) => getListingImageUrl(server, guid, revision),
|
getRegistryImageUrl: (server, guid, revision) => getListingImageUrl(server, guid, revision),
|
||||||
|
getCardImageUrl: (cardId, revision) => getCardImageUrl(state.token, cardId, revision),
|
||||||
}
|
}
|
||||||
|
|
||||||
const adminActions = {
|
const adminActions = {
|
||||||
|
@ -1,28 +1,70 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { CardsWrapper } from './Cards.styled';
|
import { CardsWrapper, CardItem } from './Cards.styled';
|
||||||
import { Drawer } from 'antd';
|
import { Drawer, List } from 'antd';
|
||||||
import { Registry } from './Registry/Registry';
|
import { Registry } from './Registry/Registry';
|
||||||
|
import { useCards } from './useCards.hook';
|
||||||
|
import { Logo } from '../../../../Logo/Logo';
|
||||||
|
|
||||||
export function Cards({ showRegistry }) {
|
export function Cards({ showRegistry }) {
|
||||||
|
|
||||||
|
const { state, actions } = useCards();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
}, [showRegistry]);
|
}, [showRegistry]);
|
||||||
|
|
||||||
|
const onSelect = (item) => {
|
||||||
|
actions.select(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardProfile = (item) => {
|
||||||
|
if (item?.data?.cardProfile) {
|
||||||
|
return item.data.cardProfile;
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardImage = (item) => {
|
||||||
|
if (actions?.getCardImageUrl) {
|
||||||
|
return actions.getCardImageUrl(item.id, item.revision);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CardsWrapper>
|
<CardsWrapper>
|
||||||
<div>
|
<Drawer
|
||||||
<Drawer
|
placement="right"
|
||||||
placement="right"
|
closable={false}
|
||||||
closable={false}
|
visible={showRegistry}
|
||||||
visible={showRegistry}
|
getContainer={false}
|
||||||
getContainer={false}
|
contentWrapperStyle={{ width: '100%' }}
|
||||||
contentWrapperStyle={{ width: '100%' }}
|
bodyStyle={{ backgroundColor: '#f6f5ed', paddingLeft: 16, paddingRight: 16, paddingTop: 16, paddingBottom: 0 }}
|
||||||
bodyStyle={{ backgroundColor: '#f6f5ed', paddingLeft: 16, paddingRight: 16, paddingTop: 16, paddingBottom: 0 }}
|
style={{ position: 'absolute' }}
|
||||||
style={{ position: 'absolute' }}
|
>
|
||||||
>
|
<Registry />
|
||||||
<Registry />
|
</Drawer>
|
||||||
</Drawer>
|
<List
|
||||||
</div>
|
locale={{ emptyText: '' }}
|
||||||
|
itemLayout="horizontal"
|
||||||
|
dataSource={state.cards}
|
||||||
|
gutter="0"
|
||||||
|
renderItem={item => (
|
||||||
|
<CardItem onClick={() => onSelect(item)}>
|
||||||
|
<div class="item">
|
||||||
|
<div class="logo">
|
||||||
|
<Logo imageUrl={cardImage(item)}
|
||||||
|
imageSet={cardProfile(item).imageSet} />
|
||||||
|
</div>
|
||||||
|
<div class="username">
|
||||||
|
<span class="handle">{ cardProfile(item).handle }</span>
|
||||||
|
<span class="name">{ cardProfile(item).name }</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</CardsWrapper>
|
</CardsWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button } from 'antd';
|
import { Button, List } from 'antd';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
export const CardsWrapper = styled.div`
|
export const CardsWrapper = styled.div`
|
||||||
@ -11,3 +11,43 @@ export const CardsWrapper = styled.div`
|
|||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const CardItem = styled(List.Item)`
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-left: 16px;
|
||||||
|
text-align: right;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handle {
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
35
net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js
Normal file
35
net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { useContext, useState, useEffect } from 'react';
|
||||||
|
import { AppContext } from '../../../../AppContext/AppContext';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
export function useCards() {
|
||||||
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
cards: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const app = useContext(AppContext);
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
getCardImageUrl: app?.actions?.getCardImageUrl,
|
||||||
|
select: (contact) => {
|
||||||
|
navigate(`/user/contact/${contact.data.cardProfile.guid}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }));
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (app?.state?.Data?.cards) {
|
||||||
|
updateState({ cards: app.state.Data.cards });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateState({ cards: [] });
|
||||||
|
}
|
||||||
|
}, [app])
|
||||||
|
|
||||||
|
return { state, actions };
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user