feat: github login

This commit is contained in:
Tristan Yang
2022-10-30 22:12:25 +08:00
parent dec387ed5b
commit 4950a0663c
11 changed files with 149 additions and 75 deletions
+5 -5
View File
@@ -7,15 +7,15 @@ type Props = {
};
const Index: FC<Props> = ({ handleClose }) => {
const { name, logo } = useAppSelector(store => store.server);
const { name, description, logo } = useAppSelector(store => store.server);
return (
<div className="flex gap-4 justify-between items-center p-2">
<div className="relative w-10 h-10">
<div className="flex gap-2 justify-between items-center p-2">
<div className="relative w-12 h-12">
<img src={logo} alt="logo" className="w-full h-full" />
</div>
<div className="flex flex-col flex-1">
<span className="text-gray-900 text-lg">{name}</span>
{/* <span className="text-gray-400 text-sm">{online ? 'Active now' : 'Offline now'}</span> */}
<span className="text-gray-900 text-lg font-bold">{name}</span>
{description && <span className="text-gray-400 text-sm">{description}</span>}
</div>
<IconClose className="w-5 h-5 mr-2 cursor-pointer" onClick={handleClose} />
</div>
+2 -2
View File
@@ -20,9 +20,9 @@ const Login = () => {
} = loginConfig;
const googleLogin = enableGoogleLogin && clientId;
return (
<div className="w-60 flex flex-col">
<div className="w-60 flex flex-col py-2">
{googleLogin && <GoogleLoginButton clientId={clientId} />}
{enableGithubLogin && <GithubLoginButton client_id={githubAuthConfig?.client_id} />}
{enableGithubLogin && <GithubLoginButton client_id={githubAuthConfig?.client_id} source="widget" />}
</div>
);
};
+10 -10
View File
@@ -28,18 +28,18 @@ export type MessageProps = {
const Index: FC<MessageProps> = (props) => {
const { server: { name, logo }, loginUser } = useAppSelector(store => { return { server: store.server, loginUser: store.authData.user }; });
const { hostId, from_uid, content, created_at, compact, isFirst = false } = props;
const { hostId, from_uid, content, created_at = 0, compact, isFirst = false } = props;
const isHost = from_uid == hostId;
return (
<div
className={clsx(
'flex flex-col relative pl-14 py-1 hover:bg-gray-100 rounded-sm',
compact ? 'mt-0' : 'mt-4',
'flex flex-col relative pl-14 py-2 hover:bg-gray-100 rounded-sm',
compact ? 'py-1' : 'mt-4',
isFirst ? 'mt-0' : ''
)}
>
{!compact && (
<div className="absolute left-0 top-2 w-12 h-12 rounded-full overflow-hidden">
<div className="absolute left-1 top-2 w-12 h-12 rounded-full overflow-hidden">
{isHost ? (
<img src={logo} alt="logo" className="w-full h-full" />
) : (
@@ -48,19 +48,19 @@ const Index: FC<MessageProps> = (props) => {
</div>
)}
{!compact && (
<span className="flex items-center gap-2 leading-6">
<em className="text-black not-italic font-bold text-md">{isHost ? name : loginUser?.name}</em>
<Time time={created_at ?? 0} />
<span className="flex items-center gap-2 text-md">
<em className="text-black not-italic font-bold">{isHost ? name : loginUser?.name}</em>
<Time time={created_at} />
</span>
)}
<p
className={clsx(
'text-gray-600 text-md whitespace-normal break-words mt-2 w-[80%]',
compact ? 'group relative mt-0' : ''
'text-gray-600 text-md whitespace-normal break-words w-[80%]',
compact ? 'group relative ' : 'pt-1'
)}
>
{compact && (
<time className="absolute -left-2 top-0 -translate-x-full text-gray-300 text-xs invisible group-hover:visible">{`${new Date(created_at)
<time className="absolute -left-2 top-1/2 -translate-x-full -translate-y-1/2 text-gray-300 text-xs invisible group-hover:visible">{`${new Date(created_at)
.toLocaleTimeString('en-US', {
second: 'numeric',
minute: 'numeric',
+4 -4
View File
@@ -4,7 +4,7 @@ import { useAppSelector } from '../../app/store';
import Login from './Login';
const TextMessage = ({ text, animate = '' }: { text: string; animate?: string }) => (
<p className={`text-gray-600 text-md mb-3 ${animate}`}>{text}</p>
<p className={`text-gray-600 text-md mb-1 ${animate}`}>{text}</p>
);
type Props = {
needLogin?: boolean
@@ -12,20 +12,20 @@ type Props = {
const Index = ({ needLogin = false }: Props) => {
const { name, logo } = useAppSelector(store => store.server);
return (
<div className="flex gap-2">
<div className="flex gap-1 pl-1">
<div className="w-12 h-12">
<img src={logo} alt="logo" className="w-full h-full" />
</div>
<div className="flex flex-col">
<span className="flex items-center gap-2 leading-6">
<em className="text-black not-italic font-bold text-lg">{name}</em>
<em className="text-black not-italic text-lg font-bold">{name}</em>
<time className="text-gray-300 text-sm">{`${new Date().toLocaleTimeString('en-US', {
minute: 'numeric',
hour: 'numeric',
hour12: true,
})}`}</time>
</span>
<TextMessage text="👋 Hi there, Nice to meet you!" animate="animate-[fadeInUp_.5s_ease-in-out_both]" />
<TextMessage text="Hi there, Nice to meet you! 👋👋👋" animate={needLogin ? "animate-[fadeInUp_.5s_ease-in-out_both]" : ''} />
{needLogin && <>
<TextMessage text="You need login before we have a nice talk 👇" animate="animate-[fadeInUp_.5s_.8s_ease-in-out_both]" />
<div className="animate-[fadeInUp_.5s_1.2s_ease-in-out_both]">
+4 -3
View File
@@ -1,4 +1,4 @@
import { useState, useRef, ChangeEvent } from 'react';
import { useState, ChangeEvent } from 'react';
import Header from './Header';
import Welcome from './Welcome';
import MessageFeed from './MessageFeed';
@@ -33,7 +33,7 @@ const Index = ({ handleClose, hostId }: Props) => {
// no token or guest login
const notLogin = !token || isGuest;
return (
<aside className="flex flex-col justify-between bg-white w-full h-full rounded-md overflow-hidden">
<aside className="flex flex-col justify-between bg-white w-[600px] h-[800px] rounded-md overflow-hidden">
<Header handleClose={handleClose} />
<Line />
{/* message list */}
@@ -45,10 +45,11 @@ const Index = ({ handleClose, hostId }: Props) => {
{/* message input */}
<div className="w-full px-2 py-3">
<textarea
disabled={notLogin}
value={input}
onChange={handleInput}
className="w-full h-full text-sm p-2 rounded-lg bg-gray-200 resize-none text-black outline-none"
placeholder="Write a message..."
placeholder={notLogin ? "Login first..." : "Write a message..."}
rows={3}
/>
</div>
+5 -7
View File
@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState } from "react";
import { useGetServerQuery } from "../app/services/server";
import Icon from "./Icon";
@@ -10,18 +10,16 @@ type Props = {
function Widget({ hostId }: Props) {
const { rehydrated } = usePreload();
const [visible, setVisible] = useState(false);
const [visible, setVisible] = useState(!!new URLSearchParams(location.search).get("open"));
const { isLoading, isError } = useGetServerQuery();
const toggleVisible = () => {
setVisible((prev) => !prev);
};
useEffect(() => {
// 有无iframe内嵌
const parentWindow = window.parent;
if (parentWindow) {
parentWindow.postMessage(visible ? 'OPEN' : 'CLOSE', '*');
parentWindow.postMessage(visible ? 'CLOSE' : 'OPEN', '*');
}
}, [visible]);
setVisible((prev) => !prev);
};
if (isLoading || isError || !rehydrated) return null;
return visible ? <Popup handleClose={toggleVisible} hostId={hostId} /> : <Icon handleClick={toggleVisible} />;
}