mirror of
https://github.com/ourongxing/newsnow.git
synced 2025-01-18 18:59:15 +08:00
feat: refactor login
This commit is contained in:
parent
75ab32d250
commit
773ab138ca
8
server/api/enable-login.ts
Normal file
8
server/api/enable-login.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import process from "node:process"
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
return {
|
||||
enable: true,
|
||||
url: `https://github.com/login/oauth/authorize?client_id=${process.env.G_CLIENT_ID}`,
|
||||
}
|
||||
})
|
@ -53,10 +53,10 @@ function NewsCard({ id, handleListeners }: NewsCardProps) {
|
||||
queryKey: [id, getRefreshId(id)],
|
||||
queryFn: async ({ queryKey }) => {
|
||||
const [_id, _refetchTime] = queryKey as [SourceID, number]
|
||||
let url = `/api/s?id=${_id}`
|
||||
let url = `/s?id=${_id}`
|
||||
const headers: Record<string, any> = {}
|
||||
if (Date.now() - _refetchTime < 1000) {
|
||||
url = `/api/s?id=${_id}&latest`
|
||||
url = `/s?id=${_id}&latest`
|
||||
const jwt = safeParseString(localStorage.getItem("jwt"))
|
||||
if (jwt) headers.Authorization = `Bearer ${jwt}`
|
||||
} else if (cache.has(_id)) {
|
||||
|
@ -25,10 +25,11 @@ import { currentSourcesAtom } from "~/atoms"
|
||||
export function Dnd() {
|
||||
const [items, setItems] = useAtom(currentSourcesAtom)
|
||||
useQuery({
|
||||
queryKey: ["entries", items.sort()],
|
||||
// sort in place
|
||||
queryKey: ["entries", [...items].sort()],
|
||||
queryFn: async ({ queryKey }) => {
|
||||
const sources = queryKey[1]
|
||||
const res: EntriesSourceResponse = await myFetch("/api/s/entries", {
|
||||
const res: EntriesSourceResponse = await myFetch("/s/entries", {
|
||||
method: "POST",
|
||||
body: {
|
||||
sources,
|
||||
|
@ -14,7 +14,7 @@ function ThemeToggle() {
|
||||
}
|
||||
|
||||
export function Menu() {
|
||||
const { loggedIn, login, logout, userInfo } = useLogin()
|
||||
const { loggedIn, login, logout, userInfo, enableLogin } = useLogin()
|
||||
const [shown, show] = useState(false)
|
||||
const ref = useRef<HTMLElement>(null)
|
||||
const isHover = useHoverDirty(ref)
|
||||
@ -25,7 +25,7 @@ export function Menu() {
|
||||
<span ref={ref} className="relative">
|
||||
<span className="flex items-center scale-90">
|
||||
{
|
||||
loggedIn && userInfo.avatar
|
||||
enableLogin && loggedIn && userInfo.avatar
|
||||
? (
|
||||
<button
|
||||
type="button"
|
||||
@ -57,7 +57,7 @@ export function Menu() {
|
||||
}}
|
||||
>
|
||||
<ol className="bg-base bg-op-70! backdrop-blur-md p-2 rounded-lg color-base text-base">
|
||||
{loggedIn
|
||||
{enableLogin && (loggedIn
|
||||
? (
|
||||
<li onClick={logout}>
|
||||
<span className="i-ph:sign-out-duotone inline-block" />
|
||||
@ -69,7 +69,7 @@ export function Menu() {
|
||||
<span className="i-ph:sign-in-duotone inline-block" />
|
||||
<span>Github 账号登录</span>
|
||||
</li>
|
||||
)}
|
||||
))}
|
||||
<ThemeToggle />
|
||||
<li onClick={() => window.open(Homepage)}>
|
||||
<span className="i-ph:github-logo-duotone inline-block" />
|
||||
|
@ -5,12 +5,32 @@ const userAtom = atomWithStorage<{
|
||||
|
||||
const jwtAtom = atomWithStorage("jwt", "")
|
||||
|
||||
const enableLoginAtom = atomWithStorage<{
|
||||
enable: boolean
|
||||
url?: string
|
||||
}>("login", {
|
||||
enable: true,
|
||||
})
|
||||
|
||||
enableLoginAtom.onMount = (set) => {
|
||||
myFetch("/enable-login").then((r) => {
|
||||
set(r)
|
||||
}).catch((e) => {
|
||||
if (e.statusCode === 506) {
|
||||
set({ enable: false })
|
||||
console.log("clear")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function useLogin() {
|
||||
const userInfo = useAtomValue(userAtom)
|
||||
const jwt = useAtomValue(jwtAtom)
|
||||
const enableLogin = useAtomValue(enableLoginAtom)
|
||||
|
||||
const login = useCallback(() => {
|
||||
window.location.href = __LOGIN_URL__
|
||||
}, [])
|
||||
window.location.href = enableLogin.url || "/api/login"
|
||||
}, [enableLogin])
|
||||
|
||||
const logout = useCallback(() => {
|
||||
window.localStorage.clear()
|
||||
@ -20,6 +40,7 @@ export function useLogin() {
|
||||
return {
|
||||
loggedIn: !!jwt,
|
||||
userInfo,
|
||||
enableLogin: !!enableLogin.enable,
|
||||
logout,
|
||||
login,
|
||||
}
|
||||
|
@ -16,14 +16,26 @@ function initRefetchSources() {
|
||||
const refetchSourcesAtom = atom(initRefetchSources())
|
||||
export function useRefetch() {
|
||||
const [refetchSource, setRefetchSource] = useAtom(refetchSourcesAtom)
|
||||
const { enableLogin, loggedIn, login } = useLogin()
|
||||
const toaster = useToast()
|
||||
|
||||
const refresh = useCallback((...sources: SourceID[]) => {
|
||||
const obj = Object.fromEntries(sources.map(id => [id, Date.now()]))
|
||||
setRefetchSource(prev => ({
|
||||
...prev,
|
||||
...obj,
|
||||
}))
|
||||
}, [setRefetchSource])
|
||||
if (loggedIn) {
|
||||
const obj = Object.fromEntries(sources.map(id => [id, Date.now()]))
|
||||
setRefetchSource(prev => ({
|
||||
...prev,
|
||||
...obj,
|
||||
}))
|
||||
} else if (enableLogin) {
|
||||
toaster("登录后可以强制拉取最新数据", {
|
||||
type: "warning",
|
||||
action: {
|
||||
label: "登录",
|
||||
onClick: login,
|
||||
},
|
||||
})
|
||||
}
|
||||
}, [setRefetchSource, loggedIn, toaster, login, enableLogin])
|
||||
|
||||
const getRefreshId = useCallback((id: SourceID) => refetchSource[id], [refetchSource])
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { safeParseString } from "~/utils"
|
||||
async function uploadMetadata(metadata: PrimitiveMetadata) {
|
||||
const jwt = safeParseString(localStorage.getItem("jwt"))
|
||||
if (!jwt) return
|
||||
await myFetch("/api/me/sync", {
|
||||
await myFetch("/me/sync", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
@ -22,7 +22,7 @@ async function uploadMetadata(metadata: PrimitiveMetadata) {
|
||||
async function downloadMetadata(): Promise<PrimitiveMetadata | undefined> {
|
||||
const jwt = safeParseString(localStorage.getItem("jwt"))
|
||||
if (!jwt) return
|
||||
const { data, updatedTime } = await myFetch("/api/me/sync", {
|
||||
const { data, updatedTime } = await myFetch("/me/sync", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
|
@ -10,8 +10,6 @@ const router = createRouter({
|
||||
context: {
|
||||
queryClient,
|
||||
},
|
||||
defaultPreload: "intent",
|
||||
defaultPreloadStaleTime: 0,
|
||||
})
|
||||
|
||||
const rootElement = document.getElementById("app")!
|
||||
|
@ -15,14 +15,6 @@ export const Route = createRootRouteWithContext<{
|
||||
}>()({
|
||||
component: RootComponent,
|
||||
notFoundComponent: NotFoundComponent,
|
||||
beforeLoad: () => {
|
||||
const query = new URLSearchParams(window.location.search)
|
||||
if (query.has("login") && query.has("user") && query.has("jwt")) {
|
||||
localStorage.setItem("user", query.get("user")!)
|
||||
localStorage.setItem("jwt", JSON.stringify(query.get("jwt")!))
|
||||
window.history.replaceState({}, document.title, window.location.pathname)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
function NotFoundComponent() {
|
||||
|
@ -40,4 +40,5 @@ export class Timer {
|
||||
export const myFetch = $fetch.create({
|
||||
timeout: 15000,
|
||||
retry: 0,
|
||||
baseURL: "/api",
|
||||
})
|
||||
|
1
src/vite-env.d.ts
vendored
1
src/vite-env.d.ts
vendored
@ -2,4 +2,3 @@
|
||||
/// <reference types="vite-plugin-pwa/react" />
|
||||
/// <reference types="vite-plugin-pwa/info" />
|
||||
/// <reference lib="webworker" />
|
||||
declare const __LOGIN_URL__: string
|
||||
|
@ -1,4 +1,3 @@
|
||||
import process from "node:process"
|
||||
import { join } from "node:path"
|
||||
import { defineConfig } from "vite"
|
||||
import react from "@vitejs/plugin-react-swc"
|
||||
@ -15,13 +14,6 @@ dotenv.config({
|
||||
})
|
||||
|
||||
export default defineConfig({
|
||||
define: {
|
||||
__LOGIN_URL__: process.env.G_CLIENT_ID ? `"https://github.com/login/oauth/authorize?client_id=${process.env.G_CLIENT_ID}"` : `"/api/login"`,
|
||||
},
|
||||
build: {
|
||||
sourcemap: true,
|
||||
minify: false,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"~": join(projectDir, "src"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user