From 8b09d214b79fe8f299e14e824f5262da57515103 Mon Sep 17 00:00:00 2001 From: balzack Date: Tue, 20 Sep 2022 00:50:53 -0700 Subject: [PATCH] syncing channels --- app/mobile/src/api/getCardImageUrl.js | 4 +- app/mobile/src/context/useAppContext.hook.js | 6 +- app/mobile/src/context/useCardContext.hook.js | 69 ++++++++++++++----- .../src/context/useChannelContext.hook.js | 26 ++++--- .../src/context/useStoreContext.hook.js | 8 ++- app/mobile/src/session/channels/Channels.jsx | 3 +- .../channels/channelItem/ChannelItem.jsx | 7 ++ .../src/session/channels/useChannels.hook.js | 48 ++++++++++++- app/mobile/src/utitls/Logo.jsx | 8 +-- 9 files changed, 139 insertions(+), 40 deletions(-) create mode 100644 app/mobile/src/session/channels/channelItem/ChannelItem.jsx diff --git a/app/mobile/src/api/getCardImageUrl.js b/app/mobile/src/api/getCardImageUrl.js index 40e130e6..c91a58c2 100644 --- a/app/mobile/src/api/getCardImageUrl.js +++ b/app/mobile/src/api/getCardImageUrl.js @@ -1,4 +1,4 @@ -export function getCardImageUrl(token, cardId, revision) { - return `/contact/cards/${cardId}/profile/image?agent=${token}&revision=${revision}` +export function getCardImageUrl(server, token, cardId, revision) { + return `https://${server}/contact/cards/${cardId}/profile/image?agent=${token}&revision=${revision}` } diff --git a/app/mobile/src/context/useAppContext.hook.js b/app/mobile/src/context/useAppContext.hook.js index 67f68471..565bf59c 100644 --- a/app/mobile/src/context/useAppContext.hook.js +++ b/app/mobile/src/context/useAppContext.hook.js @@ -66,19 +66,19 @@ export function useAppContext() { create: async (server, username, password, token) => { await addAccount(server, username, password, token); const access = await setLogin(username, server, password) - await setSession({ ...access, server }); await store.actions.setSession({ ...access, server}); + await setSession({ ...access, server }); }, access: async (server, token) => { const access = await setAccountAccess(server, token); - await setSession({ ...access, server }); await store.actions.setSession({ ...access, server}); + await setSession({ ...access, server }); }, login: async (username, password) => { const acc = username.split('@'); const access = await setLogin(acc[0], acc[1], password) - await setSession({ ...access, server: acc[1] }); await store.actions.setSession({ ...access, server: acc[1]}); + await setSession({ ...access, server: acc[1] }); }, logout: async () => { await clearSession(); diff --git a/app/mobile/src/context/useCardContext.hook.js b/app/mobile/src/context/useCardContext.hook.js index 38afc7fe..1a7b7f47 100644 --- a/app/mobile/src/context/useCardContext.hook.js +++ b/app/mobile/src/context/useCardContext.hook.js @@ -8,6 +8,7 @@ import { getContactChannels } from 'api/getContactChannels'; import { getContactChannelTopics } from 'api/getContactChannelTopics'; import { getContactChannelDetail } from 'api/getContactChannelDetail'; import { getContactChannelSummary } from 'api/getContactChannelSummary'; +import { getCardImageUrl } from 'api/getCardImageUrl'; export function useCardContext() { const [state, setState] = useState({ @@ -26,19 +27,38 @@ export function useCardContext() { setState((s) => ({ ...s, ...value })) } + const setCard = (cardId, card) => { + let updated = cards.current.get(cardId); + if (updated == null) { + updated = { channels: new Map() }; + } + cards.current.set(cardId, { + ...updated, + cardId: cardId, + revision: card?.revision, + detailRevision: card?.data?.detailRevision, + profileRevision: card?.data?.profileRevision, + detail: card?.data?.cardDetail, + profile: card?.data?.cardProfile, + notifiedView: card?.data?.notifiedView, + notifiedProfile: card?.data?.notifiedProfile, + notifiedArtile: card?.data?.notifiedArticle, + notifiedChannel: card?.data?.notifiedChannel, + }); + } const setCardDetail = (cardId, detail, revision) => { let card = cards.current.get(cardId); - if (card?.data) { - card.data.cardDetail = detail; - card.data.detailRevision = revision; + if (card) { + card.detail = detail; + card.detailRevision = revision; cards.current.set(cardId, card); } } const setCardProfile = (cardId, profile, revision) => { let card = cards.current.get(cardId); - if (card?.data) { - card.data.cardProfile = profile; - card.data.profileRevision = revision; + if (card) { + card.profile = profile; + card.profileRevision = revision; cards.current.set(cardId, card); } } @@ -64,6 +84,17 @@ export function useCardContext() { } } const setCardChannel = (cardId, channel) => { + setCardChannelItem(cardId, { + cardId: cardId, + channelId: channel?.id, + revision: channel?.revision, + detailRevision: channel?.data?.detailRevision, + topicRevision: channel?.data?.topicRevision, + detail: channel?.data?.channelDetail, + summary: channel?.data?.channelSummary, + }); + } + const setCardChannelItem = (cardId, channel) => { let card = cards.current.get(cardId); if (card) { card.channels.set(channel.id, channel); @@ -74,9 +105,9 @@ export function useCardContext() { let card = cards.current.get(cardId); if (card) { let channel = card.channels.get(channelId); - if (channel?.data) { - channel.data.channelDetail = detail; - channel.data.detailRevision = revision; + if (channel) { + channel.detail = detail; + channel.detailRevision = revision; card.channels.set(channelId, channel); cards.current.set(cardId, card); } @@ -86,9 +117,9 @@ export function useCardContext() { let card = cards.current.get(cardId); if (card) { let channel = card.channels.get(channelId); - if (channel?.data) { - channel.data.channelSummary = detail; - channel.data.topicRevision = revision; + if (channel) { + channel.summary = detail; + channel.topicRevision = revision; card.channels.set(channelId, channel); cards.current.set(cardId, card); } @@ -128,7 +159,7 @@ export function useCardContext() { if (card.data) { if (card.data.cardDetail && card.data.cardProfile) { await store.actions.setCardItem(guid, card); - cards.current.set(cardId, card); + setCard(card.id, card); } else { const view = await store.actions.getCardItemView(guid, card.id); @@ -138,7 +169,7 @@ export function useCardContext() { assembled.data.cardDetail = await getCardDetail(server, appToken, card.id); assembled.data.cardProfile = await getCardProfile(server, appToken, card.id); await store.actions.setCardItem(guid, assembled); - cards.curent.set(assembled.id, assembled); + setCard(assembled.id, assembled); } else { if (view.detailRevision != detailRevision) { @@ -185,7 +216,7 @@ export function useCardContext() { } } catch(err) { - console.log(err); + console.log("card1:", err); await store.actions.setCardItemOffsync(guid, card.id); setCardOffsync(card.id, true); } @@ -203,7 +234,7 @@ export function useCardContext() { await store.actions.setCardRevision(guid, revision); } catch(err) { - console.log(err); + console.log("card2:", err); syncing.current = false; return; } @@ -267,7 +298,7 @@ export function useCardContext() { } const cardChannelItems = await store.actions.getCardChannelItems(guid); for (item of cardChannelItems) { - setCardChannel(item.cardId, item); + setCardChannelItem(item.cardId, item); } const revision = await store.actions.getCardRevision(guid); updateState({ cards: cards.current }); @@ -283,6 +314,10 @@ export function useCardContext() { curRevision.current = rev; sync(); }, + getCardLogo: (cardId, revision) => { + const { server, appToken } = session.current; + return getCardImageUrl(server, appToken, cardId, revision); + } } return { state, actions } diff --git a/app/mobile/src/context/useChannelContext.hook.js b/app/mobile/src/context/useChannelContext.hook.js index aa5eaa62..ee3c211f 100644 --- a/app/mobile/src/context/useChannelContext.hook.js +++ b/app/mobile/src/context/useChannelContext.hook.js @@ -20,19 +20,29 @@ export function useChannelContext() { setState((s) => ({ ...s, ...value })) } - const setChannelDetails = (channelId, details, revision) => { + const setChannel = (channelId, channel) => { + channels.current.set(channelId, { + channelId: channel?.id, + revision: channel?.revision, + detail: channel?.data?.channelDetail, + summary: channel?.data?.channelSummary, + detailRevision: channel?.data?.detailRevision, + topicRevision: channel?.data?.topicRevision, + }); + } + const setChannelDetails = (channelId, detail, revision) => { let channel = channels.current.get(channelId); if (channel?.data) { - channel.data.channelDetails = details; - channel.data.detailRevision = revision; + channel.detail = detail; + channel.detailRevision = revision; channels.current.set(channelId, channel); } } const setChannelSummary = (channelId, summary, revision) => { let channel = channels.current.get(channelId); - if (channel?.data) { - channel.data.channelSummary = summary; - channel.data.topicRevision = revision; + if (channel) { + channel.summary = summary; + channel.topicRevision = revision; channels.curent.set(channelId, channel); } } @@ -58,7 +68,7 @@ export function useChannelContext() { if (channel.data) { if (channel.data.channelDetail && channel.data.channelSummary) { await store.actions.setChannelItem(guid, channel); - channels.current.set(channel.id, channel); + setChannel(channel.id, channel); } else { const { detailRevision, topicRevision, channelDetail, channelSummary } = channel.data; @@ -69,7 +79,7 @@ export function useChannelContext() { assembled.data.channelDetail = await getChannelDetail(server, appToken, channel.id); assembled.data.channelSummary = await getChannelSummary(server, appToken, channel.id); await store.actions.setChannelItem(guid, assembled); - channels.current.set(assembled.id, assembled); + setChannel(assembled.id, assembled); } else { if (view.detailRevision != detailRevision) { diff --git a/app/mobile/src/context/useStoreContext.hook.js b/app/mobile/src/context/useStoreContext.hook.js index 428417d2..5c91b857 100644 --- a/app/mobile/src/context/useStoreContext.hook.js +++ b/app/mobile/src/context/useStoreContext.hook.js @@ -1,7 +1,7 @@ import { useEffect, useState, useRef, useContext } from 'react'; import SQLite from "react-native-sqlite-storage"; -const DATABAG_DB = 'databag_v019.db'; +const DATABAG_DB = 'databag_v025.db'; export function useStoreContext() { const [state, setState] = useState({}); @@ -113,18 +113,20 @@ export function useStoreContext() { await db.current.executeSql(`UPDATE card_${guid} set profile_revision=?, profile=? where card_id=?`, [revision, encodeObject(profile), cardId]); }, getCardItemStatus: async (guid, cardId) => { - const values = await getAppValues(db.current, `SELECT detail, profile, notified_view, notified_article, notified_profile, notified_channel, offsync FROM card_${guid} WHERE card_id=?`, [cardId]); + const values = await getAppValues(db.current, `SELECT detail, profile, profile_revision, detail_revision, notified_view, notified_article, notified_profile, notified_channel, offsync FROM card_${guid} WHERE card_id=?`, [cardId]); if (!values.length) { return null; } return { detail: decodeObject(values[0].detail), profile: decodeObject(values[0].profile), - offsync: values[0].offsync, + profileRevision: values[0].profile_revision, + detailRevision: values[0].detail_revision, notifiedView: values[0].notified_view, notifiedArticle: values[0].notified_article, notifiedProfile: values[0].notified_profile, notifiedChannel: values[0].notified_cahnnel, + offsync: values[0].offsync, }; }, getCardItemView: async (guid, cardId) => { diff --git a/app/mobile/src/session/channels/Channels.jsx b/app/mobile/src/session/channels/Channels.jsx index 6fbb4a59..5cb8127e 100644 --- a/app/mobile/src/session/channels/Channels.jsx +++ b/app/mobile/src/session/channels/Channels.jsx @@ -3,6 +3,7 @@ import { FlatList, ScrollView, View, TextInput, TouchableOpacity, Text } from 'r import { styles } from './Channels.styled'; import { useChannels } from './useChannels.hook'; import Ionicons from '@expo/vector-icons/AntDesign'; +import { ChannelItem } from './channelItem/ChannelItem'; export function Channels() { @@ -18,7 +19,7 @@ export function Channels() { { item.channelId }} + renderItem={({ item }) => } keyExtractor={item => (`${item.cardId}:${item.channelId}`)} /> diff --git a/app/mobile/src/session/channels/channelItem/ChannelItem.jsx b/app/mobile/src/session/channels/channelItem/ChannelItem.jsx new file mode 100644 index 00000000..6335af75 --- /dev/null +++ b/app/mobile/src/session/channels/channelItem/ChannelItem.jsx @@ -0,0 +1,7 @@ +import { Text } from 'react-native'; +import { Logo } from 'utils/Logo'; + +export function ChannelItem({ item }) { + return +} + diff --git a/app/mobile/src/session/channels/useChannels.hook.js b/app/mobile/src/session/channels/useChannels.hook.js index 63cab82c..52883755 100644 --- a/app/mobile/src/session/channels/useChannels.hook.js +++ b/app/mobile/src/session/channels/useChannels.hook.js @@ -1,6 +1,7 @@ import { useState, useEffect, useContext } from 'react'; import { useWindowDimensions } from 'react-native'; import { useNavigate } from 'react-router-dom'; +import { CardContext } from 'context/CardContext'; import { ChannelContext } from 'context/ChannelContext'; import config from 'constants/Config'; @@ -12,14 +13,57 @@ export function useChannels() { }); const channel = useContext(ChannelContext); + const card = useContext(CardContext); const updateState = (value) => { setState((s) => ({ ...s, ...value })); } + const getCard = (guid) => { + let contact = null + card.state.cards.forEach((card, cardId, map) => { + if (card?.profile?.guid === guid) { + contact = card; + } + }); + return contact; + } + + const setChannelEntry = (item) => { + let contacts = []; + if (item?.detail?.members) { + item.detail.members.forEach(guid => { + contacts.push(getCard(guid)); + }) + } + + let logo = null; + if (contacts.length === 0) { + logo = 'solution'; + } + else if (contacts.length === 1) { + if (contacts[0]?.profile?.imageSet) { + logo = card.actions.getCardLogo(contacts[0].cardId, contacts[0].profileRevision); + } + else { + logo = 'avatar'; + } + } + else { + logo = 'appstore'; + } + + return { + channelId: item.channelId, + contacts: contacts, + logo: logo, + } + } + useEffect(() => { - updateState({ channels: Array.from(channel.state.channels.values()) }); - }, [channel]); + const channels = Array.from(channel.state.channels.values()).map(item => setChannelEntry(item)); + updateState({ channels }); + }, [channel, card]); const actions = { setTopic: (topic) => { diff --git a/app/mobile/src/utitls/Logo.jsx b/app/mobile/src/utitls/Logo.jsx index e6661126..a32483f4 100644 --- a/app/mobile/src/utitls/Logo.jsx +++ b/app/mobile/src/utitls/Logo.jsx @@ -1,4 +1,4 @@ -import { Image } from 'react-native'; +import { Image, View } from 'react-native'; import avatar from 'images/avatar.png'; import appstore from 'images/appstore.png'; import solution from 'images/solution.png'; @@ -6,7 +6,7 @@ import team from 'images/team.png'; export function Logo({ src, width, height, radius }) { return ( -
+ { src === 'team' && ( )} @@ -23,9 +23,9 @@ export function Logo({ src, width, height, radius }) { )} { src && src.startsWith('http') && ( - + )} -
+ ); }