diff --git a/net/server/internal/api_status.go b/net/server/internal/api_status.go
index ae52b0cf..f41bddf2 100644
--- a/net/server/internal/api_status.go
+++ b/net/server/internal/api_status.go
@@ -113,7 +113,7 @@ func getRevision(account *store.Account) Activity {
r.Card = account.CardRevision
var a Activity
- a.Revision = r
+ a.Revision = &r
return a
}
@@ -131,7 +131,7 @@ func SetRing(card *store.Card, ring Ring) {
phone.CalleeToken = ring.CalleeToken
phone.CardID = card.CardSlot.CardSlotID
var a Activity
- a.Phone = phone;
+ a.Phone = ☎
msg, err := json.Marshal(a)
if err != nil {
ErrMsg(err);
diff --git a/net/server/internal/models.go b/net/server/internal/models.go
index f0ab4ab9..0642ce58 100644
--- a/net/server/internal/models.go
+++ b/net/server/internal/models.go
@@ -395,9 +395,9 @@ type ProfileData struct {
//Activity listener for account
type Activity struct {
- Revision Revision `json:"revision,emitempty"`
+ Revision *Revision `json:"revision,emitempty"`
- Phone Phone `json:"ring",omitempty"`
+ Phone *Phone `json:"ring",omitempty"`
}
//Revision revision of each account module
diff --git a/net/web/src/App.js b/net/web/src/App.js
index 5e8c23c7..2ef1e566 100644
--- a/net/web/src/App.js
+++ b/net/web/src/App.js
@@ -12,6 +12,7 @@ import { StoreContextProvider } from 'context/StoreContext';
import { UploadContextProvider } from 'context/UploadContext';
import { ViewportContextProvider } from 'context/ViewportContext';
import { ConversationContextProvider } from 'context/ConversationContext';
+import { RingContextProvider } from 'context/RingContext';
import { AppWrapper } from 'App.styled';
import { Root } from './root/Root';
@@ -30,33 +31,35 @@ function App() {
-
-
-
-
-
-
- } />
- } />
- } />
- } />
- } />
-
-
-
- }>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+ }>
+
+
+
+
+
+
+
+
diff --git a/net/web/src/api/addContactRing.js b/net/web/src/api/addContactRing.js
new file mode 100644
index 00000000..fd387762
--- /dev/null
+++ b/net/web/src/api/addContactRing.js
@@ -0,0 +1,12 @@
+import { checkResponse, fetchWithTimeout } from './fetchUtil';
+
+export async function addContactRing(server, token, call) {
+ let host = "";
+ if (server) {
+ host = `https://${server}`
+ }
+
+ let ring = await fetchWithTimeout(`${host}/talk/ring?contact=${token}`, { method: 'POST', body: JSON.stringify(call) });
+ checkResponse(ring);
+}
+
diff --git a/net/web/src/context/RingContext.js b/net/web/src/context/RingContext.js
new file mode 100644
index 00000000..1ec9e7ca
--- /dev/null
+++ b/net/web/src/context/RingContext.js
@@ -0,0 +1,14 @@
+import { createContext } from 'react';
+import { useRingContext } from './useRingContext.hook';
+
+export const RingContext = createContext({});
+
+export function RingContextProvider({ children }) {
+ const { state, actions } = useRingContext();
+ return (
+
+ {children}
+
+ );
+}
+
diff --git a/net/web/src/context/useAppContext.hook.js b/net/web/src/context/useAppContext.hook.js
index 2d281a09..eff405bb 100644
--- a/net/web/src/context/useAppContext.hook.js
+++ b/net/web/src/context/useAppContext.hook.js
@@ -9,6 +9,7 @@ import { CardContext } from './CardContext';
import { ChannelContext } from './ChannelContext';
import { StoreContext } from './StoreContext';
import { UploadContext } from './UploadContext';
+import { RingContext } from './RingContext';
import { createWebsocket } from 'api/fetchUtil';
export function useAppContext(websocket) {
@@ -30,6 +31,7 @@ export function useAppContext(websocket) {
setState((s) => ({ ...s, ...value }))
}
+ const ringContext = useContext(RingContext);
const uploadContext = useContext(UploadContext);
const storeContext = useContext(StoreContext);
const accountContext = useContext(AccountContext);
@@ -57,6 +59,7 @@ export function useAppContext(websocket) {
const clearSession = () => {
uploadContext.actions.clear();
storeContext.actions.clear();
+ ringContext.actions.clear();
accountContext.actions.clearToken();
profileContext.actions.clearToken();
@@ -173,8 +176,14 @@ export function useAppContext(websocket) {
let activity = JSON.parse(ev.data);
updateState({ status: 'connected' });
if (activity.revision) {
+console.log("GOR REVISION");
setAppRevision(activity.revision);
}
+ if (activity.ring) {
+console.log("GOT PHONE!");
+ const { cardId, callId, calleeToken } = activity.ring;
+ ringContext.actions.ring(cardId, callId, calleeToken);
+ }
}
catch (err) {
console.log(err);
diff --git a/net/web/src/context/useRingContext.hook.js b/net/web/src/context/useRingContext.hook.js
new file mode 100644
index 00000000..89a51cca
--- /dev/null
+++ b/net/web/src/context/useRingContext.hook.js
@@ -0,0 +1,60 @@
+import { useEffect, useContext, useState, useRef } from 'react';
+
+export function useRingContext() {
+ const [state, setState] = useState({
+ ringing: new Map(),
+ });
+ const access = useRef(null);
+
+ const EXPIRE = 3000
+ const ringing = useRef(new Map());
+
+ const updateState = (value) => {
+ setState((s) => ({ ...s, ...value }))
+ }
+
+ const actions = {
+ clear: () => {
+ ringing.current = new Map();
+ updateState({ ringing: ringing.current });
+ },
+ ring: (cardId, callId, calleeToken) => {
+ const key = `${cardId}:${callId}`
+ const call = ringing.current.get(key) || { calleeToken, callId }
+ call.expires = Date.now() + EXPIRE;
+ ringing.current.set(key, call);
+ updateState({ ringing: ringing.current });
+ },
+ ignore: (cardId, callId) => {
+ const key = `${cardId}:${callId}`
+ const call = ringing.current.get(key);
+ if (call) {
+ call.status = 'ignored'
+ ringing.current.set(key, call);
+ updateState({ ringing: ringing.current });
+ }
+ },
+ decline: (cardId, callId) => {
+ const key = `${cardId}:${callId}`
+ const call = ringing.current.get(key);
+ if (call) {
+ call.status = 'declined'
+ ringing.current.set(key, call);
+ updateState({ ringing: ringing.current });
+ }
+ },
+ accept: (cardId, callId) => {
+ const key = `${cardId}:${callId}`
+ const call = ringing.current.get(key);
+ if (call) {
+ call.status = 'accepted'
+ ringing.current.set(key, call);
+ updateState({ ringing: ringing.current });
+ }
+ },
+ }
+
+ return { state, actions }
+}
+
+
diff --git a/net/web/src/session/contact/Contact.jsx b/net/web/src/session/contact/Contact.jsx
index 98dfff28..fd410c53 100644
--- a/net/web/src/session/contact/Contact.jsx
+++ b/net/web/src/session/contact/Contact.jsx
@@ -9,6 +9,10 @@ export function Contact({ close, guid, listing }) {
const [ modal, modalContext ] = Modal.useModal();
const { state, actions } = useContact(guid, listing, close);
+ const ring = async () => {
+ actions.ring();
+ };
+
const updateContact = async (action) => {
try {
await action();
@@ -132,6 +136,9 @@ export function Contact({ close, guid, listing }) {
updateContact(actions.saveConnect)}>Save and Request
)}
+
+ RING
+
diff --git a/net/web/src/session/contact/useContact.hook.js b/net/web/src/session/contact/useContact.hook.js
index b7b9f146..6a41e5f9 100644
--- a/net/web/src/session/contact/useContact.hook.js
+++ b/net/web/src/session/contact/useContact.hook.js
@@ -3,6 +3,7 @@ import { CardContext } from 'context/CardContext';
import { ViewportContext } from 'context/ViewportContext';
import { getListingMessage } from 'api/getListingMessage';
import { getCardByGuid } from 'context/cardUtil';
+import { addContactRing } from 'api/addContactRing';
export function useContact(guid, listing, close) {
@@ -155,6 +156,14 @@ export function useContact(guid, listing, close) {
close();
});
},
+ ring: async () => {
+ console.log("ringing!!");
+ const contact = card.state.cards.get(state.cardId);
+ const { node, guid } = contact.data.cardProfile;
+ const { token } = contact.data.cardDetail;
+ await addContactRing(node, `${guid}.${token}`, { index: 0, callId: 'abc', calleeToken: '123' });
+ console.log(contact);
+ },
};
return { state, actions };
diff --git a/net/web/src/session/useSession.hook.js b/net/web/src/session/useSession.hook.js
index 7587193f..b9259346 100644
--- a/net/web/src/session/useSession.hook.js
+++ b/net/web/src/session/useSession.hook.js
@@ -5,6 +5,7 @@ import { CardContext } from 'context/CardContext';
import { StoreContext } from 'context/StoreContext';
import { ViewportContext } from 'context/ViewportContext';
import { ProfileContext } from 'context/ProfileContext';
+import { RingContext } from 'context/RingContext';
export function useSession() {
@@ -27,6 +28,7 @@ export function useSession() {
const app = useContext(AppContext);
const card = useContext(CardContext);
const store = useContext(StoreContext);
+ const ring = useContext(RingContext);
const viewport = useContext(ViewportContext);
const profile = useContext(ProfileContext);
@@ -39,6 +41,10 @@ export function useSession() {
setState((s) => ({ ...s, ...value }));
}
+ useEffect(() => {
+ console.log(ring.state);
+ }, [ring.state]);
+
useEffect(() => {
if (!profile.state.identity?.guid) {
updateState({ loading: true });