mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 06:30:10 +08:00
feat(minapp): add Google login tip for untrusted browser issue (#8230)
* feat(minapp): add Google login tip for untrusted browser issue * feat(miniapp): add open Google button for Google Login popup * feat(minapp): replace custom alert with Ant Design Alert component
This commit is contained in:
parent
4a4d861592
commit
ee32942f71
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -10,7 +10,7 @@
|
||||
"windows": {
|
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd"
|
||||
},
|
||||
"runtimeArgs": ["--sourcemap"],
|
||||
"runtimeArgs": ["--inspect", "--sourcemap"],
|
||||
"env": {
|
||||
"REMOTE_DEBUGGING_PORT": "9222"
|
||||
}
|
||||
@ -21,7 +21,7 @@
|
||||
"request": "attach",
|
||||
"type": "chrome",
|
||||
"webRoot": "${workspaceFolder}/src/renderer",
|
||||
"timeout": 60000,
|
||||
"timeout": 3000000,
|
||||
"presentation": {
|
||||
"hidden": true
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import { useAppDispatch } from '@renderer/store'
|
||||
import { setMinappsOpenLinkExternal } from '@renderer/store/settings'
|
||||
import { MinAppType } from '@renderer/types'
|
||||
import { delay } from '@renderer/utils'
|
||||
import { Avatar, Drawer, Tooltip } from 'antd'
|
||||
import { Alert, Avatar, Button, Drawer, Tooltip } from 'antd'
|
||||
import { WebviewTag } from 'electron'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -39,6 +39,100 @@ interface AppExtraInfo {
|
||||
|
||||
type AppInfo = MinAppType & AppExtraInfo
|
||||
|
||||
/** Google login tip component */
|
||||
const GoogleLoginTip = ({
|
||||
isReady,
|
||||
currentUrl,
|
||||
currentAppId
|
||||
}: {
|
||||
appId?: string | null
|
||||
isReady: boolean
|
||||
currentUrl: string | null
|
||||
currentAppId: string | null
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [visible, setVisible] = useState(false)
|
||||
const { openMinappById } = useMinappPopup()
|
||||
|
||||
// 判断当前URL是否涉及Google登录
|
||||
const needsGoogleLogin = useMemo(() => {
|
||||
// 如果当前已经在Google小程序中,不需要显示提示
|
||||
if (currentAppId === 'google') return false
|
||||
|
||||
if (!currentUrl) return false
|
||||
|
||||
const googleLoginPatterns = [
|
||||
'accounts.google.com',
|
||||
'signin/oauth',
|
||||
'auth/google',
|
||||
'login/google',
|
||||
'sign-in/google',
|
||||
'google.com/signin',
|
||||
'gsi/client'
|
||||
]
|
||||
|
||||
return googleLoginPatterns.some((pattern) => currentUrl.toLowerCase().includes(pattern.toLowerCase()))
|
||||
}, [currentUrl, currentAppId])
|
||||
|
||||
// 在URL更新时检查是否需要显示提示
|
||||
useEffect(() => {
|
||||
let showTimer: NodeJS.Timeout | null = null
|
||||
let hideTimer: NodeJS.Timeout | null = null
|
||||
|
||||
// 如果是Google登录相关URL且小程序已加载完成,则延迟显示提示
|
||||
if (needsGoogleLogin && isReady) {
|
||||
showTimer = setTimeout(() => {
|
||||
setVisible(true)
|
||||
hideTimer = setTimeout(() => {
|
||||
setVisible(false)
|
||||
}, 30000)
|
||||
}, 500)
|
||||
} else {
|
||||
setVisible(false)
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (showTimer) clearTimeout(showTimer)
|
||||
if (hideTimer) clearTimeout(hideTimer)
|
||||
}
|
||||
}, [needsGoogleLogin, isReady, currentUrl])
|
||||
|
||||
// 处理关闭提示
|
||||
const handleClose = () => {
|
||||
setVisible(false)
|
||||
}
|
||||
|
||||
// 跳转到Google小程序
|
||||
const openGoogleMinApp = () => {
|
||||
// 使用openMinappById方法打开Google小程序
|
||||
openMinappById('google', true)
|
||||
// 关闭提示
|
||||
setVisible(false)
|
||||
}
|
||||
|
||||
// 只在需要Google登录时显示提示
|
||||
if (!needsGoogleLogin || !visible) return null
|
||||
|
||||
// 使用直接的消息文本
|
||||
const message = t('miniwindow.alert.google_login')
|
||||
|
||||
return (
|
||||
<Alert
|
||||
message={message}
|
||||
type="warning"
|
||||
showIcon
|
||||
closable
|
||||
onClose={handleClose}
|
||||
action={
|
||||
<Button type="primary" size="small" onClick={openGoogleMinApp}>
|
||||
{t('common.open')} Google
|
||||
</Button>
|
||||
}
|
||||
style={{ zIndex: 10, animation: 'fadeIn 0.3s ease-in-out' }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
/** The main container for MinApp popup */
|
||||
const MinappPopupContainer: React.FC = () => {
|
||||
const { openedKeepAliveMinapps, openedOneOffMinapp, currentMinappId, minappShow } = useRuntime()
|
||||
@ -198,9 +292,11 @@ const MinappPopupContainer: React.FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** the callback function to handle the webview navigate to new url */
|
||||
/** the callback function to handle webview navigation */
|
||||
const handleWebviewNavigate = (appid: string, url: string) => {
|
||||
// 记录当前URL,用于GoogleLoginTip判断
|
||||
if (appid === currentMinappId) {
|
||||
console.log('URL changed:', url)
|
||||
setCurrentUrl(url)
|
||||
}
|
||||
}
|
||||
@ -297,36 +393,36 @@ const MinappPopupContainer: React.FC = () => {
|
||||
</Tooltip>
|
||||
{appInfo.canOpenExternalLink && (
|
||||
<Tooltip title={t('minapp.popup.openExternal')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handleOpenLink(url ?? appInfo.url)}>
|
||||
<TitleButton onClick={() => handleOpenLink(url ?? appInfo.url)}>
|
||||
<ExportOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Spacer />
|
||||
<ButtonsGroup className={isWin || isLinux ? 'windows' : ''}>
|
||||
<Tooltip title={t('minapp.popup.goBack')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handleGoBack(appInfo.id)}>
|
||||
<TitleButton onClick={() => handleGoBack(appInfo.id)}>
|
||||
<ArrowLeftOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('minapp.popup.goForward')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handleGoForward(appInfo.id)}>
|
||||
<TitleButton onClick={() => handleGoForward(appInfo.id)}>
|
||||
<ArrowRightOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('minapp.popup.refresh')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handleReload(appInfo.id)}>
|
||||
<TitleButton onClick={() => handleReload(appInfo.id)}>
|
||||
<ReloadOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
{appInfo.canPinned && (
|
||||
<Tooltip
|
||||
title={appInfo.isPinned ? t('minapp.sidebar.remove.title') : t('minapp.sidebar.add.title')}
|
||||
mouseEnterDelay={0.8}
|
||||
placement="bottom">
|
||||
<Button onClick={() => handleTogglePin(appInfo.id)} className={appInfo.isPinned ? 'pinned' : ''}>
|
||||
<TitleButton onClick={() => handleTogglePin(appInfo.id)} className={appInfo.isPinned ? 'pinned' : ''}>
|
||||
<PushpinOutlined style={{ fontSize: 16 }} />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Tooltip
|
||||
@ -337,28 +433,28 @@ const MinappPopupContainer: React.FC = () => {
|
||||
}
|
||||
mouseEnterDelay={0.8}
|
||||
placement="bottom">
|
||||
<Button onClick={handleToggleOpenExternal} className={minappsOpenLinkExternal ? 'open-external' : ''}>
|
||||
<TitleButton onClick={handleToggleOpenExternal} className={minappsOpenLinkExternal ? 'open-external' : ''}>
|
||||
<LinkOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
{isInDevelopment && (
|
||||
<Tooltip title={t('minapp.popup.devtools')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handleOpenDevTools(appInfo.id)}>
|
||||
<TitleButton onClick={() => handleOpenDevTools(appInfo.id)}>
|
||||
<CodeOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
{canMinimize && (
|
||||
<Tooltip title={t('minapp.popup.minimize')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handlePopupMinimize()}>
|
||||
<TitleButton onClick={() => handlePopupMinimize()}>
|
||||
<MinusOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Tooltip title={t('minapp.popup.close')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<Button onClick={() => handlePopupClose(appInfo.id)}>
|
||||
<TitleButton onClick={() => handlePopupClose(appInfo.id)}>
|
||||
<CloseOutlined />
|
||||
</Button>
|
||||
</TitleButton>
|
||||
</Tooltip>
|
||||
</ButtonsGroup>
|
||||
</TitleContainer>
|
||||
@ -399,6 +495,8 @@ const MinappPopupContainer: React.FC = () => {
|
||||
marginLeft: 'var(--sidebar-width)',
|
||||
backgroundColor: window.root.style.background
|
||||
}}>
|
||||
{/* 在所有小程序中显示GoogleLoginTip */}
|
||||
<GoogleLoginTip isReady={isReady} currentUrl={currentUrl} currentAppId={currentMinappId} />
|
||||
{!isReady && (
|
||||
<EmptyView>
|
||||
<Avatar
|
||||
@ -460,7 +558,7 @@ const ButtonsGroup = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
const Button = styled.div`
|
||||
const TitleButton = styled.div`
|
||||
cursor: pointer;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
@ -437,6 +437,7 @@
|
||||
"more": "More",
|
||||
"name": "Name",
|
||||
"no_results": "No results",
|
||||
"open": "Open",
|
||||
"paste": "Paste",
|
||||
"prompt": "Prompt",
|
||||
"provider": "Provider",
|
||||
@ -813,6 +814,9 @@
|
||||
"title": "MinApp"
|
||||
},
|
||||
"miniwindow": {
|
||||
"alert": {
|
||||
"google_login": "Tip: If you see a 'browser not trusted' message when logging into Google, please first login through the Google mini app in the mini app list, then use Google login in other mini apps"
|
||||
},
|
||||
"clipboard": {
|
||||
"empty": "Clipboard is empty"
|
||||
},
|
||||
|
||||
@ -437,6 +437,7 @@
|
||||
"more": "もっと",
|
||||
"name": "名前",
|
||||
"no_results": "検索結果なし",
|
||||
"open": "開く",
|
||||
"paste": "貼り付け",
|
||||
"prompt": "プロンプト",
|
||||
"provider": "プロバイダー",
|
||||
@ -813,6 +814,9 @@
|
||||
"title": "ミニアプリ"
|
||||
},
|
||||
"miniwindow": {
|
||||
"alert": {
|
||||
"google_login": "ヒント:Googleログイン時に「信頼できないブラウザ」というメッセージが表示された場合は、先にミニアプリリストのGoogleミニアプリでアカウントログインを完了してから、他のミニアプリでGoogleログインを使用してください"
|
||||
},
|
||||
"clipboard": {
|
||||
"empty": "クリップボードが空です"
|
||||
},
|
||||
|
||||
@ -437,6 +437,7 @@
|
||||
"more": "Ещё",
|
||||
"name": "Имя",
|
||||
"no_results": "Результатов не найдено",
|
||||
"open": "Открыть",
|
||||
"paste": "Вставить",
|
||||
"prompt": "Промпт",
|
||||
"provider": "Провайдер",
|
||||
@ -813,6 +814,9 @@
|
||||
"title": "Встроенные приложения"
|
||||
},
|
||||
"miniwindow": {
|
||||
"alert": {
|
||||
"google_login": "Совет: Если при входе в Google вы видите сообщение 'ненадежный браузер', сначала войдите в аккаунт через мини-приложение Google в списке мини-приложений, а затем используйте вход через Google в других мини-приложениях"
|
||||
},
|
||||
"clipboard": {
|
||||
"empty": "Буфер обмена пуст"
|
||||
},
|
||||
|
||||
@ -437,6 +437,7 @@
|
||||
"more": "更多",
|
||||
"name": "名称",
|
||||
"no_results": "无结果",
|
||||
"open": "打开",
|
||||
"paste": "粘贴",
|
||||
"prompt": "提示词",
|
||||
"provider": "提供商",
|
||||
@ -813,6 +814,9 @@
|
||||
"title": "小程序"
|
||||
},
|
||||
"miniwindow": {
|
||||
"alert": {
|
||||
"google_login": "提示:如遇到Google登录提示\"不受信任的浏览器\",请先在小程序列表中的Google小程序中完成账号登录,再在其它小程序使用Google登录"
|
||||
},
|
||||
"clipboard": {
|
||||
"empty": "剪贴板为空"
|
||||
},
|
||||
|
||||
@ -437,6 +437,7 @@
|
||||
"more": "更多",
|
||||
"name": "名稱",
|
||||
"no_results": "沒有結果",
|
||||
"open": "開啟",
|
||||
"paste": "貼上",
|
||||
"prompt": "提示詞",
|
||||
"provider": "供應商",
|
||||
@ -813,6 +814,9 @@
|
||||
"title": "小工具"
|
||||
},
|
||||
"miniwindow": {
|
||||
"alert": {
|
||||
"google_login": "提示:如遇到Google登入提示\"不受信任的瀏覽器\",請先在小程序列表中的Google小程序中完成帳號登入,再在其它小程序使用Google登入"
|
||||
},
|
||||
"clipboard": {
|
||||
"empty": "剪貼簿為空"
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user