diff --git a/apps/desktop/src-electron/app.ts b/apps/desktop/src-electron/app.ts index 368147ee2cd..21a69fe21f8 100644 --- a/apps/desktop/src-electron/app.ts +++ b/apps/desktop/src-electron/app.ts @@ -637,6 +637,11 @@ function createMainWindow() { safelyBrowserWindow?.setBackgroundColor(getBackgroundColor(themeKey)); }); + ipcMain.on(ipcMessageKeys.APP_IS_FOCUSED, (event) => { + const safelyBrowserWindow = getSafelyBrowserWindow(); + event.returnValue = safelyBrowserWindow?.isFocused(); + }); + ipcMain.on(ipcMessageKeys.TOUCH_ID_PROMPT, async (event, msg: string) => { if (isWin) { logger.info( diff --git a/apps/desktop/src-electron/config.ts b/apps/desktop/src-electron/config.ts index 280bb123d76..5a62e9491ab 100644 --- a/apps/desktop/src-electron/config.ts +++ b/apps/desktop/src-electron/config.ts @@ -56,6 +56,7 @@ export const ipcMessageKeys = { APP_OPEN_LOGGER_FILE: 'app/openLoggerFile', APP_TEST_CRASH: 'app/testCrash', APP_UPDATE_DISABLE_SHORTCUTS: 'app/updateDisableShortcuts', + APP_IS_FOCUSED: 'app/isFocused', // Theme THEME_UPDATE: 'theme/update', diff --git a/apps/desktop/src-electron/preload.ts b/apps/desktop/src-electron/preload.ts index cb0edc7e407..561377d09d6 100644 --- a/apps/desktop/src-electron/preload.ts +++ b/apps/desktop/src-electron/preload.ts @@ -54,6 +54,7 @@ export type IDesktopAPI = { onAppState: (cb: (state: IDesktopAppState) => void) => () => void; canPromptTouchID: () => boolean; getEnvPath: () => { [key: string]: string }; + isFocused: () => boolean; changeDevTools: (isOpen: boolean) => void; changeTheme: (theme: string) => void; changeLanguage: (theme: string) => void; @@ -277,6 +278,7 @@ const desktopApi = Object.freeze({ }, getBundleInfo: () => ipcRenderer.sendSync(ipcMessageKeys.APP_GET_BUNDLE_INFO) as IMacBundleInfo, + isFocused: () => ipcRenderer.sendSync(ipcMessageKeys.APP_IS_FOCUSED), openLoggerFile: () => ipcRenderer.send(ipcMessageKeys.APP_OPEN_LOGGER_FILE), testCrash: () => ipcRenderer.send(ipcMessageKeys.APP_TEST_CRASH), promptTouchID: async ( diff --git a/development/webpack/utils.js b/development/webpack/utils.js index 5f0655ea909..7787387ddbc 100644 --- a/development/webpack/utils.js +++ b/development/webpack/utils.js @@ -40,3 +40,9 @@ exports.createResolveExtensions = function ({ platform, configName }) { '.d.ts', ]); }; + +exports.getOutputFolder = function ({ isManifestV3 }) { + // isManifestV3 ? `${buildTargetBrowser}_v3` : buildTargetBrowser, + const buildTargetBrowser = TARGET_BROWSER; + return isManifestV3 ? `${buildTargetBrowser}_v3` : buildTargetBrowser; +}; diff --git a/development/webpack/webpack.ext.config.js b/development/webpack/webpack.ext.config.js index 4cdcfd57c16..b2f280c86af 100644 --- a/development/webpack/webpack.ext.config.js +++ b/development/webpack/webpack.ext.config.js @@ -13,9 +13,9 @@ const { isDev, isManifestV2, ENABLE_ANALYZER, - TARGET_BROWSER, } = require('./constant'); const devUtils = require('./ext/devUtils'); +const utils = require('./utils'); const codeSplit = require('./ext/codeSplit'); const pluginsHtml = require('./ext/pluginsHtml'); const pluginsCopy = require('./ext/pluginsCopy'); @@ -23,14 +23,6 @@ const pluginsCopy = require('./ext/pluginsCopy'); const IS_DEV = isDev; -function getOutputFolder() { - // isManifestV3 ? `${buildTargetBrowser}_v3` : buildTargetBrowser, - const buildTargetBrowser = TARGET_BROWSER; - return isManifestV3 ? `${buildTargetBrowser}_v3` : buildTargetBrowser; -} - -module.exports.getOutputFolder = getOutputFolder; - module.exports = ({ basePath, platform = babelTools.developmentConsts.platforms.ext, @@ -52,7 +44,7 @@ module.exports = ({ plugins: baseConfig.basePlugins, output: { clean: false, - path: path.resolve(basePath, 'build', getOutputFolder()), + path: path.resolve(basePath, 'build', utils.getOutputFolder()), // do not include [hash] here, as `content-script.bundle.js` filename should be stable filename: '[name].bundle.js', chunkFilename: isDev diff --git a/development/webpack/webpack.prod.config.js b/development/webpack/webpack.prod.config.js index b60d31b51a4..bd17d838fe9 100644 --- a/development/webpack/webpack.prod.config.js +++ b/development/webpack/webpack.prod.config.js @@ -2,7 +2,7 @@ const TerserPlugin = require('terser-webpack-plugin'); const path = require('path'); const { sentryWebpackPlugin } = require('@sentry/webpack-plugin'); const babelTools = require('../babelTools'); -const extConfig = require('./webpack.ext.config'); +const utils = require('./utils'); const FILES_TO_DELETE_AFTER_UPLOAD = [ '**/*.js.map', @@ -13,7 +13,7 @@ const FILES_TO_DELETE_AFTER_UPLOAD = [ module.exports = ({ platform, basePath }) => { const isExt = platform === babelTools.developmentConsts.platforms.ext; const rootPath = isExt - ? path.join(basePath, 'build', extConfig.getOutputFolder()) + ? path.join(basePath, 'build', utils.getOutputFolder()) : path.join(basePath, 'web-build'); const filesToDeleteAfterUpload = FILES_TO_DELETE_AFTER_UPLOAD.map((file) => path.join(rootPath, file), diff --git a/packages/components/src/composite/Banner/index.tsx b/packages/components/src/composite/Banner/index.tsx index 29dcd7cab48..7040b516d75 100644 --- a/packages/components/src/composite/Banner/index.tsx +++ b/packages/components/src/composite/Banner/index.tsx @@ -142,7 +142,7 @@ export function Banner({ ({ variant="tertiary" position="absolute" right="$10" - top="50%" + bottom="50%" transform={platformEnv.isNative ? '' : 'translateY(-50%)'} iconProps={{ color: diff --git a/packages/components/src/hooks/useVisibilityChange.ts b/packages/components/src/hooks/useVisibilityChange.ts index 3925d842c11..1bb2491e695 100644 --- a/packages/components/src/hooks/useVisibilityChange.ts +++ b/packages/components/src/hooks/useVisibilityChange.ts @@ -10,6 +10,9 @@ export const getCurrentVisibilityState = () => { // https://reactnative.dev/docs/appstate return AppState.currentState === 'active' || AppState.currentState === null; } + if (platformEnv.isDesktop) { + return globalThis.desktopApi.isFocused(); + } return document.visibilityState === 'visible'; }; export const onVisibilityStateChange = ( @@ -23,6 +26,13 @@ export const onVisibilityStateChange = ( subscription.remove(); }; } + + if (platformEnv.isDesktop) { + const removeSubscription = globalThis.desktopApi.onAppState((state) => { + callback(state === 'active'); + }); + return removeSubscription; + } const handleVisibilityStateChange = () => { callback(document.visibilityState === 'visible'); }; diff --git a/packages/kit-bg/src/states/jotai/atoms/devSettings.ts b/packages/kit-bg/src/states/jotai/atoms/devSettings.ts index db8f4524aab..e5798a03bd4 100644 --- a/packages/kit-bg/src/states/jotai/atoms/devSettings.ts +++ b/packages/kit-bg/src/states/jotai/atoms/devSettings.ts @@ -21,6 +21,7 @@ export interface IDevSettings { disableSolanaPriorityFee?: boolean; disableNumberShortcuts?: boolean; disableSearchAndAccountSelectorShortcuts?: boolean; + webviewDebuggingEnabled?: boolean; } export type IDevSettingsKeys = keyof IDevSettings; @@ -43,6 +44,7 @@ export const { disableSolanaPriorityFee: false, disableNumberShortcuts: false, disableSearchAndAccountSelectorShortcuts: false, + webviewDebuggingEnabled: false, }, }, }); diff --git a/packages/kit/src/components/WebView/InpageProviderWebView.native.tsx b/packages/kit/src/components/WebView/InpageProviderWebView.native.tsx index e1e66714a70..b7ffb15e3ec 100644 --- a/packages/kit/src/components/WebView/InpageProviderWebView.native.tsx +++ b/packages/kit/src/components/WebView/InpageProviderWebView.native.tsx @@ -33,6 +33,7 @@ const InpageProviderWebView: FC = forwardRef( androidLayerType, displayProgressBar, onProgress, + webviewDebuggingEnabled, }: IInpageProviderWebViewProps, ref: any, ) => { @@ -120,6 +121,7 @@ const InpageProviderWebView: FC = forwardRef( {progressLoading} , []); + const debuggingEnabled = useMemo(() => { + if (__DEV__) { + return true; + } + + if ( + devSettings.enabled && + devSettings.settings?.webviewDebuggingEnabled + ) { + return true; + } + + return webviewDebuggingEnabled; + }, [ + devSettings.enabled, + devSettings.settings?.webviewDebuggingEnabled, + webviewDebuggingEnabled, + ]); + const renderWebView = ( ); diff --git a/packages/kit/src/components/WebView/index.tsx b/packages/kit/src/components/WebView/index.tsx index 88828957e97..d27eaa39ee9 100644 --- a/packages/kit/src/components/WebView/index.tsx +++ b/packages/kit/src/components/WebView/index.tsx @@ -42,6 +42,7 @@ interface IWebViewProps extends IElectronWebViewEvents { onScroll?: IWebViewOnScroll; displayProgressBar?: boolean; onProgress?: (progress: number) => void; + webviewDebuggingEnabled?: boolean; } const WebView: FC = ({ @@ -51,6 +52,7 @@ const WebView: FC = ({ onWebViewRef = () => {}, customReceiveHandler, containerProps, + webviewDebuggingEnabled, ...rest }) => { const receiveHandler = useCallback( @@ -81,6 +83,7 @@ const WebView: FC = ({ void; + /** + * Enables WebView remote debugging using Chrome (Android) or Safari (iOS). + * Only works in iOS and Android devices. + */ + webviewDebuggingEnabled?: boolean; } export type IElectronWebView = { diff --git a/packages/kit/src/provider/Container/NetworkReachabilityTracker.tsx b/packages/kit/src/provider/Container/NetworkReachabilityTracker.tsx index 9a19183985e..05ce99d3a55 100644 --- a/packages/kit/src/provider/Container/NetworkReachabilityTracker.tsx +++ b/packages/kit/src/provider/Container/NetworkReachabilityTracker.tsx @@ -19,8 +19,8 @@ const checkNetInfo = async (devSettings: IDevSettingsPersistAtom) => { reachabilityLongTimeout: REACHABILITY_LONG_TIMEOUT, reachabilityShortTimeout: REACHABILITY_SHORT_TIMEOUT, reachabilityRequestTimeout: REACHABILITY_REQUEST_TIMEOUT, - reachabilityShouldRun: () => getCurrentVisibilityState(), - // met iOS requirements to get SSID. Will leak memory if set to true without meeting requirements. + // TODO: Rewrite to periodically check reachability + reachabilityShouldRun: () => true, shouldFetchWiFiSSID: false, useNativeReachability: false, }); diff --git a/packages/kit/src/views/Earn/EarnHome.tsx b/packages/kit/src/views/Earn/EarnHome.tsx index b21a667b38a..e9cb4480247 100644 --- a/packages/kit/src/views/Earn/EarnHome.tsx +++ b/packages/kit/src/views/Earn/EarnHome.tsx @@ -799,22 +799,26 @@ function BasicEarnHome() { onItemPress={onBannerPress} isLoading={false} leftIconButtonStyle={{ - left: '$1.5', + left: '$3.5', + bottom: '$2.5', size: 'small', }} rightIconButtonStyle={{ - right: '$1.5', + right: '$3.5', + bottom: '$2.5', size: 'small', }} indicatorContainerStyle={{ - right: '$2.5', + right: 0, + width: '100%', + jc: 'center', bottom: '$3', }} itemTitleContainerStyle={{ top: 0, bottom: 0, - right: '$10', - left: '$10', + right: '$3.5', + left: '$3.5', justifyContent: 'center', }} /> diff --git a/packages/kit/src/views/Setting/pages/FloatingIcon/index.tsx b/packages/kit/src/views/Setting/pages/FloatingIcon/index.tsx index 95648326f49..ec6cdf8c7e3 100644 --- a/packages/kit/src/views/Setting/pages/FloatingIcon/index.tsx +++ b/packages/kit/src/views/Setting/pages/FloatingIcon/index.tsx @@ -11,6 +11,7 @@ import { import backgroundApiProxy from '@onekeyhq/kit/src/background/instance/backgroundApiProxy'; import { useSettingsPersistAtom } from '@onekeyhq/kit-bg/src/states/jotai/atoms/settings'; import { ETranslations } from '@onekeyhq/shared/src/locale'; +import { defaultLogger } from '@onekeyhq/shared/src/logger/logger'; function FloatingIconModal() { const intl = useIntl(); @@ -35,6 +36,9 @@ function FloatingIconModal() { await backgroundApiProxy.serviceSetting.setIsShowFloatingButton( value, ); + defaultLogger.discovery.dapp.enableFloatingIcon({ + enable: value, + }); }} /> diff --git a/packages/kit/src/views/Setting/pages/List/DevSettingsSection/index.tsx b/packages/kit/src/views/Setting/pages/List/DevSettingsSection/index.tsx index bf3469a8626..efae0b05dcb 100644 --- a/packages/kit/src/views/Setting/pages/List/DevSettingsSection/index.tsx +++ b/packages/kit/src/views/Setting/pages/List/DevSettingsSection/index.tsx @@ -217,6 +217,19 @@ export const DevSettingsSection = () => { > + {platformEnv.isNative ? ( + { + setTimeout(() => { + backgroundApiProxy.serviceApp.restartApp(); + }, 300); + }} + > + + + ) : null}