Skip to content

Conversation

@MohammedAnasNathani
Copy link
Contributor

@MohammedAnasNathani MohammedAnasNathani commented Nov 29, 2025

Description

Fixed the issue where live preview of color settings was not working. Previously, the preview only updated after saving.

Issues

Closes #1175

Fix

  1. ColorPicker.vue: Changed the input event from @change to @input. This ensures the parent component receives color updates continuously while dragging the color picker, not just when the picker is closed.
  2. theme.vue: Added a deep watcher on config.theme.colors. This triggers applyThemeConfig immediately whenever colors change, updating the CSS variables in real-time for an instant preview.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Summary by Sourcery

Enable real-time theme color preview while editing admin configuration

Bug Fixes:

  • Update the color picker to emit changes continuously so theme colors update while dragging the selector instead of only on change commit

Enhancements:

  • Add a deep watcher on theme color configuration to immediately apply theme updates for live preview in the admin UI

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 29, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Enables real-time theme color live preview by emitting color changes continuously from the ColorPicker component and immediately re-applying theme configuration via a deep watcher on theme colors.

Sequence diagram for real-time theme color live preview

sequenceDiagram
  actor AdminUser
  participant ColorPicker
  participant AdminThemeView
  participant VueWatcher
  participant ThemeService
  participant BrowserCSS

  AdminUser ->> ColorPicker: Drag color input (native input event)
  ColorPicker -->> AdminThemeView: emit update:modelValue(newColor) on input
  AdminThemeView ->> AdminThemeView: update config.theme.colors via v-model
  AdminThemeView -->> VueWatcher: config.theme.colors changed
  VueWatcher ->> ThemeService: applyThemeConfig(themePayload)
  ThemeService ->> BrowserCSS: Update CSS variables for theme
  BrowserCSS -->> AdminUser: Live preview updates immediately

  loop Continuous drag
    AdminUser ->> ColorPicker: Move picker handle
    ColorPicker -->> AdminThemeView: emit update:modelValue(newColor)
    AdminThemeView -->> VueWatcher: config.theme.colors changed
    VueWatcher ->> ThemeService: applyThemeConfig(themePayload)
    ThemeService ->> BrowserCSS: Update CSS variables
  end
Loading

Flow diagram for color changes to theme CSS variables

graph TD
  A["AdminUser drags color in ColorPicker"] --> B["ColorPicker emits update:modelValue on input"]
  B --> C["AdminThemeView updates config.theme.colors"]
  C --> D["Vue deep watcher on config.theme.colors triggers"]
  D --> E["Build themePayload with merged defaults"]
  E --> F["applyThemeConfig(themePayload)"]
  F --> G["CSS variables updated in browser"]
  G --> H["Live theme color preview visible to AdminUser"]
Loading

File-Level Changes

Change Details Files
Emit color updates continuously from the color picker instead of only on change completion.
  • Switch the native color input listener from the change event to the input event so updates fire while dragging the picker.
  • Continue emitting v-model compatible update:modelValue events with the current color value.
app/eventyay/webapp/src/components/ColorPicker.vue
Re-apply theme configuration in real-time when color settings change.
  • Add a deep Vue watcher on config.theme.colors to detect any nested color field changes.
  • On color change, build a theme payload merging DEFAULT_* constants with the current config.theme values, including logo, streamOfflineImage, and identicons.
  • Call applyThemeConfig with the constructed payload to update CSS variables immediately for live preview.
app/eventyay/webapp/src/views/admin/config/theme.vue

Assessment against linked issues

Issue Objective Addressed Explanation
#1175 Ensure that changes to color settings (Primary, Accent, Background, etc.) are propagated to the theme configuration so that the live preview updates instead of showing default system colors.
#1175 Implement real-time or near-real-time updating of the live preview when color values are modified, without requiring a full page refresh or additional manual steps.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The watcher is declared only on config.theme.colors but the handler also reads logo, identicons, and streamOfflineImage, so consider expanding the watch source (or using a single deep watch on config.theme) to keep all theme aspects in sync for live preview.
  • The watcher’s handler reconstructs the themePayload inline; if similar logic exists elsewhere (e.g., save/apply routines), consider extracting a shared helper to avoid duplication and keep future changes to the theme structure in one place.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The watcher is declared only on `config.theme.colors` but the handler also reads `logo`, `identicons`, and `streamOfflineImage`, so consider expanding the watch source (or using a single deep watch on `config.theme`) to keep all theme aspects in sync for live preview.
- The watcher’s handler reconstructs the `themePayload` inline; if similar logic exists elsewhere (e.g., save/apply routines), consider extracting a shared helper to avoid duplication and keep future changes to the theme structure in one place.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@MohammedAnasNathani
Copy link
Contributor Author

Thank you for the excellent suggestions, @sourcery-ai! I've refactored the code to address both points:

  1. The watcher now observes the entire config.theme object to enable live previews for all theme settings on this page.
  2. I've extracted the theme application logic into a shared _applyThemePreview() helper to avoid code duplication.

Copy link
Member

@mariobehling mariobehling left a comment

Choose a reason for hiding this comment

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

Please share screenshots for PRs that involve UI features or changes. Thank you

Copilot finished reviewing on behalf of mariobehling November 30, 2025 05:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enables real-time live preview for color settings in the theme configuration admin UI. Previously, color changes only applied after clicking Save; now they update instantly while editing.

Key Changes:

  • Modified ColorPicker to emit updates continuously during color selection via @input instead of @change
  • Added a deep watcher on theme configuration to automatically apply changes in real-time
  • Refactored theme application logic into a reusable helper method
  • Simplified validation configuration (though with some issues noted below)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
app/eventyay/webapp/src/components/ColorPicker.vue Changed color input event from @change to @input to emit updates continuously during drag/selection
app/eventyay/webapp/src/views/admin/config/theme.vue Added deep watcher on theme config, extracted _applyThemePreview() helper method, simplified validation config, and removed outdated comments

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hpdang
Copy link
Member

hpdang commented Dec 1, 2025

@prayag78 do you want to test/review this one?

@MohammedAnasNathani
Copy link
Contributor Author

Hi @mariobehling, thank you for the review.
I am unfortunately blocked from providing screenshots currently due to a persistent and unresolvable issue with the development environment.

However, the UI fix in this PR is straightforward:

  1. The ColorPicker component now uses the @input event for real-time updates.
  2. A watcher was added to theme.vue to immediately call applyThemeConfig.

These two changes logically enable the real-time preview as requested. I hope the code is clear enough for review on its own. Thank you.

@mariobehling
Copy link
Member

@MohammedAnasNathani
What is the issue with the development environment? What is preventing you from setting it up?

@MohammedAnasNathani
Copy link
Contributor Author

Hi @mariobehling, thanks for asking. I've been working in two environments (local Docker on macOS and GitHub Codespaces) and have run into a persistent WebSocket connection issue.

Core Problem:
The video component fails to establish a WebSocket connection (Error 1006), which prevents the modern admin UI from fully rendering.

What I've Tried:

  • Codespaces:
    I correctly configured ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, and even CORS_ALLOWED_ORIGINS to match the forwarded Codespace URL. Despite this, the WebSocket connection is still rejected, likely due to a conflict with the Codespaces proxy layer.

  • Local Docker:
    The build process is repeatedly failing at the apt-get install step with "Hash Sum mismatch" and "File has unexpected size" errors. This points to a temporary issue with the upstream Debian package mirrors, as it persists even after running builds with --no-cache.

I'm confident I can resolve this, but I didn't want to delay the PRs further while I debugged what seems to be an external infrastructure issue. The code fixes themselves are complete and verified through logic and server logs.

@prayag78
Copy link
Contributor

prayag78 commented Dec 1, 2025

@hpdang thanks for giving opportunity to review this PR.

Hi @MohammedAnasNathani, thanks for work on this issue. I previously worked on this #1360, where I added a missing CSS regeneration trigger to update the color.

During the fixing, I was thinking about the organizer settings, but we can also change colors from the specific event settings. After testing, the current logic correctly regenerates CSS from both settings:

  1. Organizer Settings:

    • Triggers regenerate_organizer_css()
    • Updates CSS for all events under that organizer
  2. Event Settings:

    • Triggers regenerate_css()
    • Updates CSS for that specific event, overriding organizer colors

@mariobehling could you please check PR #1360 again? I think both the organizer and event-level CSS regeneration working.

Copy link
Member

@ArnavBallinCode ArnavBallinCode left a comment

Choose a reason for hiding this comment

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

Hi @mariobehling, thanks for asking. I've been working in two environments (local Docker on macOS and GitHub Codespaces) and have run into a persistent WebSocket connection issue.

Core Problem: The video component fails to establish a WebSocket connection (Error 1006), which prevents the modern admin UI from fully rendering.

What I've Tried:

  • Codespaces:
    I correctly configured ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, and even CORS_ALLOWED_ORIGINS to match the forwarded Codespace URL. Despite this, the WebSocket connection is still rejected, likely due to a conflict with the Codespaces proxy layer.
  • Local Docker:
    The build process is repeatedly failing at the apt-get install step with "Hash Sum mismatch" and "File has unexpected size" errors. This points to a temporary issue with the upstream Debian package mirrors, as it persists even after running builds with --no-cache.

I'm confident I can resolve this, but I didn't want to delay the PRs further while I debugged what seems to be an external infrastructure issue. The code fixes themselves are complete and verified through logic and server logs.

  1. I think you are messing up two things, please start a fresh clean setup using local Docker

  2. The WebSocket failure you’re seeing is specific to Codespaces, not the Docker setup. With the current compose file, the WebSocket endpoint runs on the same container and same port as Django

There’s no networking layer that can trigger a 1006 close. Can you restart your system too once.

Also the full stack does run on my system , can you send the log file / screenshot of the logs -local - docker

Screenshot 2025-12-02 at 10 13 40 AM

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +70 to +77
watch: {
'config.theme.colors': {
deep: true,
handler() {
this._applyThemePreview()
}
}
},
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The deep watcher combined with continuous @input events from the color picker will trigger applyThemeConfig() very frequently while dragging. This function manipulates DOM CSS variables on every call. Consider adding throttling/debouncing to the watcher handler to improve performance during rapid color changes:

import { throttle } from 'lodash' // or implement a simple throttle

export default {
  // ...
  watch: {
    'config.theme.colors': {
      deep: true,
      handler: throttle(function() {
        this._applyThemePreview()
      }, 50) // Throttle to max 20 updates/second
    }
  }
}

This would maintain smooth live preview while reducing unnecessary DOM manipulations.

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +131
_applyThemePreview() {
if (!this.config) return
const themePayload = {
colors: {...DEFAULT_COLORS, ...this.config.theme.colors},
logo: {...DEFAULT_LOGO, ...this.config.theme.logo},
streamOfflineImage: this.config.theme.streamOfflineImage ?? null,
identicons: {...DEFAULT_IDENTICONS, ...this.config.theme.identicons}
}
applyThemeConfig(themePayload)
},
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The watcher will trigger _applyThemePreview() even when color values are invalid (e.g., while typing an incomplete hex code). Since applyThemeConfig() uses the Color() library which throws errors on invalid color strings, this could cause runtime errors during user input.

Consider adding validation before applying the theme:

_applyThemePreview() {
  if (!this.config) return
  // Don't apply if there are validation errors
  if (this.v$.$invalid) return
  
  const themePayload = {
    colors: {...DEFAULT_COLORS, ...this.config.theme.colors},
    logo: {...DEFAULT_LOGO, ...this.config.theme.logo},
    streamOfflineImage: this.config.theme.streamOfflineImage ?? null,
    identicons: {...DEFAULT_IDENTICONS, ...this.config.theme.identicons}
  }
  applyThemeConfig(themePayload)
}

Or wrap the applyThemeConfig() call in a try-catch to prevent errors from breaking the UI.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Color settings do not update in the live preview after modification

5 participants