From 26be0daa5956f3332796fe95809fa9e935efd118 Mon Sep 17 00:00:00 2001 From: balzack Date: Wed, 7 Sep 2022 00:32:06 -0700 Subject: [PATCH] setting root structure --- app/mobile/App.js | 28 +++-- app/mobile/access/Access.jsx | 4 + app/mobile/admin/Admin.jsx | 4 + app/mobile/api/addAccount.js | 15 +++ app/mobile/api/addAccountAccess.js | 8 ++ app/mobile/api/addAccountCreate.js | 8 ++ app/mobile/api/addCard.js | 8 ++ app/mobile/api/addChannel.js | 10 ++ app/mobile/api/addChannelTopic.js | 93 +++++++++++++++ app/mobile/api/addContactChannelTopic.js | 96 ++++++++++++++++ app/mobile/api/clearChannelCard.js | 7 ++ app/mobile/api/createAccount.js | 11 ++ app/mobile/api/fetchUtil.js | 24 ++++ app/mobile/api/getAccountImageUrl.js | 4 + app/mobile/api/getAccountStatus.js | 8 ++ app/mobile/api/getAvailable.js | 8 ++ app/mobile/api/getCardCloseMessage.js | 8 ++ app/mobile/api/getCardDetail.js | 9 ++ app/mobile/api/getCardImageUrl.js | 4 + app/mobile/api/getCardOpenMessage.js | 8 ++ app/mobile/api/getCardProfile.js | 8 ++ app/mobile/api/getCards.js | 12 ++ app/mobile/api/getChannelDetail.js | 8 ++ app/mobile/api/getChannelSummary.js | 8 ++ app/mobile/api/getChannelTopic.js | 9 ++ app/mobile/api/getChannelTopicAssetUrl.js | 4 + app/mobile/api/getChannelTopics.js | 29 +++++ app/mobile/api/getChannels.js | 13 +++ app/mobile/api/getContactChannelDetail.js | 12 ++ app/mobile/api/getContactChannelSummary.js | 12 ++ app/mobile/api/getContactChannelTopic.js | 14 +++ .../api/getContactChannelTopicAssetUrl.js | 9 ++ app/mobile/api/getContactChannelTopics.js | 34 ++++++ app/mobile/api/getContactChannels.js | 20 ++++ app/mobile/api/getContactProfile.js | 13 +++ app/mobile/api/getGroups.js | 13 +++ app/mobile/api/getListing.js | 13 +++ app/mobile/api/getListingImageUrl.js | 10 ++ app/mobile/api/getListingMessage.js | 13 +++ app/mobile/api/getNodeAccounts.js | 8 ++ app/mobile/api/getNodeConfig.js | 8 ++ app/mobile/api/getNodeStatus.js | 8 ++ app/mobile/api/getProfile.js | 9 ++ app/mobile/api/getProfileImageUrl.js | 4 + app/mobile/api/getUsername.js | 12 ++ app/mobile/api/package.json | 3 + app/mobile/api/removeAccount.js | 7 ++ app/mobile/api/removeCard.js | 8 ++ app/mobile/api/removeChannel.js | 8 ++ app/mobile/api/removeChannelTopic.js | 8 ++ app/mobile/api/removeContactChannel.js | 12 ++ app/mobile/api/removeContactChannelTopic.js | 12 ++ app/mobile/api/setAccountAccess.js | 9 ++ app/mobile/api/setAccountLogin.js | 10 ++ app/mobile/api/setAccountSearchable.js | 7 ++ app/mobile/api/setAccountStatus.js | 7 ++ app/mobile/api/setCardCloseMessage.js | 13 +++ app/mobile/api/setCardOpenMessage.js | 13 +++ app/mobile/api/setCardProfile.js | 8 ++ app/mobile/api/setCardStatus.js | 20 ++++ app/mobile/api/setChannelCard.js | 7 ++ app/mobile/api/setChannelSubject.js | 9 ++ app/mobile/api/setChannelTopicAsset.js | 48 ++++++++ app/mobile/api/setChannelTopicSubject.js | 11 ++ app/mobile/api/setContactChannelTopicAsset.js | 53 +++++++++ .../api/setContactChannelTopicSubject.js | 16 +++ app/mobile/api/setLogin.js | 11 ++ app/mobile/api/setNodeConfig.js | 8 ++ app/mobile/api/setNodeStatus.js | 7 ++ app/mobile/api/setProfileData.js | 9 ++ app/mobile/api/setProfileImage.js | 8 ++ app/mobile/context/package.json | 3 + app/mobile/context/useAppContext.hook.js | 107 +++++++++++++++++- app/mobile/package.json | 3 + app/mobile/root/Root.jsx | 3 + app/mobile/session/Session.jsx | 4 + app/mobile/yarn.lock | 43 ++++++- 77 files changed, 1148 insertions(+), 15 deletions(-) create mode 100644 app/mobile/access/Access.jsx create mode 100644 app/mobile/admin/Admin.jsx create mode 100644 app/mobile/api/addAccount.js create mode 100644 app/mobile/api/addAccountAccess.js create mode 100644 app/mobile/api/addAccountCreate.js create mode 100644 app/mobile/api/addCard.js create mode 100644 app/mobile/api/addChannel.js create mode 100644 app/mobile/api/addChannelTopic.js create mode 100644 app/mobile/api/addContactChannelTopic.js create mode 100644 app/mobile/api/clearChannelCard.js create mode 100644 app/mobile/api/createAccount.js create mode 100644 app/mobile/api/fetchUtil.js create mode 100644 app/mobile/api/getAccountImageUrl.js create mode 100644 app/mobile/api/getAccountStatus.js create mode 100644 app/mobile/api/getAvailable.js create mode 100644 app/mobile/api/getCardCloseMessage.js create mode 100644 app/mobile/api/getCardDetail.js create mode 100644 app/mobile/api/getCardImageUrl.js create mode 100644 app/mobile/api/getCardOpenMessage.js create mode 100644 app/mobile/api/getCardProfile.js create mode 100644 app/mobile/api/getCards.js create mode 100644 app/mobile/api/getChannelDetail.js create mode 100644 app/mobile/api/getChannelSummary.js create mode 100644 app/mobile/api/getChannelTopic.js create mode 100644 app/mobile/api/getChannelTopicAssetUrl.js create mode 100644 app/mobile/api/getChannelTopics.js create mode 100644 app/mobile/api/getChannels.js create mode 100644 app/mobile/api/getContactChannelDetail.js create mode 100644 app/mobile/api/getContactChannelSummary.js create mode 100644 app/mobile/api/getContactChannelTopic.js create mode 100644 app/mobile/api/getContactChannelTopicAssetUrl.js create mode 100644 app/mobile/api/getContactChannelTopics.js create mode 100644 app/mobile/api/getContactChannels.js create mode 100644 app/mobile/api/getContactProfile.js create mode 100644 app/mobile/api/getGroups.js create mode 100644 app/mobile/api/getListing.js create mode 100644 app/mobile/api/getListingImageUrl.js create mode 100644 app/mobile/api/getListingMessage.js create mode 100644 app/mobile/api/getNodeAccounts.js create mode 100644 app/mobile/api/getNodeConfig.js create mode 100644 app/mobile/api/getNodeStatus.js create mode 100644 app/mobile/api/getProfile.js create mode 100644 app/mobile/api/getProfileImageUrl.js create mode 100644 app/mobile/api/getUsername.js create mode 100644 app/mobile/api/package.json create mode 100644 app/mobile/api/removeAccount.js create mode 100644 app/mobile/api/removeCard.js create mode 100644 app/mobile/api/removeChannel.js create mode 100644 app/mobile/api/removeChannelTopic.js create mode 100644 app/mobile/api/removeContactChannel.js create mode 100644 app/mobile/api/removeContactChannelTopic.js create mode 100644 app/mobile/api/setAccountAccess.js create mode 100644 app/mobile/api/setAccountLogin.js create mode 100644 app/mobile/api/setAccountSearchable.js create mode 100644 app/mobile/api/setAccountStatus.js create mode 100644 app/mobile/api/setCardCloseMessage.js create mode 100644 app/mobile/api/setCardOpenMessage.js create mode 100644 app/mobile/api/setCardProfile.js create mode 100644 app/mobile/api/setCardStatus.js create mode 100644 app/mobile/api/setChannelCard.js create mode 100644 app/mobile/api/setChannelSubject.js create mode 100644 app/mobile/api/setChannelTopicAsset.js create mode 100644 app/mobile/api/setChannelTopicSubject.js create mode 100644 app/mobile/api/setContactChannelTopicAsset.js create mode 100644 app/mobile/api/setContactChannelTopicSubject.js create mode 100644 app/mobile/api/setLogin.js create mode 100644 app/mobile/api/setNodeConfig.js create mode 100644 app/mobile/api/setNodeStatus.js create mode 100644 app/mobile/api/setProfileData.js create mode 100644 app/mobile/api/setProfileImage.js create mode 100644 app/mobile/context/package.json create mode 100644 app/mobile/root/Root.jsx create mode 100644 app/mobile/session/Session.jsx diff --git a/app/mobile/App.js b/app/mobile/App.js index eb188170..265043a1 100644 --- a/app/mobile/App.js +++ b/app/mobile/App.js @@ -1,23 +1,27 @@ import { StatusBar } from 'expo-status-bar'; import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; -import { AppContextProvider } from './context/AppContext'; +import { AppContextProvider } from 'context/AppContext'; +import { NativeRouter } from "react-router-native"; +import { Routes, Route } from 'react-router-dom'; +import { Root } from './root/Root'; +import { Access } from './access/Access'; +import { Session } from './session/Session'; +import { Admin } from './admin/Admin'; export default function App() { return ( - - Open App.js to start working on your app! - + + + } /> + } /> + } /> + } /> + } /> + + ); } -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#fff', - alignItems: 'center', - justifyContent: 'center', - }, -}); diff --git a/app/mobile/access/Access.jsx b/app/mobile/access/Access.jsx new file mode 100644 index 00000000..2576757f --- /dev/null +++ b/app/mobile/access/Access.jsx @@ -0,0 +1,4 @@ +export function Access({ mode }) { + return <> +} + diff --git a/app/mobile/admin/Admin.jsx b/app/mobile/admin/Admin.jsx new file mode 100644 index 00000000..599d8358 --- /dev/null +++ b/app/mobile/admin/Admin.jsx @@ -0,0 +1,4 @@ +export function Admin() { + return <> +} + diff --git a/app/mobile/api/addAccount.js b/app/mobile/api/addAccount.js new file mode 100644 index 00000000..1eb76047 --- /dev/null +++ b/app/mobile/api/addAccount.js @@ -0,0 +1,15 @@ +import { checkResponse, fetchWithCustomTimeout } from './fetchUtil'; +import base64 from 'react-native-base64' + +export async function addAccount(username, password, token) { + let access = ""; + if (token) { + access = `?token=${token}` + } + let headers = new Headers() + headers.append('Credentials', 'Basic ' + base64.encode(username + ":" + password)); + let profile = await fetchWithCustomTimeout(`/account/profile${access}`, { method: 'POST', headers: headers }, 60000) + checkResponse(profile); + return await profile.json() +} + diff --git a/app/mobile/api/addAccountAccess.js b/app/mobile/api/addAccountAccess.js new file mode 100644 index 00000000..d0494332 --- /dev/null +++ b/app/mobile/api/addAccountAccess.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function addAccountAccess(token, accountId) { + let access = await fetchWithTimeout(`/admin/accounts/${accountId}/auth?token=${token}`, { method: 'POST' }) + checkResponse(access); + return await access.json() +} + diff --git a/app/mobile/api/addAccountCreate.js b/app/mobile/api/addAccountCreate.js new file mode 100644 index 00000000..49e4015e --- /dev/null +++ b/app/mobile/api/addAccountCreate.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function addAccountCreate(token) { + let access = await fetchWithTimeout(`/admin/accounts?token=${token}`, { method: 'POST' }) + checkResponse(access); + return await access.json() +} + diff --git a/app/mobile/api/addCard.js b/app/mobile/api/addCard.js new file mode 100644 index 00000000..8109c94b --- /dev/null +++ b/app/mobile/api/addCard.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function addCard(token, message) { + let card = await fetchWithTimeout(`/contact/cards?agent=${token}`, { method: 'POST', body: JSON.stringify(message)} ); + checkResponse(card); + return await card.json(); +} + diff --git a/app/mobile/api/addChannel.js b/app/mobile/api/addChannel.js new file mode 100644 index 00000000..46a81725 --- /dev/null +++ b/app/mobile/api/addChannel.js @@ -0,0 +1,10 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function addChannel(token, cards, subject, description ) { + let data = { subject, description }; + let params = { dataType: 'superbasic', data: JSON.stringify(data), groups: [], cards }; + let channel = await fetchWithTimeout(`/content/channels?agent=${token}`, { method: 'POST', body: JSON.stringify(params)} ); + checkResponse(channel); + return await channel.json(); +} + diff --git a/app/mobile/api/addChannelTopic.js b/app/mobile/api/addChannelTopic.js new file mode 100644 index 00000000..69f76d2a --- /dev/null +++ b/app/mobile/api/addChannelTopic.js @@ -0,0 +1,93 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function addChannelTopic(token, channelId, message, assets ): string { + + if (message == null && (assets == null || assets.length === 0)) { + let topic = await fetchWithTimeout(`/content/channels/${channelId}/topics?agent=${token}`, + { method: 'POST', body: JSON.stringify({}) }); + checkResponse(topic); + let slot = await topic.json(); + return slot.id; + } + else if (assets == null || assets.length === 0) { + let subject = { data: JSON.stringify(message, (key, value) => { + if (value !== null) return value + }), datatype: 'superbasictopic' }; + + let topic = await fetchWithTimeout(`/content/channels/${channelId}/topics?agent=${token}&confirm=true`, + { method: 'POST', body: JSON.stringify(subject) }); + checkResponse(topic); + let slot = await topic.json(); + return slot.id; + } + else { + + let topic = await fetchWithTimeout(`/content/channels/${channelId}/topics?agent=${token}`, + { method: 'POST', body: JSON.stringify({}) }); + checkResponse(topic); + let slot = await topic.json(); + + // add each asset + message.assets = []; + for (let asset of assets) { + if (asset.image) { + const formData = new FormData(); + formData.append('asset', asset.image); + let transform = encodeURIComponent(JSON.stringify(["ithumb;photo", "icopy;photo"])); + let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + message.assets.push({ + image: { + thumb: assetEntry.find(item => item.transform === 'ithumb;photo').assetId, + full: assetEntry.find(item => item.transform === 'icopy;photo').assetId, + } + }); + } + else if (asset.video) { + const formData = new FormData(); + formData.append('asset', asset.video); + let thumb = 'vthumb;video;' + asset.position; + let transform = encodeURIComponent(JSON.stringify(["vlq;video", "vhd;video", thumb])); + let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + message.assets.push({ + video: { + thumb: assetEntry.find(item => item.transform === thumb).assetId, + lq: assetEntry.find(item => item.transform === 'vlq;video').assetId, + hd: assetEntry.find(item => item.transform === 'vhd;video').assetId, + } + }); + } + else if (asset.audio) { + const formData = new FormData(); + formData.append('asset', asset.audio); + let transform = encodeURIComponent(JSON.stringify(["acopy;audio"])); + let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + message.assets.push({ + audio: { + label: asset.label, + full: assetEntry.find(item => item.transform === 'acopy;audio').assetId, + } + }); + } + } + + let subject = { data: JSON.stringify(message, (key, value) => { + if (value !== null) return value + }), datatype: 'superbasictopic' }; + + let unconfirmed = await fetchWithTimeout(`/content/channels/${channelId}/topics/${slot.id}/subject?agent=${token}`, + { method: 'PUT', body: JSON.stringify(subject) }); + checkResponse(unconfirmed); + + let confirmed = await fetchWithTimeout(`/content/channels/${channelId}/topics/${slot.id}/confirmed?agent=${token}`, + { method: 'PUT', body: JSON.stringify('confirmed') }); + checkResponse(confirmed); + return slot.id; + } +} + diff --git a/app/mobile/api/addContactChannelTopic.js b/app/mobile/api/addContactChannelTopic.js new file mode 100644 index 00000000..8e962b88 --- /dev/null +++ b/app/mobile/api/addContactChannelTopic.js @@ -0,0 +1,96 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function addContactChannelTopic(server, token, channelId, message, assets ) { + let host = ""; + if (server) { + host = `https://${server}` + } + + if (message == null && (assets == null || assets.length === 0)) { + let topic = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics?contact=${token}`, + { method: 'POST', body: JSON.stringify({}) }); + checkResponse(topic); + let slot = await topic.json(); + return slot.id; + } + else if (assets == null || assets.length === 0) { + let subject = { data: JSON.stringify(message, (key, value) => { + if (value !== null) return value + }), datatype: 'superbasictopic' }; + + let topic = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics?contact=${token}&confirm=true`, + { method: 'POST', body: JSON.stringify(subject) }); + checkResponse(topic); + let slot = await topic.json(); + return slot.id; + } + else { + let topic = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics?contact=${token}`, + { method: 'POST', body: JSON.stringify({}) }); + checkResponse(topic); + let slot = await topic.json(); + + // add each asset + message.assets = []; + for (let asset of assets) { + if (asset.image) { + const formData = new FormData(); + formData.append('asset', asset.image); + let transform = encodeURIComponent(JSON.stringify(["ithumb;photo", "icopy;photo"])); + let topicAsset = await fetch(`${host}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + message.assets.push({ + image: { + thumb: assetEntry.find(item => item.transform === 'ithumb;photo').assetId, + full: assetEntry.find(item => item.transform === 'icopy;photo').assetId, + } + }); + } + else if (asset.video) { + const formData = new FormData(); + formData.append('asset', asset.video); + let thumb = "vthumb;video;" + asset.position + let transform = encodeURIComponent(JSON.stringify(["vhd;video", "vlq;video", thumb])); + let topicAsset = await fetch(`${host}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + message.assets.push({ + video: { + thumb: assetEntry.find(item => item.transform === thumb).assetId, + lq: assetEntry.find(item => item.transform === 'vlq;video').assetId, + hd: assetEntry.find(item => item.transform === 'vhd;video').assetId, + } + }); + } + else if (asset.audio) { + const formData = new FormData(); + formData.append('asset', asset.audio); + let transform = encodeURIComponent(JSON.stringify(["acopy;audio"])); + let topicAsset = await fetch(`${host}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + message.assets.push({ + audio: { + label: asset.label, + full: assetEntry.find(item => item.transform === 'acopy;audio').assetId, + } + }); + } + } + + let subject = { data: JSON.stringify(message, (key, value) => { + if (value !== null) return value + }), datatype: 'superbasictopic' }; + + let unconfirmed = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics/${slot.id}/subject?contact=${token}`, + { method: 'PUT', body: JSON.stringify(subject) }); + checkResponse(unconfirmed); + + let confirmed = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics/${slot.id}/confirmed?contact=${token}`, + { method: 'PUT', body: JSON.stringify('confirmed') }); + checkResponse(confirmed); + return slot.id; + } +} + diff --git a/app/mobile/api/clearChannelCard.js b/app/mobile/api/clearChannelCard.js new file mode 100644 index 00000000..7e182fe9 --- /dev/null +++ b/app/mobile/api/clearChannelCard.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function clearChannelCard(token, channelId, cardId ) { + let channel = await fetchWithTimeout(`/content/channels/${channelId}/cards/${cardId}?agent=${token}`, {method: 'DELETE'}); + checkResponse(channel); + return await channel.json(); +} diff --git a/app/mobile/api/createAccount.js b/app/mobile/api/createAccount.js new file mode 100644 index 00000000..d12feb39 --- /dev/null +++ b/app/mobile/api/createAccount.js @@ -0,0 +1,11 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; +import base64 from 'react-native-base64' + +export async function createAccount(username, password) { + let headers = new Headers() + headers.append('Credentials', 'Basic ' + base64.encode(username + ":" + password)); + let profile = await fetchWithTimeout("/account/profile", { method: 'POST', headers: headers }) + checkResponse(profile); + return await profile.json() +} + diff --git a/app/mobile/api/fetchUtil.js b/app/mobile/api/fetchUtil.js new file mode 100644 index 00000000..e4eb445d --- /dev/null +++ b/app/mobile/api/fetchUtil.js @@ -0,0 +1,24 @@ +const TIMEOUT = 15000; + +//await new Promise(r => setTimeout(r, 2000)); + +export function checkResponse(response) { + if(response.status >= 400 && response.status < 600) { + throw new Error(response.url + " failed"); + } +} + +export async function fetchWithTimeout(url, options) { + return Promise.race([ + fetch(url, options).catch(err => { throw new Error(url + ' failed'); }), + new Promise((_, reject) => setTimeout(() => reject(new Error(url + ' timeout')), TIMEOUT)) + ]); +} + +export async function fetchWithCustomTimeout(url, options, timeout) { + return Promise.race([ + fetch(url, options).catch(err => { throw new Error(url + ' failed'); }), + new Promise((_, reject) => setTimeout(() => reject(new Error(url + ' timeout')), timeout)) + ]); +} + diff --git a/app/mobile/api/getAccountImageUrl.js b/app/mobile/api/getAccountImageUrl.js new file mode 100644 index 00000000..e164919f --- /dev/null +++ b/app/mobile/api/getAccountImageUrl.js @@ -0,0 +1,4 @@ +export function getAccountImageUrl(token, accountId) { + return `/admin/accounts/${accountId}/image?token=${token}` +} + diff --git a/app/mobile/api/getAccountStatus.js b/app/mobile/api/getAccountStatus.js new file mode 100644 index 00000000..3f1f0fa6 --- /dev/null +++ b/app/mobile/api/getAccountStatus.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getAccountStatus(token) { + let status = await fetchWithTimeout('/account/status?agent=' + token, { method: 'GET' }); + checkResponse(status); + return await status.json() +} + diff --git a/app/mobile/api/getAvailable.js b/app/mobile/api/getAvailable.js new file mode 100644 index 00000000..f16bd1a6 --- /dev/null +++ b/app/mobile/api/getAvailable.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getAvailable() { + let available = await fetchWithTimeout("/account/available", { method: 'GET' }) + checkResponse(available) + return await available.json() +} + diff --git a/app/mobile/api/getCardCloseMessage.js b/app/mobile/api/getCardCloseMessage.js new file mode 100644 index 00000000..a769c2f0 --- /dev/null +++ b/app/mobile/api/getCardCloseMessage.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getCardCloseMessage(token, cardId) { + let message = await fetchWithTimeout(`/contact/cards/${cardId}/closeMessage?agent=${token}`, { method: 'GET' }); + checkResponse(message); + return await message.json(); +} + diff --git a/app/mobile/api/getCardDetail.js b/app/mobile/api/getCardDetail.js new file mode 100644 index 00000000..69be56ab --- /dev/null +++ b/app/mobile/api/getCardDetail.js @@ -0,0 +1,9 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getCardDetail(token, cardId) { + let param = "?agent=" + token + let detail = await fetchWithTimeout(`/contact/cards/${cardId}/detail${param}`, { method: 'GET' }); + checkResponse(detail); + return await detail.json() +} + diff --git a/app/mobile/api/getCardImageUrl.js b/app/mobile/api/getCardImageUrl.js new file mode 100644 index 00000000..40e130e6 --- /dev/null +++ b/app/mobile/api/getCardImageUrl.js @@ -0,0 +1,4 @@ +export function getCardImageUrl(token, cardId, revision) { + return `/contact/cards/${cardId}/profile/image?agent=${token}&revision=${revision}` +} + diff --git a/app/mobile/api/getCardOpenMessage.js b/app/mobile/api/getCardOpenMessage.js new file mode 100644 index 00000000..130a6d89 --- /dev/null +++ b/app/mobile/api/getCardOpenMessage.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getCardOpenMessage(token, cardId) { + let message = await fetchWithTimeout(`/contact/cards/${cardId}/openMessage?agent=${token}`, { method: 'GET' }); + checkResponse(message); + return await message.json(); +} + diff --git a/app/mobile/api/getCardProfile.js b/app/mobile/api/getCardProfile.js new file mode 100644 index 00000000..974e6712 --- /dev/null +++ b/app/mobile/api/getCardProfile.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getCardProfile(token, cardId) { + let profile = await fetchWithTimeout(`/contact/cards/${cardId}/profile?agent=${token}`, { method: 'GET' }); + checkResponse(profile); + return await profile.json() +} + diff --git a/app/mobile/api/getCards.js b/app/mobile/api/getCards.js new file mode 100644 index 00000000..a05dad31 --- /dev/null +++ b/app/mobile/api/getCards.js @@ -0,0 +1,12 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getCards(token, revision) { + let param = "agent=" + token + if (revision != null) { + param += '&revision=' + revision + } + let cards = await fetchWithTimeout(`/contact/cards?${param}`, { method: 'GET' }); + checkResponse(cards) + return await cards.json() +} + diff --git a/app/mobile/api/getChannelDetail.js b/app/mobile/api/getChannelDetail.js new file mode 100644 index 00000000..cd5b6f04 --- /dev/null +++ b/app/mobile/api/getChannelDetail.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getChannelDetail(token, channelId) { + let detail = await fetchWithTimeout(`/content/channels/${channelId}/detail?agent=${token}`, { method: 'GET' }); + checkResponse(detail) + return await detail.json() +} + diff --git a/app/mobile/api/getChannelSummary.js b/app/mobile/api/getChannelSummary.js new file mode 100644 index 00000000..ca9ea8cf --- /dev/null +++ b/app/mobile/api/getChannelSummary.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getChannelSummary(token, channelId) { + let summary = await fetchWithTimeout(`/content/channels/${channelId}/summary?agent=${token}`, { method: 'GET' }); + checkResponse(summary) + return await summary.json() +} + diff --git a/app/mobile/api/getChannelTopic.js b/app/mobile/api/getChannelTopic.js new file mode 100644 index 00000000..550c73b4 --- /dev/null +++ b/app/mobile/api/getChannelTopic.js @@ -0,0 +1,9 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getChannelTopic(token, channelId, topicId) { + let topic = await fetchWithTimeout(`/content/channels/${channelId}/topics/${topicId}/detail?agent=${token}`, + { method: 'GET' }); + checkResponse(topic) + return await topic.json() +} + diff --git a/app/mobile/api/getChannelTopicAssetUrl.js b/app/mobile/api/getChannelTopicAssetUrl.js new file mode 100644 index 00000000..c20fb234 --- /dev/null +++ b/app/mobile/api/getChannelTopicAssetUrl.js @@ -0,0 +1,4 @@ +export function getChannelTopicAssetUrl(token, channelId, topicId, assetId) { + return `/content/channels/${channelId}/topics/${topicId}/assets/${assetId}?agent=${token}` +} + diff --git a/app/mobile/api/getChannelTopics.js b/app/mobile/api/getChannelTopics.js new file mode 100644 index 00000000..69cdd9e4 --- /dev/null +++ b/app/mobile/api/getChannelTopics.js @@ -0,0 +1,29 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getChannelTopics(token, channelId, revision, count, begin, end) { + let rev = '' + if (revision != null) { + rev = `&revision=${revision}` + } + let cnt = '' + if (count != null) { + cnt = `&count=${count}` + } + let bgn = '' + if (begin != null) { + bgn = `&begin=${begin}` + } + let edn = '' + if (end != null) { + edn = `&end=${end}` + } + let topics = await fetchWithTimeout(`/content/channels/${channelId}/topics?agent=${token}${rev}${cnt}${bgn}${edn}`, + { method: 'GET' }); + checkResponse(topics) + return { + marker: topics.headers.get('topic-marker'), + revision: topics.headers.get('topic-revision'), + topics: await topics.json(), + } +} + diff --git a/app/mobile/api/getChannels.js b/app/mobile/api/getChannels.js new file mode 100644 index 00000000..85af261c --- /dev/null +++ b/app/mobile/api/getChannels.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getChannels(token, revision) { + let param = "?agent=" + token + if (revision != null) { + param += '&channelRevision=' + revision + } + let channels = await fetchWithTimeout('/content/channels' + param, { method: 'GET' }); + checkResponse(channels) + let ret = await channels.json() + return ret; +} + diff --git a/app/mobile/api/getContactChannelDetail.js b/app/mobile/api/getContactChannelDetail.js new file mode 100644 index 00000000..ef8e5499 --- /dev/null +++ b/app/mobile/api/getContactChannelDetail.js @@ -0,0 +1,12 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getContactChannelDetail(server, token, channelId) { + let host = ""; + if (server) { + host = `https://${server}`; + } + let detail = await fetchWithTimeout(`${host}/content/channels/${channelId}/detail?contact=${token}`, { method: 'GET' }); + checkResponse(detail) + return await detail.json() +} + diff --git a/app/mobile/api/getContactChannelSummary.js b/app/mobile/api/getContactChannelSummary.js new file mode 100644 index 00000000..278cbfa6 --- /dev/null +++ b/app/mobile/api/getContactChannelSummary.js @@ -0,0 +1,12 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getContactChannelSummary(server, token, channelId) { + let host = ""; + if (server) { + host = `https://${server}`; + } + let summary = await fetchWithTimeout(`${host}/content/channels/${channelId}/summary?contact=${token}`, { method: 'GET' }); + checkResponse(summary) + return await summary.json() +} + diff --git a/app/mobile/api/getContactChannelTopic.js b/app/mobile/api/getContactChannelTopic.js new file mode 100644 index 00000000..0715c122 --- /dev/null +++ b/app/mobile/api/getContactChannelTopic.js @@ -0,0 +1,14 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getContactChannelTopic(server, token, channelId, topicId) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let topic = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics/${topicId}/detail?contact=${token}`, + { method: 'GET' }); + checkResponse(topic) + return await topic.json() +} + diff --git a/app/mobile/api/getContactChannelTopicAssetUrl.js b/app/mobile/api/getContactChannelTopicAssetUrl.js new file mode 100644 index 00000000..ec531c2b --- /dev/null +++ b/app/mobile/api/getContactChannelTopicAssetUrl.js @@ -0,0 +1,9 @@ +export function getContactChannelTopicAssetUrl(server, token, channelId, topicId, assetId) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + return `${host}/content/channels/${channelId}/topics/${topicId}/assets/${assetId}?contact=${token}` +} + diff --git a/app/mobile/api/getContactChannelTopics.js b/app/mobile/api/getContactChannelTopics.js new file mode 100644 index 00000000..df5d621a --- /dev/null +++ b/app/mobile/api/getContactChannelTopics.js @@ -0,0 +1,34 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getContactChannelTopics(server, token, channelId, revision, count, begin, end) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let rev = '' + if (revision != null) { + rev = `&revision=${revision}` + } + let cnt = '' + if (count != null) { + cnt = `&count=${count}` + } + let bgn = '' + if (begin != null) { + bgn = `&begin=${begin}` + } + let edn = '' + if (end != null) { + edn = `&end=${end}` + } + let topics = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics?contact=${token}${rev}${cnt}${bgn}${edn}`, + { method: 'GET' }); + checkResponse(topics) + return { + marker: topics.headers.get('topic-marker'), + revision: topics.headers.get('topic-revision'), + topics: await topics.json(), + } +} + diff --git a/app/mobile/api/getContactChannels.js b/app/mobile/api/getContactChannels.js new file mode 100644 index 00000000..d4769672 --- /dev/null +++ b/app/mobile/api/getContactChannels.js @@ -0,0 +1,20 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getContactChannels(server, token, viewRevision, channelRevision) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let param = "?contact=" + token + if (viewRevision != null) { + param += '&viewRevision=' + viewRevision + } + if (channelRevision != null) { + param += '&channelRevision=' + channelRevision + } + let channels = await fetchWithTimeout(`${host}/content/channels${param}`, { method: 'GET' }); + checkResponse(channels) + return await channels.json() +} + diff --git a/app/mobile/api/getContactProfile.js b/app/mobile/api/getContactProfile.js new file mode 100644 index 00000000..2d9577d9 --- /dev/null +++ b/app/mobile/api/getContactProfile.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getContactProfile(server, guid, token) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let profile = await fetchWithTimeout(`${host}/profile/message?contact=${guid}.${token}`, { method: 'GET', }); + checkResponse(profile); + return await profile.json() +} + diff --git a/app/mobile/api/getGroups.js b/app/mobile/api/getGroups.js new file mode 100644 index 00000000..a6a64a96 --- /dev/null +++ b/app/mobile/api/getGroups.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getGroups(token, revision) { + let param = "agent=" + token + if (revision != null) { + param += '&revision=' + revision + } + let groups = await fetchWithTimeout(`/alias/groups?${param}`, { method: 'GET' }); + checkResponse(groups) + return await groups.json() +} + + diff --git a/app/mobile/api/getListing.js b/app/mobile/api/getListing.js new file mode 100644 index 00000000..4a77ff10 --- /dev/null +++ b/app/mobile/api/getListing.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getListing(server) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let listing = await fetchWithTimeout(`${host}/account/listing`, { method: 'GET' }); + checkResponse(listing); + return await listing.json(); +} + diff --git a/app/mobile/api/getListingImageUrl.js b/app/mobile/api/getListingImageUrl.js new file mode 100644 index 00000000..9399b0db --- /dev/null +++ b/app/mobile/api/getListingImageUrl.js @@ -0,0 +1,10 @@ +export function getListingImageUrl(server, guid) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + return `${host}/account/listing/${guid}/image` +} + + diff --git a/app/mobile/api/getListingMessage.js b/app/mobile/api/getListingMessage.js new file mode 100644 index 00000000..1bd9eba4 --- /dev/null +++ b/app/mobile/api/getListingMessage.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getListingMessage(server, guid) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let listing = await fetchWithTimeout(`${host}/account/listing/${guid}/message`, { method: 'GET' }); + checkResponse(listing); + return await listing.json(); +} + diff --git a/app/mobile/api/getNodeAccounts.js b/app/mobile/api/getNodeAccounts.js new file mode 100644 index 00000000..7d7a43de --- /dev/null +++ b/app/mobile/api/getNodeAccounts.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getNodeAccounts(token) { + let accounts = await fetchWithTimeout(`/admin/accounts?token=${token}`, { method: 'GET' }); + checkResponse(accounts); + return await accounts.json(); +} + diff --git a/app/mobile/api/getNodeConfig.js b/app/mobile/api/getNodeConfig.js new file mode 100644 index 00000000..fea820e3 --- /dev/null +++ b/app/mobile/api/getNodeConfig.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getNodeConfig(token) { + let config = await fetchWithTimeout(`/admin/config?token=${token}`, { method: 'GET' }); + checkResponse(config); + return await config.json(); +} + diff --git a/app/mobile/api/getNodeStatus.js b/app/mobile/api/getNodeStatus.js new file mode 100644 index 00000000..9232bf0a --- /dev/null +++ b/app/mobile/api/getNodeStatus.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getNodeStatus() { + let status = await fetchWithTimeout(`/admin/status`, { method: 'GET' }); + checkResponse(status); + return await status.json(); +} + diff --git a/app/mobile/api/getProfile.js b/app/mobile/api/getProfile.js new file mode 100644 index 00000000..5fd6c1e2 --- /dev/null +++ b/app/mobile/api/getProfile.js @@ -0,0 +1,9 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getProfile(token) { + let profile = await fetchWithTimeout(`/profile?agent=${token}`, { method: 'GET' }); + checkResponse(profile) + return await profile.json() +} + + diff --git a/app/mobile/api/getProfileImageUrl.js b/app/mobile/api/getProfileImageUrl.js new file mode 100644 index 00000000..038a7544 --- /dev/null +++ b/app/mobile/api/getProfileImageUrl.js @@ -0,0 +1,4 @@ +export function getProfileImageUrl(token, revision) { + return '/profile/image?agent=' + token + "&revision=" + revision +} + diff --git a/app/mobile/api/getUsername.js b/app/mobile/api/getUsername.js new file mode 100644 index 00000000..65854f7c --- /dev/null +++ b/app/mobile/api/getUsername.js @@ -0,0 +1,12 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getUsername(name, token) { + let access = ""; + if (token) { + access = `&token=${token}` + } + let available = await fetchWithTimeout('/account/username?name=' + encodeURIComponent(name) + access, { method: 'GET' }) + checkResponse(available) + return await available.json() +} + diff --git a/app/mobile/api/package.json b/app/mobile/api/package.json new file mode 100644 index 00000000..bba89682 --- /dev/null +++ b/app/mobile/api/package.json @@ -0,0 +1,3 @@ +{ + "name": "api" +} diff --git a/app/mobile/api/removeAccount.js b/app/mobile/api/removeAccount.js new file mode 100644 index 00000000..ff45a8b1 --- /dev/null +++ b/app/mobile/api/removeAccount.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function removeAccount(token, accountId) { + let res = await fetchWithTimeout(`/admin/accounts/${accountId}?token=${token}`, { method: 'DELETE' }) + checkResponse(res); +} + diff --git a/app/mobile/api/removeCard.js b/app/mobile/api/removeCard.js new file mode 100644 index 00000000..3effc5c8 --- /dev/null +++ b/app/mobile/api/removeCard.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function removeCard(token, cardId) { + let card = await fetchWithTimeout(`/contact/cards/${cardId}?agent=${token}`, { method: 'DELETE' } ); + checkResponse(card); + return await card.json(); +} + diff --git a/app/mobile/api/removeChannel.js b/app/mobile/api/removeChannel.js new file mode 100644 index 00000000..81cbd84a --- /dev/null +++ b/app/mobile/api/removeChannel.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function removeChannel(token, channelId) { + + let channel = await fetchWithTimeout(`/content/channels/${channelId}?agent=${token}`, + { method: 'DELETE' }); + checkResponse(channel); +} diff --git a/app/mobile/api/removeChannelTopic.js b/app/mobile/api/removeChannelTopic.js new file mode 100644 index 00000000..bfe0ece5 --- /dev/null +++ b/app/mobile/api/removeChannelTopic.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function removeChannelTopic(token, channelId, topicId) { + + let channel = await fetchWithTimeout(`/content/channels/${channelId}/topics/${topicId}?agent=${token}`, + { method: 'DELETE' }); + checkResponse(channel); +} diff --git a/app/mobile/api/removeContactChannel.js b/app/mobile/api/removeContactChannel.js new file mode 100644 index 00000000..fc3c38c6 --- /dev/null +++ b/app/mobile/api/removeContactChannel.js @@ -0,0 +1,12 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function removeContactChannel(server, token, channelId) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let channel = await fetchWithTimeout(`${host}/content/channels/${channelId}?contact=${token}`, + { method: 'DELETE' }); + checkResponse(channel); +} diff --git a/app/mobile/api/removeContactChannelTopic.js b/app/mobile/api/removeContactChannelTopic.js new file mode 100644 index 00000000..ffd46a31 --- /dev/null +++ b/app/mobile/api/removeContactChannelTopic.js @@ -0,0 +1,12 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function removeContactChannelTopic(server, token, channelId, topicId) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let channel = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics/${topicId}?contact=${token}`, + { method: 'DELETE' }); + checkResponse(channel); +} diff --git a/app/mobile/api/setAccountAccess.js b/app/mobile/api/setAccountAccess.js new file mode 100644 index 00000000..48a947d6 --- /dev/null +++ b/app/mobile/api/setAccountAccess.js @@ -0,0 +1,9 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setAccountAccess(token) { + let app = { Name: "indicom", Description: "decentralized communication" } + let access = await fetchWithTimeout(`/account/access?token=${token}`, { method: 'PUT', body: JSON.stringify(app) }) + checkResponse(access) + return await access.json() +} + diff --git a/app/mobile/api/setAccountLogin.js b/app/mobile/api/setAccountLogin.js new file mode 100644 index 00000000..021dbc38 --- /dev/null +++ b/app/mobile/api/setAccountLogin.js @@ -0,0 +1,10 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; +import base64 from 'react-native-base64' + +export async function setAccountLogin(token, username, password) { + let headers = new Headers() + headers.append('Credentials', 'Basic ' + base64.encode(username + ":" + password)); + let res = await fetchWithTimeout(`/account/login?agent=${token}`, { method: 'PUT', headers }) + checkResponse(res); +} + diff --git a/app/mobile/api/setAccountSearchable.js b/app/mobile/api/setAccountSearchable.js new file mode 100644 index 00000000..84f357e5 --- /dev/null +++ b/app/mobile/api/setAccountSearchable.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setAccountSearchable(token, flag) { + let res = await fetchWithTimeout('/account/searchable?agent=' + token, { method: 'PUT', body: JSON.stringify(flag) }) + checkResponse(res); +} + diff --git a/app/mobile/api/setAccountStatus.js b/app/mobile/api/setAccountStatus.js new file mode 100644 index 00000000..a76459fe --- /dev/null +++ b/app/mobile/api/setAccountStatus.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setAccountStatus(token, accountId, disabled) { + let res = await fetchWithTimeout(`/admin/accounts/${accountId}/status?token=${token}`, { method: 'PUT', body: JSON.stringify(disabled) }) + checkResponse(res); +} + diff --git a/app/mobile/api/setCardCloseMessage.js b/app/mobile/api/setCardCloseMessage.js new file mode 100644 index 00000000..f479224e --- /dev/null +++ b/app/mobile/api/setCardCloseMessage.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setCardCloseMessage(server, message) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let status = await fetchWithTimeout(`${host}/contact/closeMessage`, { method: 'PUT', body: JSON.stringify(message) }); + checkResponse(status); + return await status.json(); +} + diff --git a/app/mobile/api/setCardOpenMessage.js b/app/mobile/api/setCardOpenMessage.js new file mode 100644 index 00000000..f89bcd93 --- /dev/null +++ b/app/mobile/api/setCardOpenMessage.js @@ -0,0 +1,13 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setCardOpenMessage(server, message) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let status = await fetchWithTimeout(`${host}/contact/openMessage`, { method: 'PUT', body: JSON.stringify(message) }); + checkResponse(status); + return await status.json(); +} + diff --git a/app/mobile/api/setCardProfile.js b/app/mobile/api/setCardProfile.js new file mode 100644 index 00000000..7c6a2215 --- /dev/null +++ b/app/mobile/api/setCardProfile.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setCardProfile(token, cardId, message) { + let profile = await fetchWithTimeout(`/contact/cards/${cardId}/profile?agent=${token}`, { method: 'PUT', body: JSON.stringify(message) }); + checkResponse(profile); + return await profile.json() +} + diff --git a/app/mobile/api/setCardStatus.js b/app/mobile/api/setCardStatus.js new file mode 100644 index 00000000..843bda2b --- /dev/null +++ b/app/mobile/api/setCardStatus.js @@ -0,0 +1,20 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setCardConnecting(token, cardId) { + let card = await fetchWithTimeout(`/contact/cards/${cardId}/status?agent=${token}`, { method: 'PUT', body: JSON.stringify('connecting') } ); + checkResponse(card); + return await card.json(); +} + +export async function setCardConnected(token, cardId, access, view, article, channel, profile) { + let card = await fetchWithTimeout(`/contact/cards/${cardId}/status?agent=${token}&token=${access}&viewRevision=${view}&articleRevision=${article}&channelRevision=${channel}&profileRevision=${profile}`, { method: 'PUT', body: JSON.stringify('connected') } ); + checkResponse(card); + return await card.json(); +} + +export async function setCardConfirmed(token, cardId) { + let card = await fetchWithTimeout(`/contact/cards/${cardId}/status?agent=${token}`, { method: 'PUT', body: JSON.stringify('confirmed') } ); + checkResponse(card); + return await card.json(); +} + diff --git a/app/mobile/api/setChannelCard.js b/app/mobile/api/setChannelCard.js new file mode 100644 index 00000000..c9da3287 --- /dev/null +++ b/app/mobile/api/setChannelCard.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setChannelCard(token, channelId, cardId ) { + let channel = await fetchWithTimeout(`/content/channels/${channelId}/cards/${cardId}?agent=${token}`, {method: 'PUT'}); + checkResponse(channel); + return await channel.json(); +} diff --git a/app/mobile/api/setChannelSubject.js b/app/mobile/api/setChannelSubject.js new file mode 100644 index 00000000..49c95e04 --- /dev/null +++ b/app/mobile/api/setChannelSubject.js @@ -0,0 +1,9 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setChannelSubject(token, channelId, subject ) { + let data = { subject }; + let params = { dataType: 'superbasic', data: JSON.stringify(data) }; + let channel = await fetchWithTimeout(`/content/channels/${channelId}/subject?agent=${token}`, { method: 'PUT', body: JSON.stringify(params)} ); + checkResponse(channel); + return await channel.json(); +} diff --git a/app/mobile/api/setChannelTopicAsset.js b/app/mobile/api/setChannelTopicAsset.js new file mode 100644 index 00000000..116b4801 --- /dev/null +++ b/app/mobile/api/setChannelTopicAsset.js @@ -0,0 +1,48 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setChannelTopicSubject(token, channelId, topicId, asset) { + if (asset.image) { + const formData = new FormData(); + formData.append('asset', asset.image); + let transform = encodeURIComponent(JSON.stringify(["ithumb;photo", "icopy;photo"])); + let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + return { + image: { + thumb: assetEntry.find(item => item.transform === 'ithumb;photo').assetId, + full: assetEntry.find(item => item.transform === 'icopy;photo').assetId, + } + }; + } + else if (asset.video) { + const formData = new FormData(); + formData.append('asset', asset.video); + let thumb = 'vthumb;video;' + asset.position; + let transform = encodeURIComponent(JSON.stringify(["vlq;video", "vhd;video", thumb])); + let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + return { + video: { + thumb: assetEntry.find(item => item.transform === thumb).assetId, + lq: assetEntry.find(item => item.transform === 'vlq;video').assetId, + hd: assetEntry.find(item => item.transform === 'vhd;video').assetId, + } + }; + } + else if (asset.audio) { + const formData = new FormData(); + formData.append('asset', asset.audio); + let transform = encodeURIComponent(JSON.stringify(["acopy;audio"])); + let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + return { + audio: { + label: asset.label, + full: assetEntry.find(item => item.transform === 'acopy;audio').assetId, + } + }; + } +} diff --git a/app/mobile/api/setChannelTopicSubject.js b/app/mobile/api/setChannelTopicSubject.js new file mode 100644 index 00000000..3ef43810 --- /dev/null +++ b/app/mobile/api/setChannelTopicSubject.js @@ -0,0 +1,11 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setChannelTopicSubject(token, channelId, topicId, data) { + let subject = { data: JSON.stringify(data, (key, value) => { + if (value !== null) return value + }), datatype: 'superbasictopic' }; + + let channel = await fetchWithTimeout(`/content/channels/${channelId}/topics/${topicId}/subject?agent=${token}&confirm=true`, + { method: 'PUT', body: JSON.stringify(subject) }); + checkResponse(channel); +} diff --git a/app/mobile/api/setContactChannelTopicAsset.js b/app/mobile/api/setContactChannelTopicAsset.js new file mode 100644 index 00000000..eda4244a --- /dev/null +++ b/app/mobile/api/setContactChannelTopicAsset.js @@ -0,0 +1,53 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setContactChannelTopicSubject(server, token, channelId, topicId, asset) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + if (asset.image) { + const formData = new FormData(); + formData.append('asset', asset.image); + let transform = encodeURIComponent(JSON.stringify(["ithumb;photo", "icopy;photo"])); + let topicAsset = await fetch(`${host}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + return { + image: { + thumb: assetEntry.find(item => item.transform === 'ithumb;photo').assetId, + full: assetEntry.find(item => item.transform === 'icopy;photo').assetId, + } + }; + } + else if (asset.video) { + const formData = new FormData(); + formData.append('asset', asset.video); + let thumb = "vthumb;video;" + asset.position + let transform = encodeURIComponent(JSON.stringify(["vhd;video", "vlq;video", thumb])); + let topicAsset = await fetch(`${host}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + return { + video: { + thumb: assetEntry.find(item => item.transform === thumb).assetId, + lq: assetEntry.find(item => item.transform === 'vlq;video').assetId, + hd: assetEntry.find(item => item.transform === 'vhd;video').assetId, + } + }; + } + else if (asset.audio) { + const formData = new FormData(); + formData.append('asset', asset.audio); + let transform = encodeURIComponent(JSON.stringify(["acopy;audio"])); + let topicAsset = await fetch(`${host}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData }); + checkResponse(topicAsset); + let assetEntry = await topicAsset.json(); + return { + audio: { + label: asset.label, + full: assetEntry.find(item => item.transform === 'acopy;audio').assetId, + } + }; + } +} diff --git a/app/mobile/api/setContactChannelTopicSubject.js b/app/mobile/api/setContactChannelTopicSubject.js new file mode 100644 index 00000000..dce13224 --- /dev/null +++ b/app/mobile/api/setContactChannelTopicSubject.js @@ -0,0 +1,16 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setContactChannelTopicSubject(server, token, channelId, topicId, data) { + let host = ""; + if (server) { + host = `https://${server}`; + } + + let subject = { data: JSON.stringify(data, (key, value) => { + if (value !== null) return value + }), datatype: 'superbasictopic' }; + + let channel = await fetchWithTimeout(`${host}/content/channels/${channelId}/topics/${topicId}/subject?contact=${token}&confirm=true`, + { method: 'PUT', body: JSON.stringify(subject) }); + checkResponse(channel); +} diff --git a/app/mobile/api/setLogin.js b/app/mobile/api/setLogin.js new file mode 100644 index 00000000..ab324d07 --- /dev/null +++ b/app/mobile/api/setLogin.js @@ -0,0 +1,11 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; +import base64 from 'react-native-base64' + +export async function setLogin(username, password) { + let headers = new Headers() + headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password)); + let app = { Name: "indicom", Description: "decentralized communication" } + let login = await fetchWithTimeout('/account/apps', { method: 'POST', body: JSON.stringify(app), headers: headers }) + checkResponse(login) + return await login.json() +} diff --git a/app/mobile/api/setNodeConfig.js b/app/mobile/api/setNodeConfig.js new file mode 100644 index 00000000..11da253e --- /dev/null +++ b/app/mobile/api/setNodeConfig.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setNodeConfig(token, config) { + let body = JSON.stringify(config); + let settings = await fetchWithTimeout(`/admin/config?token=${token}`, { method: 'PUT', body }); + checkResponse(settings); +} + diff --git a/app/mobile/api/setNodeStatus.js b/app/mobile/api/setNodeStatus.js new file mode 100644 index 00000000..2d2bc860 --- /dev/null +++ b/app/mobile/api/setNodeStatus.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setNodeStatus(token) { + let status = await fetchWithTimeout(`/admin/status?token=${token}`, { method: 'PUT' }); + checkResponse(status); +} + diff --git a/app/mobile/api/setProfileData.js b/app/mobile/api/setProfileData.js new file mode 100644 index 00000000..00a405fc --- /dev/null +++ b/app/mobile/api/setProfileData.js @@ -0,0 +1,9 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setProfileData(token, name, location, description) { + let data = { name: name, location: location, description: description }; + let profile = await fetchWithTimeout(`/profile/data?agent=${token}`, { method: 'PUT', body: JSON.stringify(data) }); + checkResponse(profile) + return await profile.json() +} + diff --git a/app/mobile/api/setProfileImage.js b/app/mobile/api/setProfileImage.js new file mode 100644 index 00000000..9eb46a11 --- /dev/null +++ b/app/mobile/api/setProfileImage.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setProfileImage(token, image) { + let profile = await fetchWithTimeout(`/profile/image?agent=${token}`, { method: 'PUT', body: JSON.stringify(image) }); + checkResponse(profile) + return await profile.json() +} + diff --git a/app/mobile/context/package.json b/app/mobile/context/package.json new file mode 100644 index 00000000..26a8eaac --- /dev/null +++ b/app/mobile/context/package.json @@ -0,0 +1,3 @@ +{ + "name": "context" +} diff --git a/app/mobile/context/useAppContext.hook.js b/app/mobile/context/useAppContext.hook.js index be5ea641..83a26c44 100644 --- a/app/mobile/context/useAppContext.hook.js +++ b/app/mobile/context/useAppContext.hook.js @@ -1,12 +1,115 @@ -import { useState } from 'react'; +import { useEffect, useState, useRef, useContext } from 'react'; +import { getAvailable } from 'api/getAvailable'; +import { setLogin } from 'api/setLogin'; +import { setAccountAccess } from 'api/setAccountAccess'; +import { addAccount } from 'api/addAccount'; +import { getUsername } from 'api/getUsername'; export function useAppContext() { const [state, setState] = useState({}); + const [appRevision, setAppRevision] = useState(); + + const delay = useRef(2); + const ws = useRef(null); + const revision = useRef(null); + + const updateState = (value) => { + setState((s) => ({ ...s, ...value })) + } + + const resetData = () => { + revision.current = null; + setState({}); + } const actions = { + available: getAvailable, + username: getUsername, + create: async (username, password, token) => { + await appCreate(username, password, token) + }, + login: async (username, password) => { + await appLogin(username, password) + }, + logout: () => { + appLogout(); + resetData(); + }, } + const appCreate = async (username, password, token) => { + await addAccount(username, password, token); + let access = await setLogin(username, password) + setWebsocket(access.appToken) + return access.created; + } + + const appLogin = async (username, password) => { + let access = await setLogin(username, password) + setWebsocket(access.appToken) + return access.created; + } + + const appLogout = () => { + clearWebsocket() + } + + const setWebsocket = (token) => { + + let protocol; + if (window.location.protocol === 'http:') { + protocol = 'ws://'; + } + else { + protocol = 'wss://'; + } + + ws.current = new WebSocket(protocol + window.location.host + "/status"); + ws.current.onmessage = (ev) => { + try { + let rev = JSON.parse(ev.data); + setAppRevision(rev); + updateState({ disconnected: false }); + } + catch (err) { + console.log(err); + } + } + ws.current.onclose = (e) => { + updateState({ disconnected: true }); + console.log(e) + setTimeout(() => { + if (ws.current != null) { + ws.current.onmessage = () => {} + ws.current.onclose = () => {} + ws.current.onopen = () => {} + ws.current.onerror = () => {} + setWebsocket(token); + if (delay.current < 15) { + delay.current += 1; + } + } + }, delay.current * 1000) + } + ws.current.onopen = () => { + ws.current.send(JSON.stringify({ AppToken: token })) + } + ws.current.error = (e) => { + updateState({ disconnected: true }); + console.log(e) + } + } + + const clearWebsocket = () => { + ws.current.onclose = () => {} + ws.current.close() + ws.current = null + } + + useEffect(() => { + // pull store set websocket + }, []); + return { state, actions } } - diff --git a/app/mobile/package.json b/app/mobile/package.json index 361e97ef..fb2e03c7 100644 --- a/app/mobile/package.json +++ b/app/mobile/package.json @@ -15,7 +15,10 @@ "react": "18.0.0", "react-dom": "18.0.0", "react-native": "0.69.5", + "react-native-base64": "^0.2.1", "react-native-web": "~0.18.7", + "react-router-dom": "6", + "react-router-native": "^6.3.0", "styled-components": "^5.3.5" }, "devDependencies": { diff --git a/app/mobile/root/Root.jsx b/app/mobile/root/Root.jsx new file mode 100644 index 00000000..649017a7 --- /dev/null +++ b/app/mobile/root/Root.jsx @@ -0,0 +1,3 @@ +export function Root() { + return <> +} diff --git a/app/mobile/session/Session.jsx b/app/mobile/session/Session.jsx new file mode 100644 index 00000000..9df2788c --- /dev/null +++ b/app/mobile/session/Session.jsx @@ -0,0 +1,4 @@ +export function Session() { + return <> +} + diff --git a/app/mobile/yarn.lock b/app/mobile/yarn.lock index 7a408c0b..5d14c6b8 100644 --- a/app/mobile/yarn.lock +++ b/app/mobile/yarn.lock @@ -1013,7 +1013,7 @@ pirates "^4.0.5" source-map-support "^0.5.16" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.14.0", "@babel/runtime@^7.18.6", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.14.0", "@babel/runtime@^7.18.6", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== @@ -1779,6 +1779,11 @@ dependencies: "@types/yargs-parser" "*" +"@ungap/url-search-params@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ungap/url-search-params/-/url-search-params-0.1.4.tgz#727e9b4c811beaa6be6d7e4cc0516663c884cfd0" + integrity sha512-RLwrxCTDNiNev9hpr9rDq8NyeQ8Nn0X1we4Wu7Tlf368I8r+7hBj3uObhifhuLk74egaYaSX5nUsBlWz6kjj+A== + "@urql/core@2.3.6": version "2.3.6" resolved "https://registry.yarnpkg.com/@urql/core/-/core-2.3.6.tgz#ee0a6f8fde02251e9560c5f17dce5cd90f948552" @@ -3586,6 +3591,13 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" +history@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" + integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== + dependencies: + "@babel/runtime" "^7.7.6" + hoist-non-react-statics@^3.0.0: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -5384,6 +5396,11 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-native-base64@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/react-native-base64/-/react-native-base64-0.2.1.tgz#3d0e73a649c4c0129f7b7695d3912456aebae847" + integrity sha512-eHgt/MA8y5ZF0aHfZ1aTPcIkDWxza9AaEk4GcpIX+ZYfZ04RcaNahO+527KR7J44/mD3efYfM23O2C1N44ByWA== + react-native-codegen@^0.69.2: version "0.69.2" resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.69.2.tgz#e33ac3b1486de59ddae687b731ddbfcef8af0e4e" @@ -5456,6 +5473,30 @@ react-refresh@^0.4.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" integrity sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA== +react-router-dom@6: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" + integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw== + dependencies: + history "^5.2.0" + react-router "6.3.0" + +react-router-native@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router-native/-/react-router-native-6.3.0.tgz#d8a14006cba4522fef335879997b7d7477d28748" + integrity sha512-Y+UuU6Typnz1eGWfYf2UYmh1qItbrNBK5kr3p7ZsamsLIxCKSoYo2YJyz9JOgRiv1nOFsCoSkpQJPYLAz68hlQ== + dependencies: + "@ungap/url-search-params" "^0.1.4" + history "^5.2.0" + react-router "6.3.0" + +react-router@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" + integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== + dependencies: + history "^5.2.0" + react-shallow-renderer@16.15.0: version "16.15.0" resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457"