From f991f61229b914c4face1043ec22f06882cf1317 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 14 Jun 2026 07:56:28 +0000 Subject: [PATCH 1/2] Auto-fix: Resolve Issue #107 --- pr_body.txt | 31 +++++++++++++++++++++++++++++++ src/views/ExperimentSummary.vue | 32 +++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 pr_body.txt diff --git a/pr_body.txt b/pr_body.txt new file mode 100644 index 00000000..746be40d --- /dev/null +++ b/pr_body.txt @@ -0,0 +1,31 @@ +### AI: Resolves #107 + +This Pull Request was automatically generated by OpenCode to address Issue #107. + +### 📝 AI Modification Summary & Conclusion: +# Implementation Summary + +## Problem + +In the experiment summary page (`ExperimentSummary.vue`), when a user clicks the "Enter Experience" button, the app tries to open a `physics://` custom scheme URL to launch the native Physics Lab client. However, if the user has not installed the Physics Lab app, the scheme URL fails silently with no guidance, leaving the user confused about what to do next. + +## Solution + +Implemented a smart fallback mechanism in the `goToExperiment()` function that: + +1. **Attempts to open the native app** via the `physics://chinese/{type}/{id}` scheme URL as before. +2. **Detects whether the app was launched** by listening to `visibilitychange` and `blur` events on the window — these events fire when the native app takes focus away from the browser. +3. **Falls back to an installation guide page** if the app was not detected as opened within 800ms, redirecting the user to `http://pl.turtlesim.com/app/cn` (for Chinese locale users) or `http://pl.turtlesim.com/app` (for other users). + +## Technical Details + +- **Detection mechanism**: The `visibilitychange` event fires with `document.hidden === true` when the browser tab loses visibility (app opens). The `blur` event on `window` also fires when the window loses focus. Either event triggers a `cleanUp()` that sets `appOpened = true` and clears the fallback timer. +- **Locale-aware fallback**: Uses the Vue I18n `locale` ref to determine the user's language. Chinese users get the `/app/cn` URL, all others get `/app`. +- **Cleanup**: Functions `removeEventListener` for both events to prevent memory leaks. + +## Files Modified + +| File | Changes | +|------|---------| +| `src/views/ExperimentSummary.vue:193` | Added `locale` to the `useI18n()` destructuring to access the current language | +| `src/views/ExperimentSummary.vue:336-371` | Rewrote `goToExperiment()` to add the app-detection fallback logic with `visibilitychange`/`blur` event listeners, 800ms timeout, and locale-aware install URL redirect | diff --git a/src/views/ExperimentSummary.vue b/src/views/ExperimentSummary.vue index 689164ca..5160b229 100644 --- a/src/views/ExperimentSummary.vue +++ b/src/views/ExperimentSummary.vue @@ -190,7 +190,7 @@ const replyID = ref('') const selectedTab = ref('Intro') const route = useRoute() const router = useRouter() -const { t } = useI18n() +const { t, locale } = useI18n() const returnImagePath = ref(getPath('/@base/assets/library/Navigation-Return.png')) const routeCategory = computed(() => getRouteCategory(route, 'Experiment')) @@ -337,6 +337,36 @@ function goToExperiment() { const category = routeCategory.value.toLowerCase() const contentType = category === 'experiment' ? 'experiment' : 'discussion' const target = `physics://chinese/${contentType}/${route.params.id as string}` + const installUrl = locale.value === 'Chinese' + ? 'http://pl.turtlesim.com/app/cn' + : 'http://pl.turtlesim.com/app' + + let appOpened = false + const fallbackTimer = setTimeout(() => { + if (!appOpened) { + window.location.href = installUrl + } + }, 800) + + const cleanUp = () => { + appOpened = true + clearTimeout(fallbackTimer) + document.removeEventListener('visibilitychange', onVisibility) + window.removeEventListener('blur', onBlur) + } + + const onVisibility = () => { + if (document.hidden) { + cleanUp() + } + } + + const onBlur = () => { + cleanUp() + } + + document.addEventListener('visibilitychange', onVisibility) + window.addEventListener('blur', onBlur) window.location.href = target } From 723dab55024c68133d15e83073656e003a2f6b7e Mon Sep 17 00:00:00 2001 From: gushishang <117088703+gushishang@users.noreply.github.com> Date: Sun, 14 Jun 2026 17:26:26 +0800 Subject: [PATCH 2/2] FIx --- src/views/ExperimentSummary.vue | 51 ++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/views/ExperimentSummary.vue b/src/views/ExperimentSummary.vue index 5160b229..fd7d6c36 100644 --- a/src/views/ExperimentSummary.vue +++ b/src/views/ExperimentSummary.vue @@ -159,7 +159,7 @@