mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
style(recent-playlists): refine styles and add clipboard imports
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.
This commit is contained in:
1 parent
9238fc8d86
commit
5a453a3f40
4 files changed
+120
-9
No files matched your search
@@ -58,6 +58,15 @@
|
||||
'HOME.PLAYLISTS.INFO_DIALOG.FROM_URL' | translate
|
||||
}}</mat-label>
|
||||
<input matInput formControlName="url" />
|
||||
<button
|
||||
mat-icon-button
|
||||
matSuffix
|
||||
type="button"
|
||||
(click)="copyUrl()"
|
||||
[matTooltip]="'HOME.PLAYLISTS.INFO_DIALOG.COPY_URL' | translate"
|
||||
>
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (playlist.filename) {
|
||||
|
||||
+24
-1
@@ -1,3 +1,4 @@
|
||||
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import {
|
||||
@@ -7,12 +8,13 @@ import {
|
||||
UntypedFormGroup,
|
||||
Validators,
|
||||
} from '@angular/forms';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { MatButton, MatIconButton } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import * as PlaylistActions from 'm3u-state';
|
||||
@@ -32,16 +34,20 @@ import { Playlist, PlaylistMeta } from 'shared-interfaces';
|
||||
],
|
||||
providers: [DatePipe],
|
||||
imports: [
|
||||
ClipboardModule,
|
||||
MatButton,
|
||||
MatCheckboxModule,
|
||||
MatDialogModule,
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
MatInputModule,
|
||||
MatTooltip,
|
||||
ReactiveFormsModule,
|
||||
TranslatePipe,
|
||||
],
|
||||
})
|
||||
export class PlaylistInfoComponent {
|
||||
private clipboard = inject(Clipboard);
|
||||
private datePipe = inject(DatePipe);
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
private playlistsService = inject(PlaylistsService);
|
||||
@@ -215,4 +221,21 @@ export class PlaylistInfoComponent {
|
||||
document.body.removeChild(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy URL to clipboard
|
||||
*/
|
||||
copyUrl(): void {
|
||||
const url = this.playlistDetails.get('url')?.value;
|
||||
if (url) {
|
||||
const success = this.clipboard.copy(url);
|
||||
if (success) {
|
||||
this.snackBar.open(
|
||||
this.translate.instant('HOME.PLAYLISTS.INFO_DIALOG.URL_COPIED'),
|
||||
this.translate.instant('CLOSE'),
|
||||
{ duration: 2000 }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
-8
@@ -1,5 +1,19 @@
|
||||
mat-list-item {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border-radius: 12px;
|
||||
margin: 2px 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.03) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Light theme hover
|
||||
@media (prefers-color-scheme: light) {
|
||||
mat-list-item:hover {
|
||||
background-color: rgba(0, 0, 0, 0.04) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-list-base {
|
||||
@@ -12,10 +26,21 @@ mat-list-item {
|
||||
margin-top: 2px !important;
|
||||
}
|
||||
|
||||
// Light theme
|
||||
@media (prefers-color-scheme: light) {
|
||||
.meta {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.cdk-drag-preview {
|
||||
box-sizing: border-box;
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 5px 5px -3px rgb(0 0 0 / 20%), 0 8px 10px 1px rgba(58, 58, 58, 0.14), 0 3px 14px 2px rgb(0 0 0 / 12%);
|
||||
border-radius: 12px;
|
||||
box-shadow:
|
||||
0 8px 24px rgba(0, 0, 0, 0.25),
|
||||
0 4px 12px rgba(0, 0, 0, 0.15),
|
||||
0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.cdk-drag-placeholder {
|
||||
@@ -23,7 +48,7 @@ mat-list-item {
|
||||
}
|
||||
|
||||
.cdk-drag-animating {
|
||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||
transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.drag-icon {
|
||||
@@ -33,7 +58,7 @@ mat-list-item {
|
||||
|
||||
::ng-deep {
|
||||
@media only screen and (max-width: 480px) {
|
||||
.main-container {
|
||||
.main-container {
|
||||
.favorites-icon,
|
||||
.upload-type-icon,
|
||||
.refresh-btn,
|
||||
@@ -51,11 +76,45 @@ mat-list-item {
|
||||
|
||||
.action-buttons {
|
||||
align-self: center !important;
|
||||
|
||||
button {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.06) !important;
|
||||
transform: scale(1.05);
|
||||
|
||||
mat-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
opacity: 0.85;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Light theme action buttons
|
||||
@media (prefers-color-scheme: light) {
|
||||
.action-buttons button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.04) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
|
||||
.upload-type-icon {
|
||||
opacity: 0.75;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
mat-list-item:hover & .upload-type-icon {
|
||||
opacity: 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
@@ -65,23 +124,28 @@ mat-list-item {
|
||||
border-radius: 50%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 1px solid var(--background-color, #fff);
|
||||
border: 2px solid var(--background-color, #131316);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
background-color: #4caf50;
|
||||
box-shadow: 0 0 8px rgba(76, 175, 80, 0.4);
|
||||
}
|
||||
|
||||
.status-inactive {
|
||||
background-color: #f44336;
|
||||
box-shadow: 0 0 8px rgba(244, 67, 54, 0.4);
|
||||
}
|
||||
|
||||
.status-expired {
|
||||
background-color: #ff9800;
|
||||
box-shadow: 0 0 8px rgba(255, 152, 0, 0.4);
|
||||
}
|
||||
|
||||
.status-unavailable {
|
||||
background-color: #444444;
|
||||
background-color: #666666;
|
||||
}
|
||||
|
||||
.auto-refresh-indicator {
|
||||
@@ -92,11 +156,25 @@ mat-list-item {
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
color: #4caf50;
|
||||
background-color: var(--background-color, #fff);
|
||||
background-color: var(--background-color, #131316);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
mat-list-item:hover & {
|
||||
color: #66bb6a;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
// Light theme auto-refresh indicator
|
||||
@media (prefers-color-scheme: light) {
|
||||
.auto-refresh-indicator {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
@@ -104,4 +182,4 @@ mat-list-item {
|
||||
.icon-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
.playlists-list {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.meta {
|
||||
|
||||
Reference in new issue
Block a user