Skip to content

Instantly share code, notes, and snippets.

@KATT
Last active April 16, 2020 14:29
Show Gist options
  • Save KATT/de65f8492178fb96ec9ca7358b36a587 to your computer and use it in GitHub Desktop.
Save KATT/de65f8492178fb96ec9ca7358b36a587 to your computer and use it in GitHub Desktop.
import { useEffect, useState, useRef } from 'react';
import Talk from 'talkjs';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export type TalkJSState =
| {
status: 'error';
error: Error;
session: null;
}
| {
status: 'loading';
session: null;
}
| {
status: 'ok';
session: Talk.Session;
};
export interface UseTalkJSProps {
options?: null | {
user: Talk.UserOptions;
session: Omit<Talk.SessionOptions, 'me'>;
notifications: {
email: boolean;
phone: boolean;
};
};
}
export function useTalkJS({ options }: UseTalkJSProps): TalkJSState {
const sessionRef = useRef<Talk.Session | null>(null);
const [state, setState] = useState<TalkJSState>({
status: 'loading',
session: null,
});
const [ready, setReady] = useState(false);
useEffect(() => {
Talk.ready
.then(() => {
setReady(true);
})
.catch((error) => {
setState({
status: 'error',
session: null,
error,
});
});
}, []);
useEffect(() => {
if (!ready || !options) {
return;
}
const { user, notifications, session } = options;
const me = new Talk.User({
...user,
email: notifications.email ? user.email : null,
phone: notifications.phone ? user.phone : null,
});
const sessionIntance = new Talk.Session({
appId: session.appId,
me,
signature: session.signature,
});
setState({
status: 'ok',
session: sessionIntance,
});
if (sessionRef.current) {
// destroy previous session
sessionRef.current?.destroy();
console.log('♻️ Refreshed talkJS instance');
}
sessionRef.current = sessionIntance;
}, [options, ready]);
return state;
}
function useTalkJSWrapper(userId: string): TalkJSState {
const { data, error } = useAppUserAutoSubscription({
variables: {
id: userId,
},
});
const options = useMemo(() => {
const user = data?.User_by_pk;
if (!user) {
return null;
}
const opts: UseTalkJSProps['options'] = {
user: {
id: user.id,
role: 'user',
name: user.name,
email: user.email,
phone: user.phone,
photoUrl: user.picture,
},
session: {
appId: env.REACT_APP_TALKJS_APP_ID,
},
notifications: {
email: user.messageEmailNotifications,
phone: user.messagePhoneNotifications,
},
};
return opts;
}, [data]);
const talkjs = useTalkJS({ options });
if (error) {
return {
status: 'error',
session: null,
error,
};
}
return talkjs;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment