From a54d31d1376bda18e5d44e8b6f4cf0b194dd7d95 Mon Sep 17 00:00:00 2001 From: arvinxx Date: Tue, 26 Jan 2021 21:47:10 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20feat(search-bar):=20=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E5=AE=8C=E6=88=90=E6=90=9C=E7=B4=A2=E6=A1=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/background/index.ts | 14 +++-- src/contentScripts/searchBar/app/index.tsx | 60 ++++++++++++++++--- src/contentScripts/searchBar/app/style.less | 19 +++--- .../app/useCheckTokenValidService.ts | 26 ++++++++ src/pages/options/Token/index.tsx | 36 ++++++++--- src/pages/options/index.tsx | 8 +-- src/services/useYuqueTokenService.ts | 38 ++++++++++-- src/utils/request.ts | 2 +- 8 files changed, 167 insertions(+), 36 deletions(-) create mode 100644 src/contentScripts/searchBar/app/useCheckTokenValidService.ts diff --git a/src/background/index.ts b/src/background/index.ts index 99a695f..a109e52 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -1,9 +1,15 @@ console.log('This is background page!'); -chrome.browserAction.onClicked.addListener((tab) => { - console.log(tab); - console.log('123'); +chrome.browserAction.onClicked.addListener(() => { chrome.tabs.create({ url: 'https://yuque.com' }); }); -export default null; +chrome.runtime.onMessage.addListener((message) => { + switch (message.action) { + case 'openOptionsPage': + chrome.runtime.openOptionsPage(); + break; + default: + break; + } +}); diff --git a/src/contentScripts/searchBar/app/index.tsx b/src/contentScripts/searchBar/app/index.tsx index 9d3cab9..d6d5f33 100644 --- a/src/contentScripts/searchBar/app/index.tsx +++ b/src/contentScripts/searchBar/app/index.tsx @@ -1,9 +1,11 @@ import type { FC } from 'react'; import React, { useContext } from 'react'; import { useYuqueTokenService, YuqueTokenService } from '@/services'; +import { Button, Space } from 'antd'; import useSearchBarService, { SearchBarService } from './useSearchBarService'; import { SearchService, useSearchService } from './useSearchService'; +import { useCheckTokenValidService } from './useCheckTokenValidService'; import SearchInput from './SearchInput'; import SearchResult from './SearchResult'; @@ -14,17 +16,59 @@ import styles from './style.less'; const SearchBar: FC = () => { const { visible, searchBarRef } = useContext(SearchBarService); + const valid = useCheckTokenValidService(); + return visible ? (
-
- -
-
- - - -
+ {valid ? ( + <> +
+ +
+
+ + + +
+ + ) : ( + +
+ 无效的 token +
+
+

Token 无效

+
+
+ 没有配置 token 或 token 无效,请前往配置页添加 token。 + 添加完成后请刷新页面并重试。 +
+ + + + +
+ )}
) : null; diff --git a/src/contentScripts/searchBar/app/style.less b/src/contentScripts/searchBar/app/style.less index 93190dc..882de8d 100644 --- a/src/contentScripts/searchBar/app/style.less +++ b/src/contentScripts/searchBar/app/style.less @@ -2,8 +2,8 @@ .container { position: fixed; - left: 0; top: 0; + left: 0; z-index: 999999; width: 100%; height: 100vh; @@ -11,26 +11,31 @@ } .bar { position: fixed; - top: 50%; left: 50%; - transform: translate(-50%, -50%); - width: 600px; + transform: translate(-50%, -50%); } .input { .search-bar-shadow; - border-radius: 4px; + background: @background-color-base; + border-radius: 4px; } - .result { margin-top: 8px; + overflow: hidden; border-radius: 4px; .search-bar-shadow; - overflow: hidden; } +.invalid { + width: 500px; + padding: 24px; + background: @white; + border-radius: 4px; + .flex-center-children; +} [theme='light'] { .result { background: white; diff --git a/src/contentScripts/searchBar/app/useCheckTokenValidService.ts b/src/contentScripts/searchBar/app/useCheckTokenValidService.ts new file mode 100644 index 0000000..50272dc --- /dev/null +++ b/src/contentScripts/searchBar/app/useCheckTokenValidService.ts @@ -0,0 +1,26 @@ +import { useContext, useEffect } from 'react'; + +import { SearchBarService } from './useSearchBarService'; +import { YuqueTokenService } from '@/services'; + +/** + * SearchInput 需要的状态 + */ +export const useCheckTokenValidService = () => { + const { visible } = useContext(SearchBarService); + + const { checkTokenValid, valid } = useContext(YuqueTokenService); + + useEffect(() => { + // 可见且 token 无效时 检查 token + if (visible && !valid) { + checkTokenValid(); + } + }, [visible, checkTokenValid]); + + useEffect(() => { + checkTokenValid(); + }, []); + + return valid; +}; diff --git a/src/pages/options/Token/index.tsx b/src/pages/options/Token/index.tsx index 3484af7..d4308a2 100644 --- a/src/pages/options/Token/index.tsx +++ b/src/pages/options/Token/index.tsx @@ -1,14 +1,18 @@ import React, { useContext } from 'react'; -import { Button, Input, Space } from 'antd'; +import { Button, Input, message, Space } from 'antd'; import { YuqueTokenService } from '@/services'; import styles from './style.less'; const Token = () => { - const { setYuqueToken, token, syncToCloudStorage } = useContext( - YuqueTokenService, - ); + const { + setYuqueToken, + token, + syncToCloudStorage, + checkTokenValid, + valid, + } = useContext(YuqueTokenService); return (
@@ -22,9 +26,27 @@ const Token = () => { }} onPressEnter={syncToCloudStorage} /> - + + + +
); diff --git a/src/pages/options/index.tsx b/src/pages/options/index.tsx index 9fa8652..d328126 100644 --- a/src/pages/options/index.tsx +++ b/src/pages/options/index.tsx @@ -28,17 +28,17 @@ const App = () => { 语雀 Token - + 排版配置 - + 深色模式 - - 搜索框 + + 高级搜索框 diff --git a/src/services/useYuqueTokenService.ts b/src/services/useYuqueTokenService.ts index f54d140..e10f85f 100644 --- a/src/services/useYuqueTokenService.ts +++ b/src/services/useYuqueTokenService.ts @@ -1,14 +1,16 @@ import { useLocalStorageState } from 'ahooks'; -import { getServiceToken } from '@/utils'; -import { useCallback, useEffect } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { message } from 'antd'; +import request from 'umi-request'; + +import { getServiceToken } from '@/utils'; /** * Yuque Token */ export const useYuqueTokenService = () => { // SearchBar 可见 - const [token, setYuqueToken] = useLocalStorageState('yuque_token', ''); + const [token, setYuqueToken] = useLocalStorageState('PY_YUQUE_TOKEN', ''); const syncToCloudStorage = useCallback(() => { chrome.storage?.sync.set({ yuque_token: token }, () => { @@ -17,16 +19,42 @@ export const useYuqueTokenService = () => { message.success('保存成功'); }, [token]); + const [valid, setValid] = useState(false); + + /** + * 验证 token 是否有效 + */ + const checkTokenValid = useCallback(async () => { + // 如果验证过有效,就不验证了 + if (valid) return; + + try { + const data = await request.get('https://www.yuque.com/api/v2/hello', { + headers: { + 'X-Auth-Token': token || '', + 'Access-Control-Allow-Origin': '*', + }, + getResponse: true, + }); + console.log(data); + setValid(true); + return true; + } catch (e) { + setValid(false); + return false; + } + }, [token, valid]); + + // 初始化时做一次检查 useEffect(() => { chrome.storage?.sync.get((data) => { - console.log(data); if (data.yuque_token !== token) { setYuqueToken(data.yuque_token); } }); }, []); - return { token, setYuqueToken, syncToCloudStorage }; + return { token, setYuqueToken, syncToCloudStorage, valid, checkTokenValid }; }; // 这个服务将被注册至全局 diff --git a/src/utils/request.ts b/src/utils/request.ts index 1e97824..1422361 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -60,6 +60,6 @@ export const request = extend({ credentials: 'include', // 默认请求是否带上cookie headers: { 'X-Auth-Token': - localStorage.getItem('yuque_token')?.replace(/"/g, '') || '', + localStorage.getItem('PY_YUQUE_TOKEN')?.replace(/"/g, '') || '', }, });