Skip to content

Commit

Permalink
feat: merge redirect page into login page
Browse files Browse the repository at this point in the history
  • Loading branch information
DIYgod committed Nov 9, 2024
1 parent 8c8c765 commit 2fa16b7
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 213 deletions.
2 changes: 1 addition & 1 deletion apps/renderer/src/lib/auth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IN_ELECTRON, WEB_URL } from "@follow/shared/constants"
import { signIn } from "@hono/auth-js/react"

export const LOGIN_CALLBACK_URL = `${WEB_URL}/redirect?app=follow`
export const LOGIN_CALLBACK_URL = `${WEB_URL}/login`
export type LoginRuntime = "browser" | "app"
export const loginHandler = (provider: string, runtime: LoginRuntime = "app") => {
if (IN_ELECTRON) {
Expand Down
78 changes: 44 additions & 34 deletions apps/renderer/src/pages/(external)/login.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Logo } from "@follow/components/icons/logo.jsx"
import { Button } from "@follow/components/ui/button/index.js"
import { DEEPLINK_SCHEME } from "@follow/shared/constants"
import { SessionProvider, signIn, useSession } from "@hono/auth-js/react"
import { useEffect, useState } from "react"
import { useTranslation } from "react-i18next"
import { useLocation, useNavigate } from "react-router-dom"

import { useSignOut } from "~/hooks/biz/useSignOut"
import { apiClient } from "~/lib/api-fetch"
import { LOGIN_CALLBACK_URL, loginHandler } from "~/lib/auth"
import { UserAvatar } from "~/modules/user/UserAvatar"

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

const isAuthenticated = status === "authenticated"
const onOpenInWebApp = () => {
if (isAuthenticated) {
navigate("/")
}
}

const { t } = useTranslation("external")

useEffect(() => {
if (!window.electron && provider) {
if (status === "authenticated") {
signOut()
}
if (status === "unauthenticated") {
signIn(provider, {
callbackUrl: LOGIN_CALLBACK_URL,
})
}
if (!window.electron && provider && status === "unauthenticated") {
signIn(provider, {
callbackUrl: LOGIN_CALLBACK_URL,
})
setRedirecting(true)
}
}, [status])

const getCallbackUrl = async () => {
const { data } = await apiClient["auth-app"]["new-session"].$post({})
return {
url: `${DEEPLINK_SCHEME}auth?token=${data.sessionToken}&userId=${data.userId}`,
userId: data.userId,
}
}

return (
<div className="flex h-screen w-full flex-col items-center justify-center gap-10">
<Logo className="size-20" />
{!isAuthenticated ? (
{!isAuthenticated && (
<h1 className="text-3xl font-bold">
{t("login.logInTo")}
{` ${APP_NAME}`}
</h1>
) : (
<h1 className="-mb-6 text-3xl font-bold">
{t("login.welcomeTo")}
{` ${APP_NAME}`}
</h1>
)}
{redirecting ? (
<div>{t("login.redirecting")}</div>
) : (
<div className="flex flex-col gap-3">
{isAuthenticated ? (
<>
<div className="center flex">
<UserAvatar className="gap-8 px-10 py-4 text-2xl" />
<Button variant="ghost" onClick={signOut}>
<i className="i-mingcute-exit-line" />
</Button>
<div className="flex w-full flex-col items-center justify-center gap-10 px-4">
<div className="relative flex items-center justify-center">
<UserAvatar className="gap-4 px-10 py-4 text-2xl" />
<div className="absolute right-0">
<Button variant="ghost" onClick={signOut}>
<i className="i-mingcute-exit-line text-xl" />
</Button>
</div>
</div>
<div className="flex items-center justify-center gap-4">
<Button variant="outline" onClick={onOpenInWebApp}>
{t("login.backToWebApp")}
</Button>
<h2 className="text-center">
{t("redirect.successMessage", { app_name: APP_NAME })} <br />
<br />
{t("redirect.instruction", { app_name: APP_NAME })}
</h2>
<div className="center flex flex-col gap-20 sm:flex-row">
<Button
variant="primary"
variant="text"
className="h-14 text-base"
onClick={() => {
navigate("/redirect?app=follow")
navigate("/")
}}
>
{t("redirect.continueInBrowser")}
</Button>

<Button
className="h-14 !rounded-full px-5 text-lg"
onClick={async () => {
const { url } = await getCallbackUrl()
window.open(url, "_top")
}}
>
{t("login.openApp")}
{t("redirect.openApp", { app_name: APP_NAME })}
</Button>
</div>
</>
</div>
) : (
<>
<Button
Expand Down
72 changes: 0 additions & 72 deletions apps/renderer/src/pages/(external)/redirect.tsx

This file was deleted.

10 changes: 8 additions & 2 deletions apps/server/client/components/ui/user-avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useWhoami } from "@client/atoms/user"
import { Avatar, AvatarFallback, AvatarImage } from "@follow/components/ui/avatar/index.jsx"
import { getBackgroundGradient } from "@follow/utils/color"
import { cn } from "@follow/utils/utils"
import { useMemo } from "react"

export const UserAvatar = () => {
export const UserAvatar = ({ className }: { className?: string }) => {
let user = useWhoami()

const colors = useMemo(
Expand Down Expand Up @@ -31,7 +32,12 @@ export const UserAvatar = () => {
const { name, image } = user

return (
<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">
<div
className={cn(
"flex h-20 items-center justify-center gap-8 px-10 py-4 text-2xl font-medium text-zinc-600 dark:text-zinc-300",
className,
)}
>
<Avatar className="border">
<AvatarImage
className="aspect-square size-full duration-200 animate-in fade-in-0"
Expand Down
2 changes: 1 addition & 1 deletion apps/server/client/lib/auth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IN_ELECTRON, WEB_URL } from "@follow/shared/constants"
import { signIn } from "@hono/auth-js/react"

export const LOGIN_CALLBACK_URL = `${WEB_URL}/redirect?app=follow`
export const LOGIN_CALLBACK_URL = `${WEB_URL}/login`
export type LoginRuntime = "browser" | "app"
export const loginHandler = (provider: string, runtime: LoginRuntime = "app") => {
if (IN_ELECTRON) {
Expand Down
78 changes: 44 additions & 34 deletions apps/server/client/pages/(login)/login.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { UserAvatar } from "@client/components/ui/user-avatar"
import { apiClient } from "@client/lib/api-fetch"
import { LOGIN_CALLBACK_URL, loginHandler } from "@client/lib/auth"
import { Logo } from "@follow/components/icons/logo.jsx"
import { Button } from "@follow/components/ui/button/index.js"
import { DEEPLINK_SCHEME } from "@follow/shared/constants"
import { SessionProvider, signIn, signOut, useSession } from "@hono/auth-js/react"
import { useEffect, useState } from "react"
import { useTranslation } from "react-i18next"
Expand All @@ -25,68 +27,76 @@ function Login() {
const provider = urlParams.get("provider")

const isAuthenticated = status === "authenticated"
const onOpenInWebApp = () => {
if (isAuthenticated) {
window.location.href = "/"
}
}

const { t } = useTranslation("external")

useEffect(() => {
if (provider) {
if (status === "authenticated") {
signOut()
}
if (status === "unauthenticated") {
signIn(provider, {
callbackUrl: LOGIN_CALLBACK_URL,
})
}
if (provider && status === "unauthenticated") {
signIn(provider, {
callbackUrl: LOGIN_CALLBACK_URL,
})
setRedirecting(true)
}
}, [status])

const getCallbackUrl = async () => {
const { data } = await apiClient["auth-app"]["new-session"].$post({})
return {
url: `${DEEPLINK_SCHEME}auth?token=${data.sessionToken}&userId=${data.userId}`,
userId: data.userId,
}
}

return (
<div className="flex h-screen w-full flex-col items-center justify-center gap-10">
<Logo className="size-20" />
{!isAuthenticated ? (
{!isAuthenticated && (
<h1 className="text-3xl font-bold">
{t("login.logInTo")}
{` ${APP_NAME}`}
</h1>
) : (
<h1 className="-mb-6 text-3xl font-bold">
{t("login.welcomeTo")}
{` ${APP_NAME}`}
</h1>
)}
{redirecting ? (
<div>{t("login.redirecting")}</div>
) : (
<div className="flex flex-col gap-3">
{isAuthenticated ? (
<>
<div className="center flex">
<UserAvatar />
<Button variant="ghost" onClick={() => signOut()}>
<i className="i-mingcute-exit-line" />
</Button>
<div className="flex w-full flex-col items-center justify-center gap-10 px-4">
<div className="relative flex items-center justify-center">
<UserAvatar className="gap-4 px-10 py-4 text-2xl" />
<div className="absolute right-0">
<Button variant="ghost" onClick={() => signOut()}>
<i className="i-mingcute-exit-line text-xl" />
</Button>
</div>
</div>
<div className="flex items-center justify-center gap-4">
<Button variant="outline" onClick={onOpenInWebApp}>
{t("login.backToWebApp")}
</Button>
<h2 className="text-center">
{t("redirect.successMessage", { app_name: APP_NAME })} <br />
<br />
{t("redirect.instruction", { app_name: APP_NAME })}
</h2>
<div className="center flex flex-col gap-20 sm:flex-row">
<Button
variant="primary"
variant="text"
className="h-14 text-base"
onClick={() => {
navigate("/redirect?app=follow")
navigate("/")
}}
>
{t("redirect.continueInBrowser")}
</Button>

<Button
className="h-14 !rounded-full px-5 text-lg"
onClick={async () => {
const { url } = await getCallbackUrl()
window.open(url, "_top")
}}
>
{t("login.openApp")}
{t("redirect.openApp", { app_name: APP_NAME })}
</Button>
</div>
</>
</div>
) : (
<>
<Button
Expand Down
Loading

0 comments on commit 2fa16b7

Please sign in to comment.