aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-03-15 14:20:26 +0100
committerChocobozzz <me@florianbigard.com>2023-03-15 14:28:27 +0100
commitdc9c9500bf5f0fd66906576ee3df4f1c49a1871d (patch)
tree347853ac17beb366bac111e3bc3e3acae31ca267 /client
parent5ccf98a4ecc39d1b50df5b748e885683f71276a9 (diff)
downloadPeerTube-dc9c9500bf5f0fd66906576ee3df4f1c49a1871d.tar.gz
PeerTube-dc9c9500bf5f0fd66906576ee3df4f1c49a1871d.tar.zst
PeerTube-dc9c9500bf5f0fd66906576ee3df4f1c49a1871d.zip
Improve accessibility
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+search/search.component.html2
-rw-r--r--client/src/app/app.component.html8
-rw-r--r--client/src/app/app.component.ts8
-rw-r--r--client/src/app/menu/menu.component.html16
-rw-r--r--client/src/app/menu/menu.component.scss2
-rw-r--r--client/src/app/menu/notification.component.html7
-rw-r--r--client/src/app/shared/shared-forms/markdown-textarea.component.html14
-rw-r--r--client/src/app/shared/shared-forms/markdown-textarea.component.scss13
-rw-r--r--client/src/app/shared/shared-instance/instance-about-accordion.component.html2
-rw-r--r--client/src/app/shared/shared-instance/instance-about-accordion.component.scss3
-rw-r--r--client/src/app/shared/shared-main/angular/link.component.scss2
-rw-r--r--client/src/app/shared/shared-main/angular/link.component.ts9
-rw-r--r--client/src/app/shared/shared-main/feeds/feed.component.html4
-rw-r--r--client/src/app/shared/shared-main/feeds/feed.component.scss8
-rw-r--r--client/src/app/shared/shared-main/misc/help.component.html8
-rw-r--r--client/src/app/shared/shared-main/misc/help.component.scss6
-rw-r--r--client/src/app/shared/shared-share-modal/video-share.component.html141
-rw-r--r--client/src/app/shared/shared-share-modal/video-share.component.scss5
-rw-r--r--client/src/app/shared/shared-thumbnail/video-thumbnail.component.html4
-rw-r--r--client/src/app/shared/shared-video-miniature/video-download.component.html2
-rw-r--r--client/src/app/shared/shared-video-miniature/video-filters-header.component.html8
-rw-r--r--client/src/app/shared/shared-video-miniature/video-filters-header.component.scss4
-rw-r--r--client/src/app/shared/shared-video-miniature/video-miniature.component.html6
-rw-r--r--client/src/app/shared/shared-video-miniature/video-miniature.component.scss2
-rw-r--r--client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.html6
-rw-r--r--client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.scss2
-rw-r--r--client/src/sass/bootstrap.scss20
-rw-r--r--client/src/sass/class-helpers/_common.scss24
-rw-r--r--client/src/sass/class-helpers/_text.scss47
-rw-r--r--client/src/sass/class-helpers/index.scss1
-rw-r--r--client/src/sass/include/_bootstrap-variables.scss1
-rw-r--r--client/src/sass/include/_miniature.scss2
-rw-r--r--client/src/sass/include/_mixins.scss19
-rw-r--r--client/src/sass/ng-select.scss3
34 files changed, 200 insertions, 209 deletions
diff --git a/client/src/app/+search/search.component.html b/client/src/app/+search/search.component.html
index c07dbab08..2530c87b7 100644
--- a/client/src/app/+search/search.component.html
+++ b/client/src/app/+search/search.component.html
@@ -22,7 +22,7 @@
22 </div> 22 </div>
23 </div> 23 </div>
24 24
25 <div class="results-filter collapse-transition" [ngbCollapse]="isSearchFilterCollapsed"> 25 <div class="results-filter" [ngbCollapse]="isSearchFilterCollapsed" [animation]="true">
26 <my-search-filters [advancedSearch]="advancedSearch" (filtered)="onFiltered()"></my-search-filters> 26 <my-search-filters [advancedSearch]="advancedSearch" (filtered)="onFiltered()"></my-search-filters>
27 27
28 <div *ngIf="error" class="alert alert-danger">{{ error }}</div> 28 <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index 6a833b039..5fefffaf4 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -6,9 +6,11 @@
6 <div class="root-header"> 6 <div class="root-header">
7 7
8 <div class="top-left-block"> 8 <div class="top-left-block">
9 <span class="icon icon-menu" role="button" [title]="getToggleTitle()" (click)="menu.toggleMenu()"></span> 9 <span role="button" tabindex="0" [title]="getToggleTitle()" (click)="menu.toggleMenu()" (keyup.enter)="menu.toggleMenu()">
10 <span class="icon icon-menu"></span>
11 </span>
10 12
11 <a class="peertube-title c-hand" (click)="goToDefaultRoute()"> 13 <a class="peertube-title c-hand" [routerLink]="getDefaultRoute()">
12 <span class="icon icon-logo"></span> 14 <span class="icon icon-logo"></span>
13 <span class="instance-name">{{ instanceName }}</span> 15 <span class="instance-name">{{ instanceName }}</span>
14 </a> 16 </a>
@@ -22,7 +24,7 @@
22 <div class="sub-header-container"> 24 <div class="sub-header-container">
23 <my-menu *ngIf="menu.isMenuDisplayed"></my-menu> 25 <my-menu *ngIf="menu.isMenuDisplayed"></my-menu>
24 26
25 <div id="content" tabindex="-1" class="main-col" [ngClass]="{ expanded: menu.isMenuDisplayed === false }"> 27 <div id="content" class="main-col" [ngClass]="{ expanded: menu.isMenuDisplayed === false }">
26 28
27 <div class="main-row"> 29 <div class="main-row">
28 30
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index e621ce432..da3ffef2f 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -83,10 +83,6 @@ export class AppComponent implements OnInit, AfterViewInit {
83 return this.serverConfig.instance.name 83 return this.serverConfig.instance.name
84 } 84 }
85 85
86 goToDefaultRoute () {
87 return this.router.navigateByUrl(this.redirectService.getDefaultRoute())
88 }
89
90 ngOnInit () { 86 ngOnInit () {
91 document.getElementById('incompatible-browser').className += ' browser-ok' 87 document.getElementById('incompatible-browser').className += ' browser-ok'
92 88
@@ -135,6 +131,10 @@ export class AppComponent implements OnInit, AfterViewInit {
135 this.pluginService.initializeCustomModal(this.customModal) 131 this.pluginService.initializeCustomModal(this.customModal)
136 } 132 }
137 133
134 getDefaultRoute () {
135 return this.redirectService.getDefaultRoute()
136 }
137
138 getToggleTitle () { 138 getToggleTitle () {
139 if (this.menu.isDisplayed()) return $localize`Close the left menu` 139 if (this.menu.isDisplayed()) return $localize`Close the left menu`
140 140
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html
index 6c5258010..0786b953b 100644
--- a/client/src/app/menu/menu.component.html
+++ b/client/src/app/menu/menu.component.html
@@ -7,7 +7,7 @@
7 class="logged-in-more" ngbDropdown #dropdown="ngbDropdown" placement="bottom-left auto" 7 class="logged-in-more" ngbDropdown #dropdown="ngbDropdown" placement="bottom-left auto"
8 [container]="dropdownContainer" (openChange)="onDropdownOpenChange($event)" autoClose="outside" 8 [container]="dropdownContainer" (openChange)="onDropdownOpenChange($event)" autoClose="outside"
9 > 9 >
10 <div ngbDropdownToggle> 10 <button class="border-0 text-start" ngbDropdownToggle>
11 <my-actor-avatar [actor]="user.account" actorType="account" size="34"></my-actor-avatar> 11 <my-actor-avatar [actor]="user.account" actorType="account" size="34"></my-actor-avatar>
12 12
13 <div class="logged-in-info"> 13 <div class="logged-in-info">
@@ -19,7 +19,7 @@
19 <div class="dropdown-toggle-indicator"> 19 <div class="dropdown-toggle-indicator">
20 <span class="chevron-down"></span> 20 <span class="chevron-down"></span>
21 </div> 21 </div>
22 </div> 22 </button>
23 23
24 <div ngbDropdownMenu> 24 <div ngbDropdownMenu>
25 <a 25 <a
@@ -31,14 +31,14 @@
31 31
32 <div class="dropdown-divider"></div> 32 <div class="dropdown-divider"></div>
33 33
34 <a 34 <button
35 myPluginSelector pluginSelectorId="menu-user-dropdown-language-item" 35 myPluginSelector pluginSelectorId="menu-user-dropdown-language-item"
36 ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openLanguageChooser()" 36 ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openLanguageChooser()"
37 > 37 >
38 <my-global-icon iconName="language" aria-hidden="true"></my-global-icon> 38 <my-global-icon iconName="language" aria-hidden="true"></my-global-icon>
39 <span i18n>Interface:</span> 39 <span i18n>Interface:</span>
40 <span class="ms-auto muted">{{ currentInterfaceLanguage }}</span> 40 <span class="ms-auto muted">{{ currentInterfaceLanguage }}</span>
41 </a> 41 </button>
42 42
43 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings" fragment="video-languages-subtitles" 43 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings" fragment="video-languages-subtitles"
44 #settingsLanguagesSubtitles (click)="onActiveLinkScrollToAnchor(settingsLanguagesSubtitles)"> 44 #settingsLanguagesSubtitles (click)="onActiveLinkScrollToAnchor(settingsLanguagesSubtitles)">
@@ -57,12 +57,12 @@
57 <span class="ms-auto muted">{{ nsfwPolicy }}</span> 57 <span class="ms-auto muted">{{ nsfwPolicy }}</span>
58 </a> 58 </a>
59 59
60 <a ngbDropdownItem class="dropdown-item" (click)="toggleUseP2P()"> 60 <button ngbDropdownItem class="dropdown-item" (click)="toggleUseP2P()">
61 <my-global-icon iconName="p2p" aria-hidden="true"></my-global-icon> 61 <my-global-icon iconName="p2p" aria-hidden="true"></my-global-icon>
62 <ng-container i18n>Help share videos</ng-container> 62 <ng-container i18n>Help share videos</ng-container>
63 63
64 <my-input-switch class="ms-auto" [checked]="user.p2pEnabled"></my-input-switch> 64 <my-input-switch class="ms-auto" [checked]="user.p2pEnabled"></my-input-switch>
65 </a> 65 </button>
66 66
67 <div class="dropdown-divider"></div> 67 <div class="dropdown-divider"></div>
68 68
@@ -100,9 +100,9 @@
100 </div> 100 </div>
101 101
102 <div *ngIf="!isLoggedIn" class="login-buttons-block"> 102 <div *ngIf="!isLoggedIn" class="login-buttons-block">
103 <my-login-link className="peertube-button-link orange-button w-100"></my-login-link> 103 <my-login-link className="peertube-button-link orange-button w-100 text-truncate"></my-login-link>
104 104
105 <a *ngIf="isRegistrationAllowed()" routerLink="/signup" class="peertube-button-link create-account-button"> 105 <a *ngIf="isRegistrationAllowed()" routerLink="/signup" class="peertube-button-link create-account-button text-truncate">
106 <my-signup-label [requiresApproval]="requiresApproval"></my-signup-label> 106 <my-signup-label [requiresApproval]="requiresApproval"></my-signup-label>
107 </a> 107 </a>
108 </div> 108 </div>
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss
index a51686601..4b1ed65ce 100644
--- a/client/src/app/menu/menu.component.scss
+++ b/client/src/app/menu/menu.component.scss
@@ -252,8 +252,6 @@ my-actor-avatar {
252 252
253 > a, 253 > a,
254 > my-login-link { 254 > my-login-link {
255 @include ellipsis;
256
257 display: block; 255 display: block;
258 width: 100%; 256 width: 100%;
259 257
diff --git a/client/src/app/menu/notification.component.html b/client/src/app/menu/notification.component.html
index 7a62800f5..907828efb 100644
--- a/client/src/app/menu/notification.component.html
+++ b/client/src/app/menu/notification.component.html
@@ -3,15 +3,16 @@
3 <div *ngIf="unreadNotifications >= 100" class="unread-notifications">99+</div> 3 <div *ngIf="unreadNotifications >= 100" class="unread-notifications">99+</div>
4</ng-template> 4</ng-template>
5 5
6<div 6<button
7 [ngbPopover]="popContent" autoClose="outside" placement="bottom" container={this} popoverClass="popover-notifications" 7 [ngbPopover]="popContent" autoClose="outside" placement="bottom" container={this} popoverClass="popover-notifications"
8 i18n-title title="View your notifications" [ngClass]="{ 'notification-inbox-popover': true, 'shown': opened, 'hidden': isInMobileView }" 8 i18n-title title="View your notifications"
9 class="border-0 text-start" [ngClass]="{ 'notification-inbox-popover': true, 'shown': opened, 'hidden': isInMobileView }"
9 #popover="ngbPopover" (shown)="onPopoverShown()" (hidden)="onPopoverHidden()" 10 #popover="ngbPopover" (shown)="onPopoverShown()" (hidden)="onPopoverHidden()"
10> 11>
11 <ng-container *ngTemplateOutlet="notificationNumber"></ng-container> 12 <ng-container *ngTemplateOutlet="notificationNumber"></ng-container>
12 13
13 <my-global-icon iconName="bell"></my-global-icon> 14 <my-global-icon iconName="bell"></my-global-icon>
14</div> 15</button>
15 16
16<div *ngIf="isInMobileView" i18n-title title="View your notifications" class="notification-inbox-link"> 17<div *ngIf="isInMobileView" i18n-title title="View your notifications" class="notification-inbox-link">
17 <ng-container *ngTemplateOutlet="notificationNumber"></ng-container> 18 <ng-container *ngTemplateOutlet="notificationNumber"></ng-container>
diff --git a/client/src/app/shared/shared-forms/markdown-textarea.component.html b/client/src/app/shared/shared-forms/markdown-textarea.component.html
index 5a9ff1a15..5d355a6d8 100644
--- a/client/src/app/shared/shared-forms/markdown-textarea.component.html
+++ b/client/src/app/shared/shared-forms/markdown-textarea.component.html
@@ -25,15 +25,11 @@
25 </ng-template> 25 </ng-template>
26 </ng-container> 26 </ng-container>
27 27
28 <my-global-icon 28 <button (click)="onMaximizeClick()" class="maximize-button border-0 m-3" [disabled]="disabled">
29 *ngIf="!isMaximized" role="button" [ngbTooltip]="maximizeInText" 29 <my-global-icon *ngIf="!isMaximized" [ngbTooltip]="maximizeInText" iconName="fullscreen"></my-global-icon>
30 class="maximize-button" iconName="fullscreen" (click)="onMaximizeClick()" [ngClass]="{ disabled: disabled }" 30
31 ></my-global-icon> 31 <my-global-icon *ngIf="isMaximized" [ngbTooltip]="maximizeOutText" iconName="exit-fullscreen"></my-global-icon>
32 32 </button>
33 <my-global-icon
34 *ngIf="isMaximized" role="button" [ngbTooltip]="maximizeOutText"
35 class="maximize-button" iconName="exit-fullscreen" (click)="onMaximizeClick()" [ngClass]="{ disabled: disabled }"
36 ></my-global-icon>
37 </div> 33 </div>
38 34
39 <div [ngbNavOutlet]="nav"></div> 35 <div [ngbNavOutlet]="nav"></div>
diff --git a/client/src/app/shared/shared-forms/markdown-textarea.component.scss b/client/src/app/shared/shared-forms/markdown-textarea.component.scss
index f4b74a2d4..1f30bf129 100644
--- a/client/src/app/shared/shared-forms/markdown-textarea.component.scss
+++ b/client/src/app/shared/shared-forms/markdown-textarea.component.scss
@@ -23,7 +23,7 @@ $input-border-radius: 3px;
23 } 23 }
24 24
25 .nav-preview { 25 .nav-preview {
26 padding: 10px; 26 padding: 10px 0;
27 27
28 border: 1px solid pvar(--inputBorderColor); 28 border: 1px solid pvar(--inputBorderColor);
29 border-top: 1px dashed pvar(--inputBorderColor); 29 border-top: 1px dashed pvar(--inputBorderColor);
@@ -38,14 +38,9 @@ $input-border-radius: 3px;
38 border-bottom: 2px solid pvar(--mainColor); 38 border-bottom: 2px solid pvar(--mainColor);
39 39
40 .maximize-button { 40 .maximize-button {
41 @include margin-left(15px);
42
43 opacity: 0.6; 41 opacity: 0.6;
44 cursor: default;
45
46 &:not(.disabled) {
47 cursor: pointer;
48 42
43 &:not([disabled]) {
49 &:hover, 44 &:hover,
50 &:active { 45 &:active {
51 opacity: 1; 46 opacity: 1;
@@ -105,10 +100,6 @@ $input-border-radius: 3px;
105 100
106 padding: 20px 0; 101 padding: 20px 0;
107 width: 100% !important; 102 width: 100% !important;
108
109 .maximize-button {
110 @include margin-right(15px);
111 }
112 } 103 }
113 104
114 textarea { 105 textarea {
diff --git a/client/src/app/shared/shared-instance/instance-about-accordion.component.html b/client/src/app/shared/shared-instance/instance-about-accordion.component.html
index 94077fafa..ac8c01856 100644
--- a/client/src/app/shared/shared-instance/instance-about-accordion.component.html
+++ b/client/src/app/shared/shared-instance/instance-about-accordion.component.html
@@ -1,6 +1,6 @@
1<h2 *ngIf="displayInstanceName" class="instance-name">{{ about?.instance.name }}</h2> 1<h2 *ngIf="displayInstanceName" class="instance-name">{{ about?.instance.name }}</h2>
2 2
3<div *ngIf="displayInstanceShortDescription" class="instance-short-description">{{ about?.instance.shortDescription }}</div> 3<div *ngIf="displayInstanceShortDescription" class="instance-short-description ellipsis-multiline-3">{{ about?.instance.shortDescription }}</div>
4 4
5<ngb-accordion #accordion="ngbAccordion" [closeOthers]="true"> 5<ngb-accordion #accordion="ngbAccordion" [closeOthers]="true">
6 <ngb-panel *ngIf="panels.features" id="instance-features"> 6 <ngb-panel *ngIf="panels.features" id="instance-features">
diff --git a/client/src/app/shared/shared-instance/instance-about-accordion.component.scss b/client/src/app/shared/shared-instance/instance-about-accordion.component.scss
index ee9e4c3ee..8337a7154 100644
--- a/client/src/app/shared/shared-instance/instance-about-accordion.component.scss
+++ b/client/src/app/shared/shared-instance/instance-about-accordion.component.scss
@@ -6,8 +6,7 @@
6} 6}
7 7
8.instance-short-description { 8.instance-short-description {
9 @include ellipsis-multiline(1rem, 3, inherit); 9 font-size: 1rem;
10
11 margin: 25px 0; 10 margin: 25px 0;
12} 11}
13 12
diff --git a/client/src/app/shared/shared-main/angular/link.component.scss b/client/src/app/shared/shared-main/angular/link.component.scss
index f54240d31..d288afab1 100644
--- a/client/src/app/shared/shared-main/angular/link.component.scss
+++ b/client/src/app/shared/shared-main/angular/link.component.scss
@@ -1,4 +1,4 @@
1.no-class { 1.inherit-parent {
2 color: inherit; 2 color: inherit;
3 text-decoration: inherit; 3 text-decoration: inherit;
4 position: inherit; 4 position: inherit;
diff --git a/client/src/app/shared/shared-main/angular/link.component.ts b/client/src/app/shared/shared-main/angular/link.component.ts
index 1f5975589..f2093496f 100644
--- a/client/src/app/shared/shared-main/angular/link.component.ts
+++ b/client/src/app/shared/shared-main/angular/link.component.ts
@@ -14,14 +14,17 @@ export class LinkComponent implements OnInit {
14 @Input() title?: string 14 @Input() title?: string
15 15
16 @Input() className?: string 16 @Input() className?: string
17 @Input() inheritParentCSS = false
17 18
18 @Input() tabindex: string | number 19 @Input() tabindex: string | number
19 20
20 builtClasses: string 21 builtClasses: string
21 22
22 ngOnInit () { 23 ngOnInit () {
23 this.builtClasses = this.className 24 this.builtClasses = this.className || ''
24 ? this.className 25
25 : 'no-class' 26 if (!this.builtClasses || this.inheritParentCSS) {
27 this.builtClasses += ' inherit-parent'
28 }
26 } 29 }
27} 30}
diff --git a/client/src/app/shared/shared-main/feeds/feed.component.html b/client/src/app/shared/shared-main/feeds/feed.component.html
index a748be873..7032c4cd0 100644
--- a/client/src/app/shared/shared-main/feeds/feed.component.html
+++ b/client/src/app/shared/shared-main/feeds/feed.component.html
@@ -1,4 +1,4 @@
1<div class="feed" *ngIf="syndicationItems && syndicationItems.length !== 0"> 1<button class="feed border-0 p-0" *ngIf="syndicationItems && syndicationItems.length !== 0">
2 <my-global-icon 2 <my-global-icon
3 role="button" aria-label="Open syndication dropdown" i18n-aria-label 3 role="button" aria-label="Open syndication dropdown" i18n-aria-label
4 *ngIf="syndicationItems.length !== 0" [ngbPopover]="feedsList" [autoClose]="true" placement="bottom left auto" 4 *ngIf="syndicationItems.length !== 0" [ngbPopover]="feedsList" [autoClose]="true" placement="bottom left auto"
@@ -9,4 +9,4 @@
9 <ng-template #feedsList> 9 <ng-template #feedsList>
10 <a *ngFor="let item of syndicationItems" [href]="item.url" target="_blank" rel="noopener noreferrer">{{ item.label }}</a> 10 <a *ngFor="let item of syndicationItems" [href]="item.url" target="_blank" rel="noopener noreferrer">{{ item.label }}</a>
11 </ng-template> 11 </ng-template>
12</div> 12</button>
diff --git a/client/src/app/shared/shared-main/feeds/feed.component.scss b/client/src/app/shared/shared-main/feeds/feed.component.scss
index bf1f4eeeb..25afe9c6c 100644
--- a/client/src/app/shared/shared-main/feeds/feed.component.scss
+++ b/client/src/app/shared/shared-main/feeds/feed.component.scss
@@ -3,15 +3,19 @@
3 3
4.feed { 4.feed {
5 width: 100%; 5 width: 100%;
6 color: inherit;
6 7
7 a { 8 a {
8 color: #000; 9 color: pvar(--mainForegroundColor);
9 display: block; 10 display: block;
10 min-width: 100px; 11 min-width: 100px;
12
13 &:hover {
14 text-decoration: underline;
15 }
11 } 16 }
12} 17}
13 18
14my-global-icon { 19my-global-icon {
15 cursor: pointer;
16 width: 100%; 20 width: 100%;
17} 21}
diff --git a/client/src/app/shared/shared-main/misc/help.component.html b/client/src/app/shared/shared-main/misc/help.component.html
index 360a476f6..0252ad5cb 100644
--- a/client/src/app/shared/shared-main/misc/help.component.html
+++ b/client/src/app/shared/shared-main/misc/help.component.html
@@ -22,11 +22,9 @@
22 </p> 22 </p>
23</ng-template> 23</ng-template>
24 24
25<span 25<button
26 role="button" 26 class="help-tooltip-button p-0 border-0 mx-1"
27 class="help-tooltip-button"
28 [title]="title" 27 [title]="title"
29 tabindex=0
30 popoverClass="help-popover" 28 popoverClass="help-popover"
31 [attr.aria-pressed]="isPopoverOpened" 29 [attr.aria-pressed]="isPopoverOpened"
32 [ngbPopover]="tooltipTemplate" 30 [ngbPopover]="tooltipTemplate"
@@ -36,4 +34,4 @@
36 (onShown)="onPopoverShown()" 34 (onShown)="onPopoverShown()"
37> 35>
38 <my-global-icon [iconName]="iconName"></my-global-icon> 36 <my-global-icon [iconName]="iconName"></my-global-icon>
39</span> 37</button>
diff --git a/client/src/app/shared/shared-main/misc/help.component.scss b/client/src/app/shared/shared-main/misc/help.component.scss
index 6ccef9f2c..46f533f61 100644
--- a/client/src/app/shared/shared-main/misc/help.component.scss
+++ b/client/src/app/shared/shared-main/misc/help.component.scss
@@ -2,12 +2,6 @@
2@use '_mixins' as *; 2@use '_mixins' as *;
3 3
4.help-tooltip-button { 4.help-tooltip-button {
5 @include disable-outline;
6
7 cursor: pointer;
8 border: 0;
9 margin: 5px;
10
11 my-global-icon { 5 my-global-icon {
12 @include apply-svg-color(pvar(--greyForegroundColor)); 6 @include apply-svg-color(pvar(--greyForegroundColor));
13 7
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.html b/client/src/app/shared/shared-share-modal/video-share.component.html
index 01d351783..5650fa948 100644
--- a/client/src/app/shared/shared-share-modal/video-share.component.html
+++ b/client/src/app/shared/shared-share-modal/video-share.component.html
@@ -1,7 +1,10 @@
1<ng-template #modal let-hide="close"> 1<ng-template #modal let-hide="close">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Share</h4> 3 <h4 i18n class="modal-title">Share</h4>
4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon> 4
5 <button class="border-0 p-0" (click)="hide()">
6 <my-global-icon iconName="cross" aria-label="Close" role="button" ></my-global-icon>
7 </button>
5 </div> 8 </div>
6 9
7 10
@@ -150,89 +153,85 @@
150 <div [ngbNavOutlet]="nav"></div> 153 <div [ngbNavOutlet]="nav"></div>
151 154
152 <div class="filters"> 155 <div class="filters">
153 <div> 156 <div class="form-group start-at" *ngIf="!video.isLive">
154 <div class="form-group start-at" *ngIf="!video.isLive"> 157 <my-peertube-checkbox
158 inputName="startAt" [(ngModel)]="customizations.startAtCheckbox"
159 i18n-labelText labelText="Start at"
160 ></my-peertube-checkbox>
161
162 <my-timestamp-input
163 [timestamp]="customizations.startAt"
164 [maxTimestamp]="video.duration"
165 [disabled]="!customizations.startAtCheckbox"
166 [(ngModel)]="customizations.startAt"
167 >
168 </my-timestamp-input>
169 </div>
170
171 <div *ngIf="videoCaptions.length !== 0" class="form-group video-caption-block">
172 <my-peertube-checkbox
173 inputName="subtitleCheckbox" [(ngModel)]="customizations.subtitleCheckbox"
174 i18n-labelText labelText="Auto select subtitle"
175 ></my-peertube-checkbox>
176
177 <div class="peertube-select-container" [ngClass]="{ disabled: !customizations.subtitleCheckbox }">
178 <select [(ngModel)]="customizations.subtitle" [disabled]="!customizations.subtitleCheckbox" class="form-control">
179 <option *ngFor="let caption of videoCaptions" [value]="caption.language.id">{{ caption.language.label }}</option>
180 </select>
181 </div>
182 </div>
183
184 <div class="form-group" *ngIf="isInVideoEmbedTab()">
185 <my-peertube-checkbox
186 inputName="onlyEmbedUrl" [(ngModel)]="customizations.onlyEmbedUrl"
187 i18n-labelText labelText="Only display embed URL"
188 ></my-peertube-checkbox>
189 </div>
190
191 <my-plugin-placeholder pluginId="share-modal-video-settings"></my-plugin-placeholder>
192
193 <div class="advanced-filters" [ngbCollapse]="isAdvancedCustomizationCollapsed" [animation]="true">
194 <div class="form-group stop-at" *ngIf="!video.isLive">
155 <my-peertube-checkbox 195 <my-peertube-checkbox
156 inputName="startAt" [(ngModel)]="customizations.startAtCheckbox" 196 inputName="stopAt" [(ngModel)]="customizations.stopAtCheckbox"
157 i18n-labelText labelText="Start at" 197 i18n-labelText labelText="Stop at"
158 ></my-peertube-checkbox> 198 ></my-peertube-checkbox>
159 199
160 <my-timestamp-input 200 <my-timestamp-input
161 [timestamp]="customizations.startAt" 201 [timestamp]="customizations.stopAt"
162 [maxTimestamp]="video.duration" 202 [maxTimestamp]="video.duration"
163 [disabled]="!customizations.startAtCheckbox" 203 [disabled]="!customizations.stopAtCheckbox"
164 [(ngModel)]="customizations.startAt" 204 [(ngModel)]="customizations.stopAt"
165 > 205 >
166 </my-timestamp-input> 206 </my-timestamp-input>
167 </div> 207 </div>
168 208
169 <div *ngIf="videoCaptions.length !== 0" class="form-group video-caption-block"> 209 <div class="form-group">
170 <my-peertube-checkbox 210 <my-peertube-checkbox
171 inputName="subtitleCheckbox" [(ngModel)]="customizations.subtitleCheckbox" 211 inputName="autoplay" [(ngModel)]="customizations.autoplay"
172 i18n-labelText labelText="Auto select subtitle" 212 i18n-labelText labelText="Autoplay"
173 ></my-peertube-checkbox> 213 ></my-peertube-checkbox>
174
175 <div class="peertube-select-container" [ngClass]="{ disabled: !customizations.subtitleCheckbox }">
176 <select [(ngModel)]="customizations.subtitle" [disabled]="!customizations.subtitleCheckbox" class="form-control">
177 <option *ngFor="let caption of videoCaptions" [value]="caption.language.id">{{ caption.language.label }}</option>
178 </select>
179 </div>
180 </div> 214 </div>
181 215
182 <div class="form-group" *ngIf="isInVideoEmbedTab()"> 216 <div class="form-group">
183 <my-peertube-checkbox 217 <my-peertube-checkbox
184 inputName="onlyEmbedUrl" [(ngModel)]="customizations.onlyEmbedUrl" 218 inputName="muted" [(ngModel)]="customizations.muted"
185 i18n-labelText labelText="Only display embed URL" 219 i18n-labelText labelText="Muted"
186 ></my-peertube-checkbox> 220 ></my-peertube-checkbox>
187 </div> 221 </div>
188 222
189 <my-plugin-placeholder pluginId="share-modal-video-settings"></my-plugin-placeholder> 223 <div class="form-group" *ngIf="!video.isLive">
190 </div> 224 <my-peertube-checkbox
191 225 inputName="loop" [(ngModel)]="customizations.loop"
192 <div class="advanced-filters collapse-transition" [ngbCollapse]="isAdvancedCustomizationCollapsed"> 226 i18n-labelText labelText="Loop"
193 <div> 227 ></my-peertube-checkbox>
194 <div class="form-group stop-at" *ngIf="!video.isLive"> 228 </div>
195 <my-peertube-checkbox
196 inputName="stopAt" [(ngModel)]="customizations.stopAtCheckbox"
197 i18n-labelText labelText="Stop at"
198 ></my-peertube-checkbox>
199
200 <my-timestamp-input
201 [timestamp]="customizations.stopAt"
202 [maxTimestamp]="video.duration"
203 [disabled]="!customizations.stopAtCheckbox"
204 [(ngModel)]="customizations.stopAt"
205 >
206 </my-timestamp-input>
207 </div>
208
209 <div class="form-group">
210 <my-peertube-checkbox
211 inputName="autoplay" [(ngModel)]="customizations.autoplay"
212 i18n-labelText labelText="Autoplay"
213 ></my-peertube-checkbox>
214 </div>
215
216 <div class="form-group">
217 <my-peertube-checkbox
218 inputName="muted" [(ngModel)]="customizations.muted"
219 i18n-labelText labelText="Muted"
220 ></my-peertube-checkbox>
221 </div>
222
223 <div class="form-group" *ngIf="!video.isLive">
224 <my-peertube-checkbox
225 inputName="loop" [(ngModel)]="customizations.loop"
226 i18n-labelText labelText="Loop"
227 ></my-peertube-checkbox>
228 </div>
229 229
230 <div *ngIf="!isLocalVideo() && !isInVideoEmbedTab()" class="form-group"> 230 <div *ngIf="!isLocalVideo() && !isInVideoEmbedTab()" class="form-group">
231 <my-peertube-checkbox 231 <my-peertube-checkbox
232 inputName="originUrl" [(ngModel)]="customizations.originUrl" 232 inputName="originUrl" [(ngModel)]="customizations.originUrl"
233 i18n-labelText labelText="Use origin instance URL" 233 i18n-labelText labelText="Use origin instance URL"
234 ></my-peertube-checkbox> 234 ></my-peertube-checkbox>
235 </div>
236 </div> 235 </div>
237 236
238 <ng-container *ngIf="isInVideoEmbedTab()"> 237 <ng-container *ngIf="isInVideoEmbedTab()">
@@ -280,9 +279,11 @@
280 </ng-container> 279 </ng-container>
281 </div> 280 </div>
282 281
283 <div (click)="isAdvancedCustomizationCollapsed = !isAdvancedCustomizationCollapsed" role="button" class="advanced-filters-button" 282 <button
284 [attr.aria-expanded]="!isAdvancedCustomizationCollapsed" aria-controls="collapseBasic"> 283 class="border-0 p-0 mt-4 mx-auto fw-semibold d-block"
285 284 (click)="isAdvancedCustomizationCollapsed = !isAdvancedCustomizationCollapsed"
285 [attr.aria-expanded]="!isAdvancedCustomizationCollapsed" aria-controls="collapseBasic"
286 >
286 <ng-container *ngIf="isAdvancedCustomizationCollapsed"> 287 <ng-container *ngIf="isAdvancedCustomizationCollapsed">
287 <span class="chevron-down"></span> 288 <span class="chevron-down"></span>
288 289
@@ -298,7 +299,7 @@
298 Less customization 299 Less customization
299 </ng-container> 300 </ng-container>
300 </ng-container> 301 </ng-container>
301 </div> 302 </button>
302 </div> 303 </div>
303 </div> 304 </div>
304 </div> 305 </div>
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.scss b/client/src/app/shared/shared-share-modal/video-share.component.scss
index 7b6009f5a..c64e11f4d 100644
--- a/client/src/app/shared/shared-share-modal/video-share.component.scss
+++ b/client/src/app/shared/shared-share-modal/video-share.component.scss
@@ -42,12 +42,7 @@ my-input-text {
42 } 42 }
43 43
44 .advanced-filters-button { 44 .advanced-filters-button {
45 display: flex;
46 justify-content: center;
47 align-items: center;
48 margin-top: 20px;
49 font-weight: $font-semibold; 45 font-weight: $font-semibold;
50 cursor: pointer;
51 } 46 }
52 47
53 .video-caption-block { 48 .video-caption-block {
diff --git a/client/src/app/shared/shared-thumbnail/video-thumbnail.component.html b/client/src/app/shared/shared-thumbnail/video-thumbnail.component.html
index 4fea0cc1c..57fcdd899 100644
--- a/client/src/app/shared/shared-thumbnail/video-thumbnail.component.html
+++ b/client/src/app/shared/shared-thumbnail/video-thumbnail.component.html
@@ -1,8 +1,8 @@
1<a *ngIf="!videoHref" [routerLink]="getVideoRouterLink()" [queryParams]="queryParams" class="video-thumbnail"> 1<a *ngIf="!videoHref" [routerLink]="getVideoRouterLink()" [queryParams]="queryParams" class="video-thumbnail" tabindex="-1">
2 <ng-container *ngTemplateOutlet="aContent"></ng-container> 2 <ng-container *ngTemplateOutlet="aContent"></ng-container>
3</a> 3</a>
4 4
5<a *ngIf="videoHref" [href]="videoHref" [target]="videoTarget" class="video-thumbnail"> 5<a *ngIf="videoHref" [href]="videoHref" [target]="videoTarget" class="video-thumbnail" tabindex="-1">
6 <ng-container *ngTemplateOutlet="aContent"></ng-container> 6 <ng-container *ngTemplateOutlet="aContent"></ng-container>
7</a> 7</a>
8 8
diff --git a/client/src/app/shared/shared-video-miniature/video-download.component.html b/client/src/app/shared/shared-video-miniature/video-download.component.html
index 1f622933d..3d8ce22de 100644
--- a/client/src/app/shared/shared-video-miniature/video-download.component.html
+++ b/client/src/app/shared/shared-video-miniature/video-download.component.html
@@ -56,7 +56,7 @@
56 56
57 <div [ngbNavOutlet]="resolutionNav"></div> 57 <div [ngbNavOutlet]="resolutionNav"></div>
58 58
59 <div class="advanced-filters collapse-transition" [ngbCollapse]="isAdvancedCustomizationCollapsed"> 59 <div class="advanced-filters" [ngbCollapse]="isAdvancedCustomizationCollapsed" [animation]="true">
60 <div ngbNav #navMetadata="ngbNav" class="nav-tabs nav-metadata"> 60 <div ngbNav #navMetadata="ngbNav" class="nav-tabs nav-metadata">
61 <ng-container ngbNavItem> 61 <ng-container ngbNavItem>
62 <a ngbNavLink i18n>Format</a> 62 <a ngbNavLink i18n>Format</a>
diff --git a/client/src/app/shared/shared-video-miniature/video-filters-header.component.html b/client/src/app/shared/shared-video-miniature/video-filters-header.component.html
index 1e92e1952..48bb0d812 100644
--- a/client/src/app/shared/shared-video-miniature/video-filters-header.component.html
+++ b/client/src/app/shared/shared-video-miniature/video-filters-header.component.html
@@ -12,8 +12,8 @@
12 12
13 <div class="first-row"> 13 <div class="first-row">
14 <div class="active-filters"> 14 <div class="active-filters">
15 <div 15 <button
16 class="pastille filters-toggle" (click)="areFiltersCollapsed = !areFiltersCollapsed" role="button" 16 class="pastille filters-toggle" (click)="areFiltersCollapsed = !areFiltersCollapsed"
17 [attr.aria-expanded]="!areFiltersCollapsed" aria-controls="collapseBasic" 17 [attr.aria-expanded]="!areFiltersCollapsed" aria-controls="collapseBasic"
18 [ngClass]="{ active: !areFiltersCollapsed }" 18 [ngClass]="{ active: !areFiltersCollapsed }"
19 > 19 >
@@ -21,7 +21,7 @@
21 <ng-container i18n *ngIf="!areFiltersCollapsed">Hide filters</ng-container> 21 <ng-container i18n *ngIf="!areFiltersCollapsed">Hide filters</ng-container>
22 22
23 <my-global-icon iconName="chevrons-up"></my-global-icon> 23 <my-global-icon iconName="chevrons-up"></my-global-icon>
24 </div> 24 </button>
25 25
26 <div 26 <div
27 *ngFor="let activeFilter of filters.getActiveFilters()" (click)="resetFilter(activeFilter.key, activeFilter.canRemove)" 27 *ngFor="let activeFilter of filters.getActiveFilters()" (click)="resetFilter(activeFilter.key, activeFilter.canRemove)"
@@ -56,7 +56,7 @@
56 56
57 </div> 57 </div>
58 58
59 <div class="collapse-transition" [ngbCollapse]="areFiltersCollapsed"> 59 <div [ngbCollapse]="areFiltersCollapsed" [animation]="true">
60 <div class="filters"> 60 <div class="filters">
61 <div class="form-group"> 61 <div class="form-group">
62 <label class="with-description" for="languageOneOf" i18n>Languages:</label> 62 <label class="with-description" for="languageOneOf" i18n>Languages:</label>
diff --git a/client/src/app/shared/shared-video-miniature/video-filters-header.component.scss b/client/src/app/shared/shared-video-miniature/video-filters-header.component.scss
index a4e51982c..c65895a51 100644
--- a/client/src/app/shared/shared-video-miniature/video-filters-header.component.scss
+++ b/client/src/app/shared/shared-video-miniature/video-filters-header.component.scss
@@ -50,6 +50,10 @@
50 padding: 4px 15px; 50 padding: 4px 15px;
51 margin-bottom: 15px; 51 margin-bottom: 15px;
52 cursor: pointer; 52 cursor: pointer;
53
54 &:focus-visible {
55 outline: pvar(--mainColor) auto 1px;
56 }
53} 57}
54 58
55.filters-toggle { 59.filters-toggle {
diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.html b/client/src/app/shared/shared-video-miniature/video-miniature.component.html
index 7d3c3dbfc..42d13f458 100644
--- a/client/src/app/shared/shared-video-miniature/video-miniature.component.html
+++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.html
@@ -24,8 +24,8 @@
24 24
25 <div class="w-100 d-flex flex-column"> 25 <div class="w-100 d-flex flex-column">
26 <my-link 26 <my-link
27 [internalLink]="videoRouterLink" [href]="videoHref" [target]="videoTarget" 27 [internalLink]="videoRouterLink" [href]="videoHref" [target]="videoTarget" [inheritParentCSS]="true"
28 [title]="video.name"class="video-miniature-name" [ngClass]="{ 'blur-filter': isVideoBlur }" tabindex="-1" 28 [title]="video.name" class="video-miniature-name" className="ellipsis-multiline-2" [ngClass]="{ 'blur-filter': isVideoBlur }"
29 > 29 >
30 {{ video.name }} 30 {{ video.name }}
31 </my-link> 31 </my-link>
@@ -40,7 +40,7 @@
40 </span> 40 </span>
41 </span> 41 </span>
42 42
43 <a tabindex="-1" *ngIf="displayOptions.by" class="video-miniature-account" [routerLink]="[ '/c', video.byVideoChannel ]"> 43 <a *ngIf="displayOptions.by" class="video-miniature-account" [routerLink]="[ '/c', video.byVideoChannel ]">
44 <ng-container *ngIf="displayOwnerAccount()">{{ authorAccount }}</ng-container> 44 <ng-container *ngIf="displayOwnerAccount()">{{ authorAccount }}</ng-container>
45 <ng-container *ngIf="displayOwnerVideoChannel()">{{ authorChannel }}</ng-container> 45 <ng-container *ngIf="displayOwnerVideoChannel()">{{ authorChannel }}</ng-container>
46 </a> 46 </a>
diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.scss b/client/src/app/shared/shared-video-miniature/video-miniature.component.scss
index a397efdca..d48b00518 100644
--- a/client/src/app/shared/shared-video-miniature/video-miniature.component.scss
+++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.scss
@@ -167,7 +167,7 @@ my-actor-avatar {
167 } 167 }
168 168
169 .video-miniature-name { 169 .video-miniature-name {
170 @include ellipsis-multiline($video-miniature-row-name-font-size, 2); 170 font-size: $video-miniature-row-name-font-size;
171 } 171 }
172 172
173 .video-miniature-created-at-views, 173 .video-miniature-created-at-views,
diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.html b/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.html
index 1dd68b09e..3b34c71ce 100644
--- a/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.html
+++ b/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.html
@@ -1,6 +1,6 @@
1<div class="miniature" [ngClass]="{ 'no-videos': playlist.videosLength === 0, 'to-manage': toManage, 'display-as-row': displayAsRow }"> 1<div class="miniature" [ngClass]="{ 'no-videos': playlist.videosLength === 0, 'to-manage': toManage, 'display-as-row': displayAsRow }">
2 <my-link 2 <my-link
3 [internalLink]="routerLink" [href]="playlistHref" [target]="playlistTarget" 3 [internalLink]="routerLink" [href]="playlistHref" [target]="playlistTarget" [inheritParentCSS]="true"
4 [title]="playlist.description" class="miniature-thumbnail" 4 [title]="playlist.description" class="miniature-thumbnail"
5 > 5 >
6 <img alt="" [attr.aria-labelledby]="playlist.displayName" [attr.src]="playlist.thumbnailUrl" /> 6 <img alt="" [attr.aria-labelledby]="playlist.displayName" [attr.src]="playlist.thumbnailUrl" />
@@ -16,8 +16,8 @@
16 16
17 <div class="miniature-info"> 17 <div class="miniature-info">
18 <my-link 18 <my-link
19 [internalLink]="routerLink" [href]="playlistHref" [target]="playlistTarget" 19 [internalLink]="routerLink" [href]="playlistHref" [target]="playlistTarget" [inheritParentCSS]="true"
20 [title]="playlist.description" class="miniature-name" tabindex="-1" 20 [title]="playlist.description" class="miniature-name" className="ellipsis-multiline-2"
21 > 21 >
22 {{ playlist.displayName }} 22 {{ playlist.displayName }}
23 </my-link> 23 </my-link>
diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.scss b/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.scss
index d43afad28..2d8377e7b 100644
--- a/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.scss
+++ b/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.scss
@@ -95,7 +95,7 @@
95 display: flex; 95 display: flex;
96 96
97 .miniature-name { 97 .miniature-name {
98 @include ellipsis-multiline($video-miniature-row-name-font-size, 2); 98 font-size: $video-miniature-row-name-font-size;
99 } 99 }
100 100
101 .miniature-thumbnail { 101 .miniature-thumbnail {
diff --git a/client/src/sass/bootstrap.scss b/client/src/sass/bootstrap.scss
index 4d956d652..d04652184 100644
--- a/client/src/sass/bootstrap.scss
+++ b/client/src/sass/bootstrap.scss
@@ -15,6 +15,7 @@
15@import 'bootstrap/scss/grid'; 15@import 'bootstrap/scss/grid';
16@import 'bootstrap/scss/forms'; 16@import 'bootstrap/scss/forms';
17@import 'bootstrap/scss/buttons'; 17@import 'bootstrap/scss/buttons';
18@import 'bootstrap/scss/transitions';
18@import 'bootstrap/scss/dropdown'; 19@import 'bootstrap/scss/dropdown';
19@import 'bootstrap/scss/button-group'; 20@import 'bootstrap/scss/button-group';
20@import 'bootstrap/scss/nav'; 21@import 'bootstrap/scss/nav';
@@ -203,7 +204,6 @@ body {
203 display: flex !important; 204 display: flex !important;
204 align-items: center; 205 align-items: center;
205 height: 30px !important; 206 height: 30px !important;
206 padding: 10px 15px !important;
207} 207}
208 208
209.nav.nav-pills { 209.nav.nav-pills {
@@ -260,19 +260,6 @@ body {
260 border-color: #dee2e6; 260 border-color: #dee2e6;
261} 261}
262 262
263.collapse-transition {
264 // Animation when we show/hide the filters
265 transition: max-height 0.3s;
266 display: block !important;
267 overflow: hidden !important;
268 max-height: 0;
269
270 &.show {
271 max-height: 1500px;
272 overflow: inherit !important;
273 }
274}
275
276.accordion-button { 263.accordion-button {
277 font-size: 18px; 264 font-size: 18px;
278 265
@@ -389,3 +376,8 @@ body {
389 display: none; 376 display: none;
390 } 377 }
391} 378}
379
380.text-truncate {
381 // Prevent invalid height in parent: https://stackoverflow.com/a/22425601
382 vertical-align: top;
383}
diff --git a/client/src/sass/class-helpers/_common.scss b/client/src/sass/class-helpers/_common.scss
index 0a81a415d..e42d7d587 100644
--- a/client/src/sass/class-helpers/_common.scss
+++ b/client/src/sass/class-helpers/_common.scss
@@ -3,30 +3,6 @@
3@use '_variables' as *; 3@use '_variables' as *;
4@use '_mixins' as *; 4@use '_mixins' as *;
5 5
6.link-orange {
7 color: pvar(--mainForegroundColor);
8 font-weight: $font-semibold;
9 border-bottom: 0.18em solid pvar(--mainColor);
10 display: inline-block;
11 line-height: 1.1;
12
13 &:hover {
14 color: pvar(--mainForegroundColor);
15 opacity: 0.8;
16 }
17}
18
19.underline-orange {
20 display: inline-block;
21 border-bottom: 0.19em solid pvar(--mainColor);
22}
23
24// ---------------------------------------------------------------------------
25
26.muted {
27 @include muted;
28}
29
30// --------------------------------------------------------------------------- 6// ---------------------------------------------------------------------------
31 7
32.pt-badge { 8.pt-badge {
diff --git a/client/src/sass/class-helpers/_text.scss b/client/src/sass/class-helpers/_text.scss
new file mode 100644
index 000000000..0fe698d4f
--- /dev/null
+++ b/client/src/sass/class-helpers/_text.scss
@@ -0,0 +1,47 @@
1@use '_badges' as *;
2@use '_icons' as *;
3@use '_variables' as *;
4@use '_mixins' as *;
5
6.link-orange {
7 color: pvar(--mainForegroundColor);
8 font-weight: $font-semibold;
9 border-bottom: 0.18em solid pvar(--mainColor);
10 display: inline-block;
11 line-height: 1.1;
12
13 &:hover {
14 color: pvar(--mainForegroundColor);
15 opacity: 0.8;
16 }
17}
18
19.underline-orange {
20 display: inline-block;
21 border-bottom: 0.19em solid pvar(--mainColor);
22}
23
24// ---------------------------------------------------------------------------
25
26.muted {
27 @include muted;
28}
29
30// ---------------------------------------------------------------------------
31
32@mixin ellipsis-multiline($number-of-lines) {
33 display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */
34 -webkit-line-clamp: $number-of-lines;
35 -webkit-box-orient: vertical;
36 overflow: hidden;
37}
38
39.ellipsis-multiline-2 {
40 @include ellipsis-multiline(2);
41}
42
43.ellipsis-multiline-3 {
44 @include ellipsis-multiline(3);
45}
46
47// ---------------------------------------------------------------------------
diff --git a/client/src/sass/class-helpers/index.scss b/client/src/sass/class-helpers/index.scss
index 28beb3b7f..4fe935ab1 100644
--- a/client/src/sass/class-helpers/index.scss
+++ b/client/src/sass/class-helpers/index.scss
@@ -3,3 +3,4 @@
3@use './_custom-bootstrap-helpers'; 3@use './_custom-bootstrap-helpers';
4@use './_forms'; 4@use './_forms';
5@use './_menu'; 5@use './_menu';
6@use './_text';
diff --git a/client/src/sass/include/_bootstrap-variables.scss b/client/src/sass/include/_bootstrap-variables.scss
index ca4a835f9..47ebe685c 100644
--- a/client/src/sass/include/_bootstrap-variables.scss
+++ b/client/src/sass/include/_bootstrap-variables.scss
@@ -41,6 +41,7 @@ $input-focus-bg: pvar(--inputBackgroundColor);
41$input-btn-focus-width: 0; 41$input-btn-focus-width: 0;
42$input-btn-focus-color: inherit; 42$input-btn-focus-color: inherit;
43$input-focus-border-color: #ced4da; 43$input-focus-border-color: #ced4da;
44$input-focus-box-shadow: 0 0 0 0.25rem pvar(--mainColorLightest);
44 45
45$input-group-addon-color: pvar(--mainForegroundColor); 46$input-group-addon-color: pvar(--mainForegroundColor);
46$input-group-addon-bg: pvar(--greyBackgroundColor); 47$input-group-addon-bg: pvar(--greyBackgroundColor);
diff --git a/client/src/sass/include/_miniature.scss b/client/src/sass/include/_miniature.scss
index a1b963400..eb77f2c3d 100644
--- a/client/src/sass/include/_miniature.scss
+++ b/client/src/sass/include/_miniature.scss
@@ -2,9 +2,9 @@
2@use '_mixins' as *; 2@use '_mixins' as *;
3 3
4@mixin miniature-name { 4@mixin miniature-name {
5 @include ellipsis-multiline(1.1em, 2);
6 @include peertube-word-wrap(false); 5 @include peertube-word-wrap(false);
7 6
7 font-size: 1.1em;
8 transition: color 0.2s; 8 transition: color 0.2s;
9 font-weight: $font-semibold; 9 font-weight: $font-semibold;
10 color: pvar(--mainForegroundColor); 10 color: pvar(--mainForegroundColor);
diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss
index 0f301dab2..004f49262 100644
--- a/client/src/sass/include/_mixins.scss
+++ b/client/src/sass/include/_mixins.scss
@@ -8,13 +8,16 @@
8 &:focus, 8 &:focus,
9 &:active { 9 &:active {
10 text-decoration: none !important; 10 text-decoration: none !important;
11 }
12
13 &:focus:not(.focus-visible) {
11 outline: none !important; 14 outline: none !important;
12 } 15 }
13} 16}
14 17
15@mixin disable-outline { 18@mixin disable-outline {
16 &:focus:not(.focus-visible) { 19 &:focus:not(.focus-visible) {
17 outline: none; 20 outline: none !important;
18 } 21 }
19} 22}
20 23
@@ -24,20 +27,6 @@
24 text-overflow: ellipsis; 27 text-overflow: ellipsis;
25} 28}
26 29
27@mixin ellipsis-multiline($font-size: 16px, $number-of-lines: 2, $line-height: $font-size) {
28 display: block;
29 /* Fallback for non-webkit */
30 display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */
31 -webkit-line-clamp: $number-of-lines;
32 -webkit-box-orient: vertical;
33 /* Fallback for non-webkit */
34 font-size: $font-size;
35 line-height: $line-height;
36 overflow: hidden;
37 text-overflow: ellipsis;
38 max-height: $font-size * $number-of-lines;
39}
40
41@mixin muted { 30@mixin muted {
42 color: pvar(--greyForegroundColor) !important; 31 color: pvar(--greyForegroundColor) !important;
43} 32}
diff --git a/client/src/sass/ng-select.scss b/client/src/sass/ng-select.scss
index 55494a556..dfe1f6f0d 100644
--- a/client/src/sass/ng-select.scss
+++ b/client/src/sass/ng-select.scss
@@ -40,8 +40,7 @@ $ng-select-input-text: pvar(--mainForegroundColor);
40 40
41 &.ng-select-focused { 41 &.ng-select-focused {
42 &:not(.ng-select-opened) > .ng-select-container { 42 &:not(.ng-select-opened) > .ng-select-container {
43 border-color: #ccc !important; 43 border-color: $ng-select-border !important;
44 box-shadow: none !important;
45 } 44 }
46 } 45 }
47 46