-
-
Notifications
You must be signed in to change notification settings - Fork 654
style/improve-start-page #672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note
|
| Cohort / File(s) | Summary |
|---|---|
Documentation & Configuration CLAUDE.md, apps/web/project.json |
Added Angular coding standards documentation; increased anyComponentStyle budget from 8kb to 10kb for production and pwa configurations. |
macOS Platform Support apps/electron-backend/src/app/app.ts, apps/web/src/app/app.component.ts, apps/web/src/styles.scss |
Added macOS-specific window chrome configuration (titleBarStyle, titleBarOverlay), exposed isMacOS platform flag via HostBinding, and added macOS-scoped CSS padding adjustments. |
Header Component Redesign apps/web/src/app/shared/components/header/header.component.html, header.component.scss, header.component.ts |
Replaced legacy mat-toolbar with modern header structure featuring branded logo block with pulse animation, conditional search bar for home view, and refactored add-playlist action to use new AddPlaylistMenuComponent; extensive styling overrides including glass-morphism effects, animations, responsive breakpoints, and Material icon customizations. |
Add Playlist Menu Component libs/ui/components/src/lib/add-playlist-menu/* |
Created new standalone component with five playlist type options (file, url, text, xtream, stalker), mat-menu integration, and playlistTypeSelected output emitter; exported in barrel index. |
Recent Playlists Component libs/ui/components/src/lib/recent-playlists/recent-playlists.component.html, recent-playlists.component.scss, recent-playlists.component.ts |
Refactored to use input-based searchQueryInput and new playlistsData$ stream combining playlists with totalCount; added addPlaylistClicked output; removed search input UI and onSearchQueryUpdate/onSearchHotkey handlers; integrated EmptyStateComponent. |
Empty State Component libs/ui/components/src/lib/recent-playlists/empty-state/* |
Created new standalone component with dual-state rendering (welcome illustration with feature list vs. no-results state); includes AddPlaylistMenuComponent integration and comprehensive animations/styling for welcome and search-failure states. |
Playlist Item & Info Components libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss, playlist-info/playlist-info.component.html, playlist-info/playlist-info.component.ts |
Enhanced playlist-item with hover effects, improved status indicators, and responsive styling; added copy-to-clipboard URL functionality in playlist-info with snackbar feedback. |
Home Component apps/web/src/app/home/home.component.html, home.component.scss, home.component.ts |
Added MatDialog dependency, searchQuery signal, onSearchQueryChange/onAddPlaylist handlers, and wired header searchQuery output and recent-playlists addPlaylistClicked input; updated recent-playlists height calculation. |
Internationalization Restructuring apps/web/src/assets/i18n/{ar,ary,by,de,en,es,fr,ja,ko,nl,pl,pt,ru,tr,zhtw}.json |
Massive i18n reorganization introducing new top-level sections (SETTINGS, THEMES, CHANNELS, TOP_MENU, EPG, LANGUAGES, PORTALS, ABOUT) with nested content previously scattered across root or HOME blocks; restructured content varies by language but follows consistent modular patterns; added welcome/feature/no-results strings and expanded error/dialog messaging. |
Public Exports libs/ui/components/src/index.ts |
Added barrel export for new AddPlaylistMenuComponent. |
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~60 minutes
- i18n consistency across 15 language files: While restructuring patterns are similar, verifying structural alignment and translation completeness across all languages requires careful cross-file validation
- Component signal/input/output patterns: Verify proper Angular 16+ patterns in new components (AddPlaylistMenuComponent, EmptyStateComponent) and refactored recent-playlists
- Empty state conditional logic: Ensure welcome/no-results states render correctly based on playlists.empty and totalCount conditions
- Header styling complexity: Extensive CSS including glass-morphism effects, animations (fadeIn, slideUp, gridMove), responsive breakpoints (480px, 599px, 899px), and Material icon overrides via ::ng-deep
- Platform detection and macOS-specific logic: Verify isMacOS binding, platform-specific window chrome, and CSS padding adjustments work correctly
Possibly related PRs
- fix/m3u-auto-refresh-mechanism #648: Modifies recent-playlists UI components (playlist-item styles and playlist list behavior), indicating parallel work on the same component area.
Poem
🐰 A header blooms with modern grace,
Playlists welcome with open space,
New menus dance, translations gleam,
Empty states now live the dream,
macOS joins the hoppy team! 🎯✨
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title 'style/improve-start-page' accurately describes the main scope of the PR, which focuses on styling improvements to the home page start page and header components. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
|
View your CI Pipeline Execution ↗ for commit 3e2afe1
☁️ Nx Cloud last updated this comment at |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (9)
libs/ui/components/src/lib/recent-playlists/recent-playlists.component.scss (1)
16-16: Align.metacolor with app theme rather than OSprefers-color-scheme
prefers-color-scheme: lightmay diverge from the app’s own dark/light theme (e.g., user selects dark theme while OS is light). Consider driving.metacolor via your existing theme classes or CSS variables instead of the OS media query, so typography stays consistent with the selected app theme.Also applies to: 25-30
CLAUDE.md (1)
147-217: Modern Angular guidance is solid; consider adding version/legacy notesThe signal-based recommendations for queries, inputs/outputs, and control flow look correct and match current Angular patterns. To avoid confusion, you might briefly note the minimum Angular version these APIs require and that older parts of the codebase may still legitimately use decorator-based patterns until fully migrated.
If helpful, double-check your workspace’s Angular version and ensure all projects are on a version that supports
viewChild(),input(),output(), and the@if/@fortemplate syntax before enforcing this section strictly.libs/ui/components/src/lib/recent-playlists/playlist-info/playlist-info.component.html (1)
55-70: URL copy button wiring looks good; consider adding aria-labelThe suffix icon button correctly calls
copyUrl()and avoids interfering with form submission. For better accessibility, consider adding an explicit ARIA label, e.g.:<button mat-icon-button matSuffix type="button" (click)="copyUrl()" [matTooltip]="'HOME.PLAYLISTS.INFO_DIALOG.COPY_URL' | translate" [attr.aria-label]="'HOME.PLAYLISTS.INFO_DIALOG.COPY_URL' | translate" > <mat-icon>content_copy</mat-icon> </button>apps/web/src/app/app.component.ts (1)
1-2: TightenisMacOSHostBinding to explicitly return a booleanThe platform check is fine, but it’s worth making the getter explicitly boolean and slightly more defensive:
@HostBinding('class.macos-platform') get isMacOS(): boolean { return !!( typeof navigator !== 'undefined' && navigator.platform?.toLowerCase().includes('mac') && (window as any).electron ); }This keeps the CSS class binding unambiguous and avoids any non-boolean values leaking through the HostBinding.
Also applies to: 30-32
libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.html (1)
1-87: Empty-state flows are well structured; consider aria-hiding decorative SVGsThe welcome vs no-results branching, integration with
app-add-playlist-menu, andonAddPlaylist($event)hookup all look consistent and should work as intended for both first-run and filtered-empty states.Since the SVGs are decorative, you might want to explicitly hide them from assistive tech:
<svg class="illustration" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" > ... </svg>Same idea for the smaller no-results illustration.
libs/ui/components/src/lib/recent-playlists/recent-playlists.component.html (1)
3-15: Playlist empty-state gating and data binding look correctUsing
data.playlists.lengthplusdata.totalCountto choose between the welcome and no-results empty states is a good separation of first-run vs filtered-empty UX, and the switch todata.playlistsin the@forloop is consistent with that model.You can optionally remove
let last = $lastfrom the@forloop since it’s not used anymore, to keep the template slightly cleaner.Also applies to: 34-38, 48-49
libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.scss (1)
24-24: Consider using CSS variables for color values.Hardcoded color values like
#3b82f6,#60a5fa,#2563ebappear throughout the file. Using CSS variables (custom properties) would improve maintainability, enable easier theming, and reduce duplication.Example approach:
:root { --color-primary: #3b82f6; --color-primary-light: #60a5fa; --color-primary-dark: #2563eb; } .title { background: linear-gradient(135deg, var(--color-primary-light) 0%, var(--color-primary) 50%, var(--color-primary-dark) 100%); // ... }This would centralize color definitions and make future theme adjustments simpler.
Also applies to: 54-75, 100-102, 144-144
apps/web/src/assets/i18n/ko.json (1)
1-254: Good restructuring; verify incomplete translations.The Korean i18n file has been successfully restructured to match the modular pattern. However, there are a few English fallback strings that may need Korean translations:
- Line 10: "Import as text"
- Line 91: "Show subtitles"
- Line 138: "Open Multi-EPG view"
- Line 143-144: "Live now", "Live stream"
- Line 181-192: Several entries in MENU section
These may be intentional or may need translation updates.
apps/web/src/app/shared/components/header/header.component.scss (1)
399-474: Consider CSS custom properties to reduce color duplication.The styling quality is excellent, but the repeated rgba color values throughout the file could benefit from CSS custom properties for maintainability.
Consider defining color variables at the top:
:host { --header-text: rgba(255, 255, 255, 0.95); --header-text-dim: rgba(255, 255, 255, 0.85); --header-border: rgba(255, 255, 255, 0.06); --accent-purple: rgba(139, 92, 246, 1); --accent-purple-dim: rgba(139, 92, 246, 0.85); // ... etc }Then use them throughout:
.search-icon { color: var(--header-text-dim); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (38)
CLAUDE.md(1 hunks)apps/electron-backend/src/app/app.ts(1 hunks)apps/web/project.json(2 hunks)apps/web/src/app/app.component.ts(2 hunks)apps/web/src/app/home/home.component.html(1 hunks)apps/web/src/app/home/home.component.scss(1 hunks)apps/web/src/app/home/home.component.ts(2 hunks)apps/web/src/app/shared/components/header/header.component.html(2 hunks)apps/web/src/app/shared/components/header/header.component.scss(1 hunks)apps/web/src/app/shared/components/header/header.component.ts(2 hunks)apps/web/src/assets/i18n/ar.json(1 hunks)apps/web/src/assets/i18n/ary.json(1 hunks)apps/web/src/assets/i18n/by.json(1 hunks)apps/web/src/assets/i18n/de.json(2 hunks)apps/web/src/assets/i18n/en.json(3 hunks)apps/web/src/assets/i18n/es.json(1 hunks)apps/web/src/assets/i18n/fr.json(1 hunks)apps/web/src/assets/i18n/ja.json(1 hunks)apps/web/src/assets/i18n/ko.json(1 hunks)apps/web/src/assets/i18n/nl.json(1 hunks)apps/web/src/assets/i18n/pl.json(1 hunks)apps/web/src/assets/i18n/pt.json(1 hunks)apps/web/src/assets/i18n/ru.json(2 hunks)apps/web/src/assets/i18n/tr.json(1 hunks)apps/web/src/assets/i18n/zhtw.json(1 hunks)apps/web/src/styles.scss(1 hunks)libs/ui/components/src/index.ts(1 hunks)libs/ui/components/src/lib/add-playlist-menu/add-playlist-menu.component.html(1 hunks)libs/ui/components/src/lib/add-playlist-menu/add-playlist-menu.component.ts(1 hunks)libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.html(1 hunks)libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.scss(1 hunks)libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.ts(1 hunks)libs/ui/components/src/lib/recent-playlists/playlist-info/playlist-info.component.html(1 hunks)libs/ui/components/src/lib/recent-playlists/playlist-info/playlist-info.component.ts(4 hunks)libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss(6 hunks)libs/ui/components/src/lib/recent-playlists/recent-playlists.component.html(3 hunks)libs/ui/components/src/lib/recent-playlists/recent-playlists.component.scss(2 hunks)libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts(6 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts (1)
apps/web/src/app/shared/components/add-playlist/add-playlist-dialog.component.ts (1)
PlaylistType(21-21)
apps/web/src/app/home/home.component.ts (1)
apps/web/src/app/shared/components/add-playlist/add-playlist-dialog.component.ts (1)
PlaylistType(21-21)
🔇 Additional comments (40)
apps/web/project.json (1)
43-43: The 2kb budget increase is justified by the extensive header styling.The header component's 522-line SCSS file includes legitimate styling additions: ambient glow animations (
headerAmbience,logoGlowkeyframes), glass-morphism effects, detailed state transitions (hover, focus, active), gradients, Material Design overrides, and responsive breakpoints. This scope reasonably accounts for the 10kb limit. The warning threshold remains at 4kb, providing adequate early feedback for future growth.apps/web/src/styles.scss (1)
4-15: macOS-specific spacing is well-scoped and non-invasiveThe new padding rules are narrowly scoped to
app-root.macos-platformand should only affect the intended macOS layout without impacting other platforms.apps/web/src/assets/i18n/de.json (1)
61-68: New HOME playlist onboarding/empty-state strings look consistentThe added
WELCOME_*andNO_RESULTS_*keys underHOME.PLAYLISTSand the simplifiedSETTINGS.TITLEare consistent with the structure used in other locales and should integrate cleanly with the new home UI.Also applies to: 196-196
apps/electron-backend/src/app/app.ts (1)
82-87: macOS window chrome options are correctly gatedThe
titleBarStyle: 'hidden'andtitleBarOverlay: trueoptions are cleanly guarded by thedarwinplatform check and won’t affect other platforms; the spread placement within the options object is safe.If you haven’t already, quickly confirm against the Electron version in use that
titleBarOverlay: truewithtitleBarStyle: 'hidden'matches the visual you want on macOS (color/height of the overlay can be tuned further if needed).apps/web/src/assets/i18n/ru.json (1)
18-25: Russian onboarding/empty-state additions are consistent and clearThe new
WELCOME_*andNO_RESULTS_*playlist messages read well and match the new home UX semantics, and simplifyingSETTINGS.TITLEto just “Настройки” is appropriate for UI labels.Also applies to: 126-126
apps/web/src/assets/i18n/by.json (1)
1-286: LGTM! Clean i18n restructuring.The Belarusian translation file has been successfully restructured into a modular format with proper nesting. All translation values appear complete and consistent with the PR's i18n refactoring pattern.
apps/web/src/assets/i18n/tr.json (1)
1-306: LGTM! Comprehensive Turkish translations.The Turkish translation file has been successfully restructured with all sections properly translated. The file includes additional features like remote control settings and CORS notes, all with complete Turkish translations.
apps/web/src/assets/i18n/ary.json (1)
1-318: LGTM! Complete Moroccan Arabic translations.The Moroccan Arabic (Darija) translation file is well-structured with comprehensive translations including newer features like sorting options and playlist export feedback. All values are properly translated.
apps/web/src/app/home/home.component.scss (1)
1-4: LGTM! Height calculation adjusted for new header.The height calculation has been updated from
calc(100vh - 100px)tocalc(100vh - 71px), providing 29px more vertical space for the recent playlists area. This aligns with the PR's header modernization and toolbar sizing improvements.libs/ui/components/src/lib/add-playlist-menu/add-playlist-menu.component.html (1)
1-43: LGTM! Well-structured menu component.The add-playlist menu template is well-implemented with:
- Proper Material Design components and patterns
- Good accessibility via aria-labels
- Consistent internationalization using translation pipe
- Semantic icons for each action type
- Logical grouping with divider separating standard uploads from specialized portals
libs/ui/components/src/index.ts (1)
1-1: LGTM! Public API export added.The new
AddPlaylistMenuComponenthas been properly exported through the barrel index, making it available as part of the public UI components library API. The export follows the established pattern and is correctly positioned.apps/web/src/app/home/home.component.html (1)
1-10: Search and add-playlist wiring between header and recent playlists looks correctThe header’s
searchQueryoutput feeding asearchQuerysignal and then intoapp-recent-playlists, plus theaddPlaylistClickedhandler, forms a clear and consistent data flow. No issues from this template change.libs/ui/components/src/lib/recent-playlists/playlist-info/playlist-info.component.ts (1)
1-1: Clipboard-based URL copy is correctly implemented; optional failure feedbackThe clipboard integration is wired properly:
ClipboardModuleis imported, andClipboardis injected.copyUrl()safely reads theurlcontrol, guards on a truthy value, and only shows a snackbar whenclipboard.copy(url)reports success.If you want to improve UX further, you could also surface feedback when there is no URL or when the copy call fails (e.g., show a brief error snackbar), but the current behavior is already safe and functional.
Also applies to: 11-11, 17-17, 36-47, 50-50, 225-240
apps/web/src/app/home/home.component.ts (1)
1-6: Home search signal and add-playlist dialog handlers are well wiredUsing a
signal<string>forsearchQueryand updating it viaonSearchQueryChangefits nicely with thesearchQuery()binding in the template. TheonAddPlaylisthandler opening the add-playlist dialog with aPlaylistTypepayload is also consistent with the rest of the flow.Also applies to: 14-31
apps/web/src/app/shared/components/header/header.component.ts (4)
39-41: LGTM! Clean HostBinding pattern for conditional styling.The use of
@HostBindingwith a getter to toggle thehome-headerclass based on theisHomeproperty is idiomatic and allows for clean separation between home and non-home header styling.
54-54: LGTM! Clean use of Angular's modern output API.The
searchQueryoutput is properly typed and enables parent components to react to search input changes, which aligns with the PR's goal of making the header more pluggable.
167-169: LGTM! Clean event emission pattern.The
onSearchQueryUpdatemethod provides a clear interface for emitting search query changes, following Angular conventions with appropriate typing.
50-50: Add explicit type for better type safety.The
addPlaylistMenuComponentis currently typed asany, which loses type safety benefits. The return type ofviewChild.requiredshould be explicitly typed.Apply this diff to add the proper type:
- readonly addPlaylistMenuComponent = viewChild.required(AddPlaylistMenuComponent); + readonly addPlaylistMenuComponent = viewChild.required<AddPlaylistMenuComponent>(AddPlaylistMenuComponent);Or alternatively, let TypeScript infer the type by removing the explicit
anyannotation if it exists in your source.Likely an incorrect or invalid review comment.
libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.scss (1)
1-486: Excellent comprehensive styling with modern CSS patterns.The styling demonstrates:
- Smooth animations that enhance UX (fadeIn, slideUp, floatIn, gridMove)
- Comprehensive responsive design with multiple breakpoints (max-width: 480px, max-height: 700px, 550px)
- Thoughtful light theme support via
@media (prefers-color-scheme: light)- Clear organization and naming conventions
The implementation creates a polished, modern UI for the empty state component.
apps/web/src/assets/i18n/pl.json (1)
1-318: LGTM! Well-organized i18n restructuring.The Polish translations have been successfully reorganized into a hierarchical structure with clear top-level sections (HOME, SETTINGS, THEMES, CHANNELS, TOP_MENU, EPG, etc.). This modular approach improves maintainability and aligns with the broader i18n restructuring across other language files in the PR.
libs/ui/components/src/lib/recent-playlists/playlist-item/playlist-item.component.scss (1)
1-185: LGTM! Polished styling improvements for playlist items.The updates enhance the playlist item UI with:
- Smooth transitions using cubic-bezier easing functions
- Improved hover states for both dark and light themes
- Enhanced drag-and-drop visual feedback with layered shadows
- Refined action button interactions with scale transforms and opacity transitions
- Proper status indicators with glowing effects
- Thoughtful responsive behavior that hides secondary icons on mobile
These changes align well with the PR's goal of modernizing and polishing the UI.
apps/web/src/assets/i18n/nl.json (1)
1-318: LGTM! Consistent i18n restructuring.The Dutch translations follow the same hierarchical restructuring pattern as other language files in the PR, with clear modular sections. The organization improves maintainability and provides a consistent structure across all supported languages.
libs/ui/components/src/lib/add-playlist-menu/add-playlist-menu.component.ts (2)
7-7: LGTM! Well-defined type for playlist variants.The
PlaylistTypeunion type clearly defines the supported playlist types and is appropriately exported for use by consuming components likeHeaderComponentandEmptyStateComponent.
9-22: LGTM! Clean, reusable component design.The
AddPlaylistMenuComponentdemonstrates excellent component design:
- Standalone architecture with focused imports
- Modern Angular APIs (
viewChild.required,output)- Clear single responsibility (menu presentation and type selection)
- Proper typing with generic parameters
- Reusable across multiple contexts (header, empty state)
The implementation is clean and follows Angular best practices.
libs/ui/components/src/lib/recent-playlists/empty-state/empty-state.component.ts (2)
8-8: LGTM! Clear type definition for empty states.The
EmptyStateTypeunion type clearly distinguishes between the 'welcome' state (first-time user) and 'no-results' state (search/filter returned nothing), making the component's API intuitive.
10-24: LGTM! Well-structured component with proper composition.The
EmptyStateComponentdemonstrates good component design:
- Proper composition with
AddPlaylistMenuComponentviaviewChild- Required input ensures the component always has a defined state
- Type-safe output that matches the
PlaylistTypefrom the menu component- Clean integration pattern that promotes reusability
The component follows Angular best practices and integrates cleanly with the new menu component.
apps/web/src/assets/i18n/en.json (3)
18-25: LGTM! Welcome onboarding strings enhance UX.The new welcome messages and feature highlights provide clear guidance for first-time users. The copy is professional and informative.
56-58: LGTM! URL copy functionality strings are clear.The new translation keys for URL clipboard operations are concise and provide appropriate user feedback.
128-128: LGTM! Settings title simplification.Removing the application name suffix from the settings title is cleaner and follows common UI patterns.
libs/ui/components/src/lib/recent-playlists/recent-playlists.component.ts (4)
59-76: LGTM! Clean refactor from ViewChild to signal-based input.The migration from ViewChild-based search query binding to an input signal with a constructor effect is a good modernization. The effect properly syncs the input to the internal BehaviorSubject.
61-61: LGTM! New output enables parent component communication.The new
addPlaylistClickedoutput properly enables the parent component to react to add-playlist menu selections.
155-157: LGTM! Simple delegation to output.The
onAddPlaylistmethod correctly emits the playlist type through the output.
78-122: Verify template and consumer compatibility with playlistsData$ structure change.The renamed
playlistsData$now emits an object containing bothplaylistsandtotalCountinstead of just the playlists array. This is a breaking change for the template and any consumers.This issue requires manual verification as the specific component file path and template cannot be located in the repository. To properly validate the breaking change claim, please verify:
- That the template correctly accesses the new structure (
playlistsData$ | async as datathen usesdata.playlistsanddata.totalCount)- That any parent components or other consumers consuming this component through an input binding have been updated to handle the new observable structure
- Whether the original code previously returned just the array directly and this change genuinely breaks existing consumers
apps/web/src/app/shared/components/header/header.component.scss (6)
6-35: LGTM! Clean modern header foundation.The
.modern-headerprovides a solid foundation with proper flexbox layout, Electron drag region support, and subtle depth effects.
37-87: LGTM! Elegant home-header ambient effects.The home-header variant with animated ambient glow creates a polished, distinctive appearance. The
headerAmbienceanimation is smooth and subtle.
89-132: LGTM! Glass-morphism brand block is well-executed.The brand block styling with backdrop-filter, subtle borders, and hover transitions creates an elegant glass effect. The home-header variant with purple accents fits the design system.
227-284: LGTM! Search container glass-morphism with great focus states.The search container has excellent focus-within states with proper visual feedback. The purple accent on home-header maintains consistency. Transitions are smooth and accessible.
477-522: LGTM! Well-considered responsive breakpoints.The responsive adjustments at 899px and 599px appropriately scale down the header for smaller screens while maintaining readability and usability.
227-338: The search input text colorrgba(255, 255, 255, 0.95)on the dark background#131316produces an effective contrast ratio of approximately 16.7:1, which far exceeds the WCAG AA requirement of 4.5:1 for normal text. No contrast compliance issue exists with the search input text.Likely an incorrect or invalid review comment.
apps/web/src/assets/i18n/ja.json (1)
1-306: LGTM! Consistent restructuring across locales.The Japanese i18n file follows the same hierarchical restructuring as the French file, maintaining consistency across locales. The Japanese translations are preserved while adopting the new modular structure.
Note: The verification script for
fr.jsonwill also validate usage of keys in this file.
Enhance the header component to support a distinct "home" appearance and emit search updates. Add a HostBinding that toggles a home-header class from the isHome flag so styles can target the home state. Expose a searchQuery output and wire an onSearchQueryUpdate method to emit the search text, enabling parent components to react to user searches. Refactor imports to include HostBinding and output. Tidy toolbar metrics and adjust element sizing for a compact brand block and pulsing logo. Introduce comprehensive SCSS for the home header: - gradient background, animated glow overlay, and edge accent - brand block styling with blur, border, hover states and box-shadow - logo sizing, pulse animation and responsive tweaks - reduced toolbar height and overall visual polish These changes separate home-specific styling from the default header appearance and provide a programmatic hook for search interactions.
Update header component UI and streamline imports. - Remove MatToolbarModule import and module list entry because the toolbar styling is handled by local SCSS and the Angular Material toolbar is no longer required. - Rewrite header SCSS to introduce a .modern-header wrapper with consistent sizing, padding, alignment and a subtle bottom border. - Add layered ambient and depth effects: refined ::before ambient gradient (headerAmbience), ::after bottom accent, and adjusted keyframes for a gentler motion. - Refine home-header styles to target .modern-header and tune colors and gradients for a cohesive dark theme. - Rework .brand-block visuals: lighter glass effect, adjusted radii, blur, borders, hover transform, and shadowing for a modern elevated look. - Minor cleanup: remove legacy variables and comments; improve box-sizing, layout, and pointer-event handling to ensure expected interaction regions. These changes modernize the header's visual design, improve layout consistency across pages, and remove an unnecessary module import.
Update recent playlists styles to improve visuals, hover feedback, and theme adaptability. Key changes: - Hide horizontal overflow on playlists list to avoid scroll bleed. - Add rounded corners, subtle transitions, and hover background for mat-list-item; include light theme hover variant. - Reduce drag preview radius, replace shadow with layered shadows, increase opacity, and extend drag animation duration for smoother interactions. - Adjust responsive selector formatting. - Add transitions and hover scaling to action buttons, plus light theme variant; improve icon opacity transitions. - Improve icon container behavior and upload-type-icon visibility on hover. - Restyle status dot and state shadows, tweak unavailable color. - Restyle auto-refresh indicator with shadow, rotation on hover, and light theme background. - Minor spacing and layout tweaks across SCSS. Code imports: - Add Clipboard and ClipboardModule import and include MatIconButton and MatTooltip references in playlist-info component to support new copy/tooltip UI affordances. These changes enhance UX polish, accessibility of interactive affordances, and light/dark theme consistency.
- Shorten German settings TITLE from "Einstellungen / IPTVnator" to "Einstellungen" to remove redundant app name and keep UI labels concise. - Reformat and normalize Korean i18n JSON indentation and structure to match expected layout (consistent nesting and whitespace). - Reintroduce missing HOME -> nested sections (TABS, PLAYLISTS, FILE_UPLOAD, URL_UPLOAD, TEXT_IMPORT, STALKER_PORTAL, XTREAM_PLAYLIST) in ko.json to restore previously collapsed keys and ensure all keys are present for runtime lookup. - Fix several untranslated/placeholder labels and ensure key presence for dialogs, validations and UI strings so translations load consistently across components.
Add new strings for the PLAYLIST view across English, Spanish, French, German, and translations. The additions include a welcome title description, a prompt to the first playlist, feature labels for supported playlist types (MU/M3U, Xtream Codes Stalker), and "no results title and description to clarify search/filter . These changes improve the onboarding experience new users and giveclearer feedback when searches return no. They also ize feature labels across languages to communicate supported playlist formats
Add a new EmptyState component and template for the recent-playlists
widget, providing two visual states: "welcome" and "no-results".
- Create empty-state.component.html with:
- a welcome illustration (monitor + WiFi) and content for first-time
users, including translated title/description, add-playlist action
button and features list.
- a no-results illustration (magnifying glass + box) and compact
content for empty search/results.
- conditional rendering based on type() to switch states.
- Start empty-state.component.ts with type definition and imports for
Angular Material and translation; wire up AddPlaylistMenu types.
This implements the UI for when there are no recent playlists and
provides the primary CTA to add the first playlist, improving onboarding
and empty-state UX.
Raise the maximumError for anyComponentStyle from 8kb to kb in the web app build configuration. This relaxes the build-size enforcement for component styles to accommodate slightly larger CSS bundles and avoid spurious build failures.
Introduce a reusable AddPlaylistMenuComponent that provides a Material menu with options to add playlists via file, URL, text, Xtream or Stalker portal. Define a PlaylistType union and expose a playlistTypeSelected output so parent components can react to the selected import type. - Add component TypeScript with Angular metadata and required Material imports. - Add template with accessible menu items, icons, translation keys and click handlers that emit the selected PlaylistType. - Organize menu items with a divider to separate common file/URL/text options from provider-specific imports. This adds a focused UI building block for playlist import flows and standardizes how import type selection is communicated to parent scopes.
Introduce explicit empty-state handling in RecentPlaylists: - Replace previous direct rendering of an empty mat-list item with app-empty-state for two cases: a global "welcome" state when no playlists exist at all, and a "no-results" state when filters/search return nothing. This clarifies UX and provides a CTA for adding playlists in the welcome state. - Change playlist data binding from playlists$ to playlistsData$ and adapt loops and accessors to data.playlists / data.totalCount. - Keep existing global favorites item and playlist-item rendering. Wire up addPlaylist event and components: - Add addPlaylistClicked output to RecentPlaylists component and forward the event from the home component so the parent can open the add-playlist flow. - Import EmptyStateComponent and PlaylistType types used by the new output. Minor cleanup and imports: - Reformat some imports and add tap to RxJS imports. - Adjust template structure and placeholders for deferred loading.
Add macOS-specific title bar settings to the Electron main window creation so the app uses a hidden title bar with an overlay on Darwin. This ensures a more native, modern appearance on macOS while keeping existing minimum size and saved bounds behavior unchanged.
Add app-region: drag to container and header elements and app-region: no-drag to interactive controls multiple components so the Tauri window dragging behaves correctly while keeping buttons and form controls clickable. Expand header search max width from 500px to 800px to give more room on larger screens. Clean up and restyle video-player toolbar toolbar primary colors and unify toolbar spacing. Files changed include navigation, sidebar, header, main containers, live-stream layout, navigation-bar, stalker container, and video-player toolbar. These changes improve window drag UX on desktop and refine toolbar/header appearance.
Add new English keys for remote control URL and QR code to support remote-control features in the settings UI. Extend French locale with many missing and corrected translations: add "Playlists" root entry, Xtream/Stalker import labels, UI copy improvements (e.g. "Chaînes", grammar fixes), new playlist export/copy messages, search/auto-refresh labels, and removal success message. Fix several typos and phrasing in French strings (IPTV, chaînes, ajouter(e), requièrent). These changes enable new remote-control functionality and improve UX for French users by completing and correcting the translations.
Add an isElectron flag to PlaylistItemComponent and conditionally render the refresh button only when running inside Electron. This prevents exposing the server refresh action in non-Electron (environments like the browser) where window.electron is unavailable and the feature is not supported. Update ensures safer behavior by checking !!window.electron in the component and using that value in the template to guard the UI.
Add support for displaying local remote-control URLs and QR code in the Settings UI, including styles for URL list, row layout, monospaced links, and a QR container. Expose a new global API signature getLocalIpAddresses for retrieving local IPs. Fix several UI issues: - Correct typo in header method name (opedAddPlaylistDialog -> openAddPlaylistDialog). - Fix malformed GitHub URL and collapse img tag formatting. - Reformat imports and viewChild usage for readability. Change local development backend URL to localhost:3000 in the local environment to point to the running local API during development. These changes improve developer ergonomics (local backend), add a remote control discovery UX for users on the same network, and tidy up header bugs and formatting.
68005ae to
3e2afe1
Compare
Summary
Changes
Why
Notes
Summary by CodeRabbit
New Features
UI/UX Improvements
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.