Skip to content

fix: Control Island stability and camera jitter resolution#1278

Open
dasilva333 wants to merge 3 commits intomoeru-ai:mainfrom
dasilva333:feat/control-islands-camera
Open

fix: Control Island stability and camera jitter resolution#1278
dasilva333 wants to merge 3 commits intomoeru-ai:mainfrom
dasilva333:feat/control-islands-camera

Conversation

@dasilva333
Copy link

This PR addresses several UI stability and synchronization issues:

  • Control Island Stability: Implements a collapse timer and sub-menu reset logic to prevent unexpected UI behavior.
  • Hearing Dialog Fix: Ensures the controls island doesn't collapse while the hearing configuration dialog is open.
  • Camera Jitter Resolution: Fixes the jitter in the VRM camera slider by introducing a programmatic update lock in OrbitControls.vue.
  • Pin on Top: Adds a toggle to keep the Tamagotchi window always on top, with a corresponding Japanese translation.
  • Dragging Fix: Ensures window dragging works correctly on non-Linux platforms.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the user experience by addressing several critical UI stability and interaction issues. It refines the behavior of the Control Island, preventing unexpected collapses and ensuring smooth sub-menu navigation. Furthermore, it eliminates camera jitter in the 3D model viewer and enhances window management with an "always on top" option and more robust dragging functionality across different operating systems. The changes also include improved logging for backend processes.

Highlights

  • Control Island Stability: Implemented a collapse timer and sub-menu reset logic for the Control Island to enhance UI stability and prevent unexpected behavior.
  • Hearing Dialog Fix: Ensured the Control Island does not collapse when the hearing configuration dialog is actively open.
  • Camera Jitter Resolution: Resolved camera jitter in the VRM camera slider by introducing a programmatic update lock within OrbitControls.vue.
  • Pin on Top Feature: Added a toggle to keep the Tamagotchi window always on top, including support for Japanese translation.
  • Window Dragging Fix: Corrected window dragging functionality to work reliably on non-Linux platforms.
  • Logging Enhancements: Introduced console logging for provider validation results and LLM raw output in the main process.
Changelog
  • apps/stage-tamagotchi/src/main/index.ts
    • Added IPC event listeners for logging provider validation results and LLM raw output to the console.
    • Integrated mic-toggle shortcut setup.
  • apps/stage-tamagotchi/src/renderer/components/stage-islands/controls-island/index.vue
    • Replaced useIntervalFn with useTimeoutFn for the collapse timer, improving control over island expansion/collapse.
    • Implemented logic to reset the sub-menu (view.value = 'main') upon island collapse.
    • Imported useModelStore to access model-related state.
    • Refactored startDraggingWindow to explicitly check isLinux.value before invoking the drag function.
  • packages/stage-ui-three/src/components/Controls/OrbitControls.vue
    • Introduced an isProgrammatic flag to prevent orbitControlsCameraChanged events from firing during programmatic camera updates, resolving camera jitter.
    • Applied the isProgrammatic flag to various camera and control watch functions (modelSize, cameraPosition, cameraTarget, cameraFOV, cameraDistance).
  • packages/stage-ui/src/stores/settings/controls-island.ts
    • Imported ref from 'vue'.
    • Added a newline in the resetState function for formatting.
Ignored Files
  • Ignored by pattern: packages/i18n/src/** (1)
    • packages/i18n/src/locales/ja/tamagotchi/stage.yaml
Activity
  • No specific activity (comments, reviews, progress updates) has been recorded for this pull request since its creation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several useful fixes for UI stability, camera jitter, and platform-specific window behavior. The refactoring of the Control Island's collapse logic and the introduction of a programmatic lock in OrbitControls are positive changes. However, a critical security vulnerability has been identified: the changes in apps/stage-tamagotchi/src/main/index.ts introduce logging of potentially sensitive information, such as provider configuration (which may contain API keys) and raw LLM output (which may contain PII), to the console. These logging statements must be removed or sanitized to prevent sensitive data exposure. Additionally, a bug in the new window dragging logic and a potential robustness issue in the camera control updates were found. Specific feedback and code suggestions are provided to address these issues.

Comment on lines +122 to +126
function startDraggingWindow() {
if (!isLinux.value) {
startDraggingWindowInvoke()
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

isLinux is an asynchronous function returned by useElectronEventaInvoke. Accessing isLinux.value is incorrect as it will be undefined, causing !isLinux.value to always be true. This will result in startDraggingWindowInvoke() being called on all platforms, which may not be the intended behavior. To correctly handle the asynchronous platform check, you should await the result of isLinux(). Making startDraggingWindow an async function is a direct way to fix this.

async function startDraggingWindow() {
  if (!await isLinux()) {
    startDraggingWindowInvoke()
  }
}

Comment on lines +187 to +189
if (data.config && (data.valid || !data.reason?.includes('required'))) {
console.log(` └─ Config: ${JSON.stringify(data.config)}`)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The application logs the entire data.config object to the console. Provider configurations often contain sensitive information such as API keys, secrets, or other credentials. Logging this information can lead to credential leakage if the console output is captured in logs or viewed by unauthorized individuals.

Suggested change
if (data.config && (data.valid || !data.reason?.includes('required'))) {
console.log(` └─ Config: ${JSON.stringify(data.config)}`)
}
if (data.config && (data.valid || !data.reason?.includes('required'))) {
// Sensitive configuration logging removed
}

Comment on lines +199 to +202
console.log(`${cyan}[LLM Final Output]${reset} Session: ${data.sessionId}`)
console.log(`----------------------------------------`)
console.log(data.text)
console.log(`----------------------------------------`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The application logs the full text of LLM output to the console. Depending on the use case, LLM output may contain Personally Identifiable Information (PII) or other sensitive data processed by the model. Logging this information to the console can lead to data exposure.

Suggested change
console.log(`${cyan}[LLM Final Output]${reset} Session: ${data.sessionId}`)
console.log(`----------------------------------------`)
console.log(data.text)
console.log(`----------------------------------------`)
console.log(`${cyan}[LLM Final Output]${reset} Session: ${data.sessionId}`)
console.log(`----------------------------------------`)
// Raw LLM output logging removed for privacy
console.log(`----------------------------------------`)

Comment on lines 76 to 84
watch(modelSize, (newSize) => {
if (!controls.value)
return
isProgrammatic = true
controls.value.minDistance = newSize.z
controls.value.maxDistance = newSize.z * 20
controls.value.update()
isProgrammatic = false
}, { immediate: true, deep: true })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of an isProgrammatic flag is a good approach to prevent update loops. However, if an error occurs during the programmatic update (e.g., inside controls.value.update()), the isProgrammatic flag will not be reset to false. This could leave the controls in a state where user input is permanently ignored. Using a try...finally block will ensure the flag is always reset, making the implementation more robust.

  watch(modelSize, (newSize) => {
    if (!controls.value)
      return
    isProgrammatic = true
    try {
      controls.value.minDistance = newSize.z
      controls.value.maxDistance = newSize.z * 20
      controls.value.update()
    }
    finally {
      isProgrammatic = false
    }
  }, { immediate: true, deep: true })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants