Skip to content

feat(birthday-greeting): add birthday-greeting edge app with responsive design#639

Open
nicomiguelino wants to merge 29 commits intomasterfrom
new-edge-app/birthday-app
Open

feat(birthday-greeting): add birthday-greeting edge app with responsive design#639
nicomiguelino wants to merge 29 commits intomasterfrom
new-edge-app/birthday-app

Conversation

@nicomiguelino
Copy link
Contributor

@nicomiguelino nicomiguelino commented Jan 28, 2026

User description

  • Create new Birthday Greeting Edge App
  • Implement personalized greeting with name, role, and optional Base64 photo support
  • Add test suite for settings retrieval and image handling
  • Include deployment configuration and documentation

Screenshots (WIP)

image

PR Type

Enhancement, Tests, Documentation


Description

  • Implement settings and Base64 image support

  • Add unit tests for settings and image handling

  • Add responsive CSS styling with Tailwind

  • Provide deployment config and documentation


Diagram Walkthrough

flowchart LR
  A["Get settings (name, role, image)"] --> B["Update DOM text content"]
  B --> C["Validate Base64 image"]
  C -- "valid" --> D["Display image"]
  C -- "invalid" --> E["Show placeholder"]
  D --> F["Signal ready on load or error"]
  E --> F
Loading

File Walkthrough

Relevant files
Tests
1 files
main.test.ts
Add unit tests for settings and image handling                     
+115/-0 
Enhancement
3 files
main.ts
Implement app startup and image handling                                 
+79/-0   
style.css
Add responsive Tailwind CSS styles                                             
+129/-0 
index.html
Create HTML layout for greeting app                                           
+83/-0   
Documentation
1 files
README.md
Add README with usage and configuration                                   
+67/-0   
Configuration changes
3 files
package.json
Add scripts and dependencies                                                         
+35/-0   
screenly.yml
Add Edge App manifest configuration                                           
+39/-0   
screenly_qc.yml
Add QC manifest configuration                                                       
+39/-0   

nicomiguelino and others added 5 commits January 27, 2026 11:37
…lines

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…pp skill

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Create new Birthday Greeting Edge App
- Implement personalized greeting with name, role, and optional Base64 photo support
- Add test suite for settings retrieval and image handling
- Include deployment configuration and documentation

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Jan 28, 2026

PR Reviewer Guide 🔍

(Review updated until commit 56b1616)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Dependency Typo

The script uses npm-run-all2 which seems incorrect; consider replacing it with the standard npm-run-all package to ensure your build scripts run as expected.

"npm-run-all2": "^8.0.4",
Config Schema Mismatch

The display_errors setting is declared as type string but its help_text schema specifies a boolean property. Ensure the type definition and schema are consistent to avoid validation errors.

display_errors:
  type: string
  default_value: 'false'
  title: Display Errors
  optional: true
  help_text:
    properties:
      advanced: true
      help_text: For debugging purposes to display errors on the screen.
      type: boolean
Image Handling

formatBase64Image always prepends data:image/jpeg;base64,, potentially overriding the original image MIME type. Consider preserving the correct format (e.g., png, gif) when formatting pure Base64 input.

function formatBase64Image(str: string): string {
  if (str.startsWith('data:image/')) {
    return str
  }
  return `data:image/jpeg;base64,${str}`
}

@github-actions
Copy link

github-actions bot commented Jan 28, 2026

PR Code Suggestions ✨

Latest suggestions up to 56b1616
Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Attach image handlers before src

Assign the onload and onerror handlers before setting photoElement.src to ensure the
callbacks fire even if the image is cached. This guarantees signalReady() is always
called.

edge-apps/birthday-greeting/src/main.ts [52-64]

-photoElement.src = formatBase64Image(image)
-photoElement.classList.remove('hidden')
-placeholderElement.classList.add('hidden')
-
 photoElement.onload = () => {
   signalReady()
 }
 
 photoElement.onerror = () => {
   photoElement.classList.add('hidden')
   placeholderElement.classList.remove('hidden')
   signalReady()
 }
 
+photoElement.src = formatBase64Image(image)
+photoElement.classList.remove('hidden')
+placeholderElement.classList.add('hidden')
+
Suggestion importance[1-10]: 7

__

Why: Assigning onload and onerror before setting src prevents missing callbacks when the image is cached, ensuring signalReady() always fires.

Medium
General
Enforce proper base64 padding

Strengthen the pure Base64 validation by trimming whitespace once and checking that
the string length is a multiple of 4 to reject malformed input.

edge-apps/birthday-greeting/src/main.ts [19-20]

+const sanitized = str.replace(/\s/g, '')
 const pureBase64Pattern = /^[A-Za-z0-9+/]+=*$/
-return pureBase64Pattern.test(str.replace(/\s/g, ''))
+return pureBase64Pattern.test(sanitized) && sanitized.length % 4 === 0
Suggestion importance[1-10]: 5

__

Why: Adding a length check ensures the Base64 string’s length is a multiple of 4, improving validation to reject malformed input.

Low

Previous suggestions

Suggestions up to commit a397ecc
CategorySuggestion                                                                                                                                    Impact
Possible issue
Move image handlers before setting src

Assign the image load and error handlers before setting src to ensure the callbacks
fire even if the image is cached. This prevents the readiness signal from hanging
when the browser delivers the image immediately.

edge-apps/birthday-greeting/src/main.ts [51-65]

 if (isValidBase64Image(image)) {
-  photoElement.src = formatBase64Image(image)
-  photoElement.classList.remove('hidden')
-  placeholderElement.classList.add('hidden')
-
   photoElement.onload = () => {
     signalReady()
   }
-
   photoElement.onerror = () => {
     photoElement.classList.add('hidden')
     placeholderElement.classList.remove('hidden')
     signalReady()
   }
+
+  photoElement.src = formatBase64Image(image)
+  photoElement.classList.remove('hidden')
+  placeholderElement.classList.add('hidden')
 }
Suggestion importance[1-10]: 8

__

Why: Registering onload and onerror before setting src ensures the handlers fire even on cached images, preventing the readiness signal from hanging.

Medium
General
Enforce strict Base64 validation

Use a stricter Base64 validation regex to ensure correct padding and grouping,
preventing false positives from arbitrary strings. This ensures only properly
formatted Base64 is accepted.

edge-apps/birthday-greeting/src/main.ts [23-24]

-const pureBase64Pattern = /^[A-Za-z0-9+/]+=*$/
+const pureBase64Pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/
 return pureBase64Pattern.test(str.replace(/\s/g, ''))
Suggestion importance[1-10]: 5

__

Why: Using a stricter regex for Base64 enforces correct padding and grouping, improving validity checks with moderate impact on image handling.

Low

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 introduces a new Birthday Greeting Edge App designed for digital signage displays. The app provides personalized birthday messages featuring the person's name, role, and an optional photo, with a responsive design that adapts to various screen sizes.

Changes:

  • New edge app with personalized birthday greeting display
  • Support for Base64-encoded images with automatic fallback to placeholder
  • Comprehensive test suite covering settings retrieval and image validation
  • Deployment configuration and documentation

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
edge-apps/birthday-greeting/static/img/icon.svg App icon featuring a birthday cake design
edge-apps/birthday-greeting/src/main.ts Core app logic with image validation and ready signal handling
edge-apps/birthday-greeting/src/main.test.ts Test suite for settings and image handling
edge-apps/birthday-greeting/src/css/style.css Responsive styling with viewport-based sizing
edge-apps/birthday-greeting/screenly_qc.yml QC environment configuration
edge-apps/birthday-greeting/screenly.yml Production deployment configuration
edge-apps/birthday-greeting/package.json Dependencies and build scripts
edge-apps/birthday-greeting/index.html Main HTML structure with Screenly logo and greeting layout
edge-apps/birthday-greeting/bun.lock Dependency lock file
edge-apps/birthday-greeting/README.md Documentation with setup and configuration instructions

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

@nicomiguelino nicomiguelino changed the title feat: add birthday-greeting edge app with responsive design feat(birthday-greeting): add birthday-greeting edge app with responsive design Jan 28, 2026
@nicomiguelino nicomiguelino marked this pull request as ready for review January 28, 2026 03:08
@github-actions
Copy link

Persistent review updated to latest commit 56b1616

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 8 out of 10 changed files in this pull request and generated 5 comments.


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

nicomiguelino and others added 7 commits January 27, 2026 20:06
…-an-edge-app

- Remove code blocks (manifests, main.ts, test.ts, HTML, CSS) that are likely to change more frequently
- Add references to `edge-apps/qr-code/` as the primary template for directory structure
- Add link to `edge-apps/qr-code/screenly.yml` for manifest example
- Clarify that qr-code uses the library but features simpler implementation with lower code footprint
- Reorganize section titles for clarity ("Manifest Files" → "About the Manifest Files", add "About `index.html`")
- Improve HTML best practices with bullet-point formatting

This makes the skill more maintainable by referencing live examples that evolve with the codebase
rather than maintaining frozen code snippets.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Fixed several grammatical issues:
- Changed "Edge Apps directory" to "Edge App directory" for consistency
- Corrected pronoun agreement from "those" to "it" for the id field
- Added missing article "the" in README section
- Improved punctuation with comma before "as" clause

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add guidance to consult Figma designs before starting Edge App
implementation, including setup of Figma MCP server and extraction
of design tokens. Also improve wording by replacing "aforementioned"
with more concise "these".

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Base automatically changed from create-claude-skills to master January 28, 2026 16:50
nicomiguelino and others added 6 commits January 28, 2026 11:33
Attach event handlers before setting src attribute to avoid race condition
where cached images might load before handlers are attached. Also check
the complete property to handle synchronous loads.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…n `img` tags

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… images can be displayed properly

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Extract image functions to separate src/image.ts module
- Add tests covering isValidBase64Image() and formatBase64Image()
- Improve validation to require proper base64 format
- Tests cover valid data URIs, pure base64, and various invalid inputs

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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 10 out of 12 changed files in this pull request and generated 1 comment.


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

nicomiguelino and others added 6 commits January 28, 2026 15:54
…e signalReady calls

- Make image field required in both manifest files
- Refactor image loading logic with early returns to prevent nested conditionals
- Ensure signalReady() is called exactly once per execution path
- Throw errors for missing DOM elements or invalid image data
- Remove placeholder fallback since image is now required

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…file

- Move inline Screenly logo SVG from HTML to src/default-logo.ts
- Insert logo dynamically via JavaScript to keep HTML clean

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…d aspect ratio

- Convert all font-size px values to rem for better scalability
- Add intermediate breakpoints for 1921-2560px and 2561-3839px ranges
- Enforce consistent 13:15 aspect ratio for photo-frame
- Increase photo-frame width to 30vw for better visual balance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add orientation-specific media queries for landscape and portrait modes with optimized layouts, aspect ratios, and responsive typography for vertical displays.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants