diff --git a/app/mobile/src/api/getCardDetail.js b/app/mobile/src/api/getCardDetail.js index 69be56ab..207b3bf3 100644 --- a/app/mobile/src/api/getCardDetail.js +++ b/app/mobile/src/api/getCardDetail.js @@ -1,8 +1,8 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getCardDetail(token, cardId) { +export async function getCardDetail(server, token, cardId) { let param = "?agent=" + token - let detail = await fetchWithTimeout(`/contact/cards/${cardId}/detail${param}`, { method: 'GET' }); + let detail = await fetchWithTimeout(`https://${server}/contact/cards/${cardId}/detail${param}`, { method: 'GET' }); checkResponse(detail); return await detail.json() } diff --git a/app/mobile/src/api/getCardProfile.js b/app/mobile/src/api/getCardProfile.js index 974e6712..5154c527 100644 --- a/app/mobile/src/api/getCardProfile.js +++ b/app/mobile/src/api/getCardProfile.js @@ -1,7 +1,7 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getCardProfile(token, cardId) { - let profile = await fetchWithTimeout(`/contact/cards/${cardId}/profile?agent=${token}`, { method: 'GET' }); +export async function getCardProfile(server, token, cardId) { + let profile = await fetchWithTimeout(`https://${server}/contact/cards/${cardId}/profile?agent=${token}`, { method: 'GET' }); checkResponse(profile); return await profile.json() } diff --git a/app/mobile/src/api/getCards.js b/app/mobile/src/api/getCards.js index a05dad31..9c2cde59 100644 --- a/app/mobile/src/api/getCards.js +++ b/app/mobile/src/api/getCards.js @@ -1,11 +1,11 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getCards(token, revision) { +export async function getCards(server, token, revision) { let param = "agent=" + token if (revision != null) { param += '&revision=' + revision } - let cards = await fetchWithTimeout(`/contact/cards?${param}`, { method: 'GET' }); + let cards = await fetchWithTimeout(`https://${server}/contact/cards?${param}`, { method: 'GET' }); checkResponse(cards) return await cards.json() } diff --git a/app/mobile/src/context/useAppContext.hook.js b/app/mobile/src/context/useAppContext.hook.js index f4aba29e..67f68471 100644 --- a/app/mobile/src/context/useAppContext.hook.js +++ b/app/mobile/src/context/useAppContext.hook.js @@ -7,6 +7,7 @@ import { getUsername } from 'api/getUsername'; import { StoreContext } from 'context/StoreContext'; import { AccountContext } from 'context/AccountContext'; import { ProfileContext } from 'context/ProfileContext'; +import { CardContext } from 'context/CardContext'; import { ChannelContext } from 'context/ChannelContext'; export function useAppContext() { @@ -17,6 +18,7 @@ export function useAppContext() { const store = useContext(StoreContext); const account = useContext(AccountContext); const profile = useContext(ProfileContext); + const card = useContext(CardContext); const channel = useContext(ChannelContext); const delay = useRef(2); @@ -43,6 +45,7 @@ export function useAppContext() { const setSession = async (access) => { await account.actions.setSession(access); await profile.actions.setSession(access); + await card.actions.setSession(access); await channel.actions.setSession(access); updateState({ session: true }); setWebsocket(access.server, access.appToken); @@ -51,6 +54,7 @@ export function useAppContext() { const clearSession = async () => { account.actions.clearSession(); profile.actions.clearSession(); + card.actions.clearSession(); channel.actions.clearSession(); updateState({ session: false }); clearWebsocket(); @@ -91,7 +95,8 @@ export function useAppContext() { try { profile.actions.setRevision(rev.profile); account.actions.setRevision(rev.account); - channel.actions.setRevision(rev.channel); + card.actions.setRevision(rev.channel); + channel.actions.setRevision(rev.card); } catch(err) { console.log(err); diff --git a/app/mobile/src/context/useCardContext.hook.js b/app/mobile/src/context/useCardContext.hook.js index f039a77a..edadc338 100644 --- a/app/mobile/src/context/useCardContext.hook.js +++ b/app/mobile/src/context/useCardContext.hook.js @@ -1,5 +1,8 @@ import { useState, useRef, useContext } from 'react'; import { StoreContext } from 'context/StoreContext'; +import { getCards } from 'api/getCards'; +import { getCardProfile } from 'api/getCardProfile'; +import { getCardDetail } from 'api/getCardDetail'; export function useCardContext() { const [state, setState] = useState({ @@ -24,9 +27,57 @@ export function useCardContext() { const { server, appToken, guid } = session.current; // get and store + const delta = await getCards(server, appToken, setRevision.current); +console.log("DELTA:", delta); + + for (let card of delta) { + if (card.data) { + if (card.data.cardDetail && card.data.cardProfile) { + await store.actions.setCardItem(guid, card); + } + else { + const { detailRevision, profileRevision, cardDetail, cardProfile, notifiedView, notifiedArticle, notifiedProfile, notifiedChannel } = channel.data; + const view = await store.actions.getCardItemView(guid, card.id); + if (view.detailRevision != detailRevision) { + const detail = await getCardDetail(server, appToken, card.id); + await store.actions.setCardItemDetail(guid, card.id, detailRevision, detail); + } + if (view.profileRevision != profileRevision) { + const profile = await getCardProfile(server, appToken, card.id); + await store.actions.setCardItemProfile(guid, card.id, profileRevision, profile); + } + if (view.notifiedView != notifiedView) { + // TODO clear contact and channels + // TODO get articles + await store.actions.setCardNotifiedArticle(guid, card.id, notifiedArticle); + // TODO get channels + await store.actions.setCardNotifiedChannel(guid, card.id, notifiedChannel); + + await store.actions.setCardNotifiedView(guid, card.id, notifiedView); + } + else { + if (view.notifiedArticle != notifiedArticle) { + // TODO get article delta + await store.actions.setCardNotifiedArticle(guid, card.id, notifiedArticle); + } + if (view.notifiedChannel != notifiedChannel) { + // TODO get channel delta + await store.actions.setCardNotifiedChannel(guid, card.id, notifiedChannel); + } + } + if (view.notifiedProflile != notifiedProfile) { + // TODO update contact profile + await store.actions.setCardNotifiedProfile(guid, card.id, notifiedProfile); + } + } + } + else { + await store.actions.clearCardItem(guid, card.id); + } + } - updateState({ status }); setRevision.current = revision; + await store.actions.setCardRevision(guid, revision); } catch(err) { console.log(err); diff --git a/app/mobile/src/context/useChannelContext.hook.js b/app/mobile/src/context/useChannelContext.hook.js index cd3a784f..af764e31 100644 --- a/app/mobile/src/context/useChannelContext.hook.js +++ b/app/mobile/src/context/useChannelContext.hook.js @@ -48,7 +48,7 @@ export function useChannelContext() { } } else { - await store.actions.clearChannelItem(channel.id); + await store.actions.clearChannelItem(guid, channel.id); } } diff --git a/app/mobile/src/context/useStoreContext.hook.js b/app/mobile/src/context/useStoreContext.hook.js index e5ec4ee6..2688a5b0 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_v011.db'; +const DATABAG_DB = 'databag_v015.db'; export function useStoreContext() { const [state, setState] = useState({}); @@ -13,7 +13,10 @@ export function useStoreContext() { const initSession = async (guid) => { await db.current.executeSql(`CREATE TABLE IF NOT EXISTS channel_${guid} (channel_id text, revision integer, detail_revision integer, topic_revision integer, detail text, summary text, unique(channel_id))`); - await db.current.executeSql(`CREATE TABLE IF NOT EXISTS topic_${guid} (channel_id text, topic_id text, revision integer, detail_revision integer, detail text, unique(channel_id, topic_id))`); + await db.current.executeSql(`CREATE TABLE IF NOT EXISTS channel_topic_${guid} (channel_id text, topic_id text, revision integer, detail_revision integer, detail text, unique(channel_id, topic_id))`); + await db.current.executeSql(`CREATE TABLE IF NOT EXISTS card_${guid} (card_id text, revision integer, detail_revision integer, profile_revision integer, detail text, profile text, notified_view integer, notified_article integer, notified_profile integer, notified_channel integer, unique(card_id))`); + await db.current.executeSql(`CREATE TABLE IF NOT EXISTS contact_channel_${guid} (card_id text, channel_id text, revision integer, detail_revision integer, topic_revision integer, detail text, summary text, unique(card_id, channel_id))`); + await db.current.executeSql(`CREATE TABLE IF NOT EXISTS contact_channel_topic_${guid} (card_id text, channel_id text, topic_id text, revision integer, detail_revision integer, detail text, unique(card_id, channel_id, topic_id))`); } const actions = { @@ -74,7 +77,65 @@ export function useStoreContext() { setCardRevision: async (guid, revision) => { const dataId = `${guid}_cardRevision`; await db.current.executeSql("INSERT OR REPLACE INTO app (key, value) values (?, ?);", [dataId, encodeObject(revision)]); - }, + }, + setCardItem: async (guid, card) => { + const { id, revision, data } = card; + await db.current.executeSql(`INSERT OR REPLACE INTO card_${guid} (card_id, revision, detail_revision, profile_revision, detail, profile, notified_view, notified_profile, notified_article, notified_channel) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, [id, revision, data.detailRevision, data.profileRevision, encodeObject(data.cardDetail), encodeObject(data.cardProfile), data.notifiedView, data.notifiedProfile, data.notifiedArticle, data.notifiedChannel]); + }, + clearCardItem: async (guid, cardId) => { + await db.current.executeSql(`DELETE FROM card_${guid} WHERE card_id=?`, [cardId]); + }, + setCardItemRevision: async (guid, cardId, revision) => { + await db.current.executeSql(`UPDATE card_${guid} set revision=? where card_id=?`, [revision, cardId]); + }, + setCardItemNotifiedView: async (guid, cardId, notified) => { + await db.current.executeSql(`UPDATE card_${guid} set notified_view=? where card_id=?`, [notified, cardId]); + }, + setCardItemNotifiedArtcile: async (guid, cardId, notified) => { + await db.current.executeSql(`UPDATE card_${guid} set notified_article=? where card_id=?`, [notified, cardId]); + }, + setCardItemNotifiedProfile: async (guid, cardId, notified) => { + await db.current.executeSql(`UPDATE card_${guid} set notified_profile=? where card_id=?`, [notified, cardId]); + }, + setCardItemNotifiedChannel: async (guid, cardId, notified) => { + await db.current.executeSql(`UPDATE card_${guid} set notified_channel=? where card_id=?`, [notified, cardId]); + }, + setCardItemDetail: async (guid, cardId, revision, detail) => { + await db.current.executeSql(`UPDATE card_${guid} set detail_revision=?, detail=? where card_id=?`, [revision, encodeObject(detail), cardId]); + }, + setCardItemProfile: async (guid, cardId, revision, profile) => { + await db.current.executeSql(`UPDATE card_${guid} set profile_revision=?, profile=? where card_id=?`, [revision, encodeObject(profile), cardId]); + }, + getCardItemView: async (guid, cardId) => { + const values = await getAppValues(db.current, `SELECT revision, detail_revision, profile_revision, notifed_view, notified_article, notifed_profile, notified_channel FROM card_${guid} WHERE card_id=?`, [cardId]); + if (!values.length) { + return {}; + } + return { + revision: values[0].revision, + detailRevision: values[0].detail_revision, + profileRevision: values[0].profile_revision, + notifiedView: values[0].notified_view, + notifiedArticle: values[0].notified_article, + notifiedProfile: values[0].notified_profile, + notifiedChannel: values[0].notified_cahnnel, + }; + }, + getCardItems: async (guid) => { + const values = await getAppValues(db.current, `SELECT card_id, revision, detail_revision, profile_revision, detail, profile, notified_view, notified_profile, notified_article, notified_channel FROM channel_${guid}`, []); + return values.map(card => ({ + cardId: card.card_id, + revision: card.revision, + detailRevision: card.detail_revision, + profileRevision: card.profile_revision, + detail: decodeObject(card.detail), + profile: decodeObject(card.profile), + notifiedView: card.notified_view, + notifiedProfile: card.notified_profile, + notifiedArticle: card.notified_article, + notifiedChannel: card.notified_channel, + })); + }, getChannelRevision: async (guid) => { const dataId = `${guid}_channelRevision`; @@ -101,7 +162,6 @@ export function useStoreContext() { await db.current.executeSql(`UPDATE channel_${guid} set topic_revision=?, summary=? where channel_id=?`, [revision, encodeObject(summary), channelId]); }, getChannelItemView: async (guid, channelId) => { -console.log("HERE", channelId); const values = await getAppValues(db.current, `SELECT revision, detail_revision, topic_revision FROM channel_${guid} WHERE channel_id=?`, [channelId]); if (!values.length) { return {};