Skip to content

Commit

Permalink
feat: support popup login (#400)
Browse files Browse the repository at this point in the history
- 支持弹窗形式登录
- 支持在对话中登录
![屏幕截图 2024-09-15
223528](https://github.com/user-attachments/assets/e4dbafbe-a53b-439b-975c-16b0262a763c)
  • Loading branch information
RaoHai authored Sep 16, 2024
2 parents 275ea9b + 2b523a8 commit a4e727e
Show file tree
Hide file tree
Showing 23 changed files with 21,382 additions and 15,271 deletions.
2 changes: 1 addition & 1 deletion assistant/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@petercatai/assistant",
"version": "1.0.5",
"version": "1.0.6",
"description": "Peter Cat Assistant Application",
"module": "dist/esm/index.js",
"types": "dist/esm/index.d.ts",
Expand Down
2 changes: 2 additions & 0 deletions assistant/src/Chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ const Chat: FC<ChatProps> = memo(
{UITemplateRender({
templateId: template_id,
cardData: data,
apiDomain: apiDomain,
token: token!,
})}
</div>
)}
Expand Down
30 changes: 30 additions & 0 deletions assistant/src/Chat/template/LoginCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { Button } from 'antd';

import GitHubIcon from '../../icons/GitHubIcon';
import useUser from '../../hooks/useUser';

const LoginCard = ({ apiDomain, token }: { apiDomain: string; token: string; }) => {
const { user, isLoading, actions } = useUser({ apiDomain, fingerprint: token });

if (isLoading) {
return <Button disabled loading>Loading...</Button>
}

if (!user || user.id.startsWith('client|')) {
return (
<Button
onClick={actions.doLogin}
type="primary"
icon={<GitHubIcon />}
>
Login
</Button>
);
}

return <p>你已完成登录。可以继续输入了。</p>

}

export default LoginCard;
11 changes: 9 additions & 2 deletions assistant/src/Chat/template/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import GitInsightCard from './GitInsightCard';
import LoginCard from './LoginCard';

export const UITemplateRender = ({ templateId, cardData }: { templateId: string, cardData: any }) => {
export const UITemplateRender = ({ templateId, apiDomain, token, cardData }: { templateId: string, apiDomain: string; token: string; cardData: any }) => {
if (templateId === 'GIT_INSIGHT') {
return (
<GitInsightCard
Expand All @@ -10,6 +11,12 @@ export const UITemplateRender = ({ templateId, cardData }: { templateId: string,
commitCount={cardData?.commits}
/>
);
return null;
}

if (templateId === 'LOGIN_INVITE') {
return (
<LoginCard apiDomain={apiDomain} token={token} />
);
}
return null;
};
59 changes: 59 additions & 0 deletions assistant/src/hooks/useUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use client';

import { getUserInfo, requestLogout } from '../services/UserController';
import useSWR from 'swr';
import { popupCenter } from '../utils/popcenter';
import { useEffect } from 'react';

function useUser({ apiDomain, fingerprint }: { apiDomain: string; fingerprint: string }) {
const { data: user, isLoading, mutate } = useSWR(
['user.info'],
async () => getUserInfo(apiDomain, { clientId: fingerprint }),
{ suspense: false },
);


const doLogin = () => {
popupCenter({
url: '/user/login',
title: 'Login',
w: 600,
h: 400,
});
}

const handleLoginPostMessage = (event: MessageEvent) => {
if (event.origin !== location.origin) {
return;
}

const { status } = event.data;
if (status === 'success') {
mutate();
}
};

useEffect(() => {
window.addEventListener('message', handleLoginPostMessage);
return () => {
window.removeEventListener('message', handleLoginPostMessage);
}
}, []);

const doLogout = async () => {
await requestLogout(apiDomain);
mutate();
}


return {
user,
isLoading,
actions: {
doLogin,
doLogout,
},
};
}

export default useUser;
11 changes: 11 additions & 0 deletions assistant/src/icons/GitHubIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const GitHubIcon = (props: { className?: string }) => (
<svg xmlns="http://www.w3.org/2000/svg" width={25} height={24} fill="none" {...props}>
<path
fill="#fff"
d="M20.552 5.083c.835-1.55-.119-3.578-.119-3.578-2.147 0-3.697 1.43-3.697 1.43-.835-.476-3.578-.476-3.578-.476s-2.743 0-3.578.477c0 0-1.55-1.431-3.698-1.431 0 0-.954 2.027-.119 3.578 0 0-1.908 1.789-1.192 5.605.672 3.586 3.816 4.532 5.844 4.532 0 0-.835.716-.716 1.908 0 0-1.193.716-2.385.24-1.193-.478-1.79-1.67-1.79-1.67s-1.192-1.551-2.385-.955c0 0-.357.358.954.954 0 0 .955 1.431 1.312 2.266.358.835 2.266 1.55 4.175 1.074v2.743s0 .238-.477.358c-.477.119-.477.357-.239.357h8.587c.239 0 .239-.238-.238-.357-.477-.12-.477-.358-.477-.358v-2.743s.01-1.43 0-1.909a2.781 2.781 0 0 0-.835-1.908c2.027 0 5.171-.946 5.844-4.532.715-3.816-1.193-5.605-1.193-5.605Z"
/>
</svg>
);
export default GitHubIcon;
1 change: 1 addition & 0 deletions assistant/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export { default as Chat } from './Chat';
export { default as GitInsight } from './GitInsight';
export { default as StarterList } from './StarterList';
export { default as ThoughtChain } from './ThoughtChain';
export { default as useUser } from './hooks/useUser';
export * from './utils';
15 changes: 15 additions & 0 deletions assistant/src/services/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import axios from 'axios';

const apiDomain = process.env.NEXT_PUBLIC_API_DOMAIN;

// Get the public bot profile by id
export async function getUserInfo(apiDomain: string, { clientId }: { clientId?: string }) {
const response = await axios.get(`${apiDomain}/api/auth/userinfo?clientId=${clientId}`, { withCredentials: true });
return response.data.data;
}


export async function requestLogout(apiDomain: string) {
const response = await axios.get(`${apiDomain}/api/auth/logout`, { withCredentials: true });
return response.data;
}
30 changes: 30 additions & 0 deletions assistant/src/utils/popcenter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const popupCenter = ({ url, title, w, h }: { url: string; title: string, w: number; h: number; }) => {
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;

const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

const systemZoom = width / window.screen.availWidth;

// 修正计算 left 和 top,使窗口能够居中
const left = (width - w / systemZoom) / 2 + dualScreenLeft;
const top = (height - h / systemZoom) / 2 + dualScreenTop;

const newWindow = window.open(
url,
title,
`
scrollbars=none,
width=${w / systemZoom},
height=${h / systemZoom},
top=${top},
left=${left}
`
);
if (newWindow && newWindow.focus) {
newWindow.focus();
}

return newWindow;
}
Loading

0 comments on commit a4e727e

Please sign in to comment.