Skip to content

Commit 2fa16b7

Browse files
committed
feat: merge redirect page into login page
1 parent 8c8c765 commit 2fa16b7

File tree

8 files changed

+98
-213
lines changed

8 files changed

+98
-213
lines changed

apps/renderer/src/lib/auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { IN_ELECTRON, WEB_URL } from "@follow/shared/constants"
22
import { signIn } from "@hono/auth-js/react"
33

4-
export const LOGIN_CALLBACK_URL = `${WEB_URL}/redirect?app=follow`
4+
export const LOGIN_CALLBACK_URL = `${WEB_URL}/login`
55
export type LoginRuntime = "browser" | "app"
66
export const loginHandler = (provider: string, runtime: LoginRuntime = "app") => {
77
if (IN_ELECTRON) {

apps/renderer/src/pages/(external)/login.tsx

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { Logo } from "@follow/components/icons/logo.jsx"
22
import { Button } from "@follow/components/ui/button/index.js"
3+
import { DEEPLINK_SCHEME } from "@follow/shared/constants"
34
import { SessionProvider, signIn, useSession } from "@hono/auth-js/react"
45
import { useEffect, useState } from "react"
56
import { useTranslation } from "react-i18next"
67
import { useLocation, useNavigate } from "react-router-dom"
78

89
import { useSignOut } from "~/hooks/biz/useSignOut"
10+
import { apiClient } from "~/lib/api-fetch"
911
import { LOGIN_CALLBACK_URL, loginHandler } from "~/lib/auth"
1012
import { UserAvatar } from "~/modules/user/UserAvatar"
1113

@@ -26,68 +28,76 @@ function Login() {
2628
const provider = urlParams.get("provider")
2729

2830
const isAuthenticated = status === "authenticated"
29-
const onOpenInWebApp = () => {
30-
if (isAuthenticated) {
31-
navigate("/")
32-
}
33-
}
3431

3532
const { t } = useTranslation("external")
3633

3734
useEffect(() => {
38-
if (!window.electron && provider) {
39-
if (status === "authenticated") {
40-
signOut()
41-
}
42-
if (status === "unauthenticated") {
43-
signIn(provider, {
44-
callbackUrl: LOGIN_CALLBACK_URL,
45-
})
46-
}
35+
if (!window.electron && provider && status === "unauthenticated") {
36+
signIn(provider, {
37+
callbackUrl: LOGIN_CALLBACK_URL,
38+
})
4739
setRedirecting(true)
4840
}
4941
}, [status])
5042

43+
const getCallbackUrl = async () => {
44+
const { data } = await apiClient["auth-app"]["new-session"].$post({})
45+
return {
46+
url: `${DEEPLINK_SCHEME}auth?token=${data.sessionToken}&userId=${data.userId}`,
47+
userId: data.userId,
48+
}
49+
}
50+
5151
return (
5252
<div className="flex h-screen w-full flex-col items-center justify-center gap-10">
5353
<Logo className="size-20" />
54-
{!isAuthenticated ? (
54+
{!isAuthenticated && (
5555
<h1 className="text-3xl font-bold">
5656
{t("login.logInTo")}
5757
{` ${APP_NAME}`}
5858
</h1>
59-
) : (
60-
<h1 className="-mb-6 text-3xl font-bold">
61-
{t("login.welcomeTo")}
62-
{` ${APP_NAME}`}
63-
</h1>
6459
)}
6560
{redirecting ? (
6661
<div>{t("login.redirecting")}</div>
6762
) : (
6863
<div className="flex flex-col gap-3">
6964
{isAuthenticated ? (
70-
<>
71-
<div className="center flex">
72-
<UserAvatar className="gap-8 px-10 py-4 text-2xl" />
73-
<Button variant="ghost" onClick={signOut}>
74-
<i className="i-mingcute-exit-line" />
75-
</Button>
65+
<div className="flex w-full flex-col items-center justify-center gap-10 px-4">
66+
<div className="relative flex items-center justify-center">
67+
<UserAvatar className="gap-4 px-10 py-4 text-2xl" />
68+
<div className="absolute right-0">
69+
<Button variant="ghost" onClick={signOut}>
70+
<i className="i-mingcute-exit-line text-xl" />
71+
</Button>
72+
</div>
7673
</div>
77-
<div className="flex items-center justify-center gap-4">
78-
<Button variant="outline" onClick={onOpenInWebApp}>
79-
{t("login.backToWebApp")}
80-
</Button>
74+
<h2 className="text-center">
75+
{t("redirect.successMessage", { app_name: APP_NAME })} <br />
76+
<br />
77+
{t("redirect.instruction", { app_name: APP_NAME })}
78+
</h2>
79+
<div className="center flex flex-col gap-20 sm:flex-row">
8180
<Button
82-
variant="primary"
81+
variant="text"
82+
className="h-14 text-base"
8383
onClick={() => {
84-
navigate("/redirect?app=follow")
84+
navigate("/")
85+
}}
86+
>
87+
{t("redirect.continueInBrowser")}
88+
</Button>
89+
90+
<Button
91+
className="h-14 !rounded-full px-5 text-lg"
92+
onClick={async () => {
93+
const { url } = await getCallbackUrl()
94+
window.open(url, "_top")
8595
}}
8696
>
87-
{t("login.openApp")}
97+
{t("redirect.openApp", { app_name: APP_NAME })}
8898
</Button>
8999
</div>
90-
</>
100+
</div>
91101
) : (
92102
<>
93103
<Button

apps/renderer/src/pages/(external)/redirect.tsx

Lines changed: 0 additions & 72 deletions
This file was deleted.

apps/server/client/components/ui/user-avatar.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useWhoami } from "@client/atoms/user"
22
import { Avatar, AvatarFallback, AvatarImage } from "@follow/components/ui/avatar/index.jsx"
33
import { getBackgroundGradient } from "@follow/utils/color"
4+
import { cn } from "@follow/utils/utils"
45
import { useMemo } from "react"
56

6-
export const UserAvatar = () => {
7+
export const UserAvatar = ({ className }: { className?: string }) => {
78
let user = useWhoami()
89

910
const colors = useMemo(
@@ -31,7 +32,12 @@ export const UserAvatar = () => {
3132
const { name, image } = user
3233

3334
return (
34-
<div className="flex h-20 items-center justify-center gap-8 px-10 py-4 text-2xl font-medium text-zinc-600 dark:text-zinc-300">
35+
<div
36+
className={cn(
37+
"flex h-20 items-center justify-center gap-8 px-10 py-4 text-2xl font-medium text-zinc-600 dark:text-zinc-300",
38+
className,
39+
)}
40+
>
3541
<Avatar className="border">
3642
<AvatarImage
3743
className="aspect-square size-full duration-200 animate-in fade-in-0"

apps/server/client/lib/auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { IN_ELECTRON, WEB_URL } from "@follow/shared/constants"
22
import { signIn } from "@hono/auth-js/react"
33

4-
export const LOGIN_CALLBACK_URL = `${WEB_URL}/redirect?app=follow`
4+
export const LOGIN_CALLBACK_URL = `${WEB_URL}/login`
55
export type LoginRuntime = "browser" | "app"
66
export const loginHandler = (provider: string, runtime: LoginRuntime = "app") => {
77
if (IN_ELECTRON) {

apps/server/client/pages/(login)/login.tsx

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { UserAvatar } from "@client/components/ui/user-avatar"
2+
import { apiClient } from "@client/lib/api-fetch"
23
import { LOGIN_CALLBACK_URL, loginHandler } from "@client/lib/auth"
34
import { Logo } from "@follow/components/icons/logo.jsx"
45
import { Button } from "@follow/components/ui/button/index.js"
6+
import { DEEPLINK_SCHEME } from "@follow/shared/constants"
57
import { SessionProvider, signIn, signOut, useSession } from "@hono/auth-js/react"
68
import { useEffect, useState } from "react"
79
import { useTranslation } from "react-i18next"
@@ -25,68 +27,76 @@ function Login() {
2527
const provider = urlParams.get("provider")
2628

2729
const isAuthenticated = status === "authenticated"
28-
const onOpenInWebApp = () => {
29-
if (isAuthenticated) {
30-
window.location.href = "/"
31-
}
32-
}
3330

3431
const { t } = useTranslation("external")
3532

3633
useEffect(() => {
37-
if (provider) {
38-
if (status === "authenticated") {
39-
signOut()
40-
}
41-
if (status === "unauthenticated") {
42-
signIn(provider, {
43-
callbackUrl: LOGIN_CALLBACK_URL,
44-
})
45-
}
34+
if (provider && status === "unauthenticated") {
35+
signIn(provider, {
36+
callbackUrl: LOGIN_CALLBACK_URL,
37+
})
4638
setRedirecting(true)
4739
}
4840
}, [status])
4941

42+
const getCallbackUrl = async () => {
43+
const { data } = await apiClient["auth-app"]["new-session"].$post({})
44+
return {
45+
url: `${DEEPLINK_SCHEME}auth?token=${data.sessionToken}&userId=${data.userId}`,
46+
userId: data.userId,
47+
}
48+
}
49+
5050
return (
5151
<div className="flex h-screen w-full flex-col items-center justify-center gap-10">
5252
<Logo className="size-20" />
53-
{!isAuthenticated ? (
53+
{!isAuthenticated && (
5454
<h1 className="text-3xl font-bold">
5555
{t("login.logInTo")}
5656
{` ${APP_NAME}`}
5757
</h1>
58-
) : (
59-
<h1 className="-mb-6 text-3xl font-bold">
60-
{t("login.welcomeTo")}
61-
{` ${APP_NAME}`}
62-
</h1>
6358
)}
6459
{redirecting ? (
6560
<div>{t("login.redirecting")}</div>
6661
) : (
6762
<div className="flex flex-col gap-3">
6863
{isAuthenticated ? (
69-
<>
70-
<div className="center flex">
71-
<UserAvatar />
72-
<Button variant="ghost" onClick={() => signOut()}>
73-
<i className="i-mingcute-exit-line" />
74-
</Button>
64+
<div className="flex w-full flex-col items-center justify-center gap-10 px-4">
65+
<div className="relative flex items-center justify-center">
66+
<UserAvatar className="gap-4 px-10 py-4 text-2xl" />
67+
<div className="absolute right-0">
68+
<Button variant="ghost" onClick={() => signOut()}>
69+
<i className="i-mingcute-exit-line text-xl" />
70+
</Button>
71+
</div>
7572
</div>
76-
<div className="flex items-center justify-center gap-4">
77-
<Button variant="outline" onClick={onOpenInWebApp}>
78-
{t("login.backToWebApp")}
79-
</Button>
73+
<h2 className="text-center">
74+
{t("redirect.successMessage", { app_name: APP_NAME })} <br />
75+
<br />
76+
{t("redirect.instruction", { app_name: APP_NAME })}
77+
</h2>
78+
<div className="center flex flex-col gap-20 sm:flex-row">
8079
<Button
81-
variant="primary"
80+
variant="text"
81+
className="h-14 text-base"
8282
onClick={() => {
83-
navigate("/redirect?app=follow")
83+
navigate("/")
84+
}}
85+
>
86+
{t("redirect.continueInBrowser")}
87+
</Button>
88+
89+
<Button
90+
className="h-14 !rounded-full px-5 text-lg"
91+
onClick={async () => {
92+
const { url } = await getCallbackUrl()
93+
window.open(url, "_top")
8494
}}
8595
>
86-
{t("login.openApp")}
96+
{t("redirect.openApp", { app_name: APP_NAME })}
8797
</Button>
8898
</div>
89-
</>
99+
</div>
90100
) : (
91101
<>
92102
<Button

0 commit comments

Comments
 (0)