Browse Source

Upgrade client dependencies

Migrate removed primeng theme to custom CSS
pull/3334/head
Chocobozzz 1 week ago
parent
commit
4f926722ea
No known key found for this signature in database GPG Key ID: 583A612D890159BE
33 changed files with 3024 additions and 2385 deletions
  1. +0
    -2
      client/angular.json
  2. +39
    -38
      client/package.json
  3. +1
    -1
      client/src/app/+admin/admin.component.html
  4. +3
    -1
      client/src/app/+admin/admin.component.scss
  5. +0
    -1
      client/src/app/+admin/follows/following-list/following-list.component.ts
  6. +0
    -28
      client/src/app/+admin/plugins/shared/toggle-plugin-type.scss
  7. +8
    -2
      client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html
  8. +0
    -2
      client/src/app/+my-account/my-account.module.ts
  9. +1
    -1
      client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
  10. +54
    -49
      client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts
  11. +1
    -1
      client/src/app/+my-library/my-history/my-history.component.html
  12. +5
    -1
      client/src/app/+my-library/my-history/my-history.component.ts
  13. +0
    -2
      client/src/app/+my-library/my-library.module.ts
  14. +2
    -3
      client/src/app/+videos/+video-edit/shared/video-edit.component.scss
  15. +4
    -3
      client/src/app/+videos/+video-watch/recommendations/recommendations.module.ts
  16. +1
    -1
      client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.html
  17. +5
    -2
      client/src/app/app.component.ts
  18. +5
    -4
      client/src/app/core/notification/peertube-socket.service.ts
  19. +2
    -1
      client/src/app/menu/menu.component.html
  20. +0
    -42
      client/src/app/menu/menu.component.scss
  21. +1
    -0
      client/src/app/shared/shared-forms/index.ts
  22. +4
    -0
      client/src/app/shared/shared-forms/input-switch.component.html
  23. +44
    -0
      client/src/app/shared/shared-forms/input-switch.component.scss
  24. +38
    -0
      client/src/app/shared/shared-forms/input-switch.component.ts
  25. +6
    -4
      client/src/app/shared/shared-forms/shared-form.module.ts
  26. +5
    -0
      client/src/app/shared/shared-forms/timestamp-input.component.scss
  27. +1
    -1
      client/src/assets/player/p2p-media-loader/hls-plugin.ts
  28. +0
    -24
      client/src/hmr.ts
  29. +1
    -12
      client/src/main.ts
  30. +1
    -1
      client/src/sass/application.scss
  31. +552
    -92
      client/src/sass/primeng-custom.scss
  32. +22
    -22
      client/webpack/webpack.video-embed.js
  33. +2218
    -2044
      client/yarn.lock

+ 0
- 2
client/angular.json View File

@@ -177,7 +177,6 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
@@ -208,7 +207,6 @@
"optimization": false,
"outputHashing": "none",
"sourceMap": true,
"extractCss": true,
"namedChunks": true,
"aot": true,
"buildOptimizer": false,


+ 39
- 38
client/package.json View File

@@ -26,24 +26,26 @@
"sass-lint": "sass-lint"
},
"typings": "*.d.ts",
"resolutions": {
"@types/mousetrap": "1.6.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.1001.0-next.6",
"@angular/animations": "^10.1.0-next.8",
"@angular/cdk": "^10.0.0",
"@angular/cli": "^10.1.0-next.6",
"@angular/common": "^10.1.0-next.8",
"@angular/compiler": "^10.1.0-next.8",
"@angular/compiler-cli": "^10.1.0-next.8",
"@angular/core": "^10.1.0-next.8",
"@angular/forms": "^10.1.0-next.8",
"@angular/localize": "^10.1.0-next.8",
"@angular/platform-browser": "^10.1.0-next.8",
"@angular/platform-browser-dynamic": "^10.1.0-next.8",
"@angular/router": "^10.1.0-next.8",
"@angular/service-worker": "^10.1.0-next.8",
"@angularclass/hmr": "^2.1.3",
"@angular-devkit/build-angular": "^0.1100.2",
"@angular/animations": "^11.0.1",
"@angular/cdk": "^11.0.0",
"@angular/cli": "^11.0.2",
"@angular/common": "^11.0.1",
"@angular/compiler": "^11.0.1",
"@angular/compiler-cli": "^11.0.1",
"@angular/core": "^11.0.1",
"@angular/forms": "^11.0.1",
"@angular/localize": "^11.0.1",
"@angular/platform-browser": "^11.0.1",
"@angular/platform-browser-dynamic": "^11.0.1",
"@angular/router": "^11.0.1",
"@angular/service-worker": "^11.0.1",
"@neos21/bootstrap3-glyphicons": "^1.0.1",
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
"@ng-bootstrap/ng-bootstrap": "^8.0.0",
"@ng-select/ng-select": "^5.0.0",
"@ngx-i18nsupport/ngx-i18nsupport": "^1.1.6",
"@ngx-i18nsupport/tooling": "^8.0.3",
@@ -62,23 +64,21 @@
"@types/lodash-es": "^4.17.0",
"@types/markdown-it": "^10.0.1",
"@types/node": "^14.0.14",
"@types/sanitize-html": "1.23.3",
"@types/sanitize-html": "1.27.0",
"@types/sha.js": "^2.4.0",
"@types/socket.io-client": "^1.4.32",
"@types/video.js": "^7.3.8",
"@types/webtorrent": "^0.107.0",
"@types/webtorrent": "^0.109.0",
"angular2-hotkeys": "^2.1.2",
"angularx-qrcode": "10.0.6",
"angularx-qrcode": "10.0.11",
"bootstrap": "^4.1.3",
"buffer": "^5.1.0",
"buffer": "^6.0.2",
"cache-chunk-store": "^3.0.0",
"chart.js": "^2.9.3",
"codelyzer": "^6.0.0",
"core-js": "^3.1.4",
"css-loader": "^3.1.0",
"debug": "^4.1.1",
"css-loader": "^5.0.1",
"debug": "^4.3.1",
"dexie": "^3.0.0",
"extract-text-webpack-plugin": "4.0.0-beta.0",
"file-loader": "^6.0.0",
"focus-visible": "^5.0.2",
"hls.js": "^0.14.16",
@@ -86,52 +86,53 @@
"html-webpack-plugin": "^4.0.3",
"https-browserify": "^1.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"jasmine-spec-reporter": "~6.0.0",
"jschannel": "^1.0.2",
"karma": "~5.1.0",
"karma": "~5.2.3",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.1",
"karma-jasmine-html-reporter": "^1.5.0",
"linkifyjs": "^2.1.5",
"lodash-es": "^4.17.4",
"markdown-it": "11.x",
"node-sass": "^4.9.3",
"markdown-it": "12.0.2",
"mini-css-extract-plugin": "^1.3.1",
"node-sass": "^5.0.0",
"npm-font-source-sans-pro": "^1.0.2",
"p2p-media-loader-hlsjs": "^0.6.2",
"path-browserify": "^1.0.0",
"primeng": "^9.0.0-rc.4",
"primeng": "^11.0.0-rc.1",
"process": "^0.11.10",
"protractor": "~7.0.0",
"purify-css": "^1.2.5",
"purifycss-webpack": "^0.7.0",
"raw-loader": "^4.0.0",
"rxjs": "^6.5.2",
"sanitize-html": "^1.18.4",
"sanitize-html": "^2.1.2",
"sass-lint": "^1.13.1",
"sass-loader": "8.0.2",
"sass-loader": "10.1.0",
"sass-resources-loader": "^2.0.0",
"sha.js": "^2.4.11",
"socket.io-client": "^2.2.0",
"socket.io-client": "^3.0.3",
"stream-browserify": "^3.0.0",
"stream-http": "^3.0.0",
"terser-webpack-plugin": "^3.0.0",
"terser-webpack-plugin": "^4",
"ts-loader": "^8.0.2",
"tslib": "^2.0.0",
"tslint": "~6.1.0",
"tslint-angular": "^3.0.2",
"tslint-config-standard": "^9.0.0",
"typescript": "~3.9.5",
"typescript": "~4.0.5",
"video.js": "^7",
"videojs-contextmenu-ui": "^5.0.0",
"videojs-contrib-quality-levels": "^2.0.9",
"videojs-dock": "^2.0.2",
"videojs-hotkeys": "^0.2.27",
"videostream": "~3.2.1",
"webpack-bundle-analyzer": "^3.0.2",
"webpack-cli": "^3.0.8",
"webtorrent": "^0.108.1",
"webpack-bundle-analyzer": "^4.1.0",
"webpack-cli": "^4.2.0",
"webtorrent": "^0.111.0",
"whatwg-fetch": "^3.0.0",
"zone.js": "~0.10.2"
"zone.js": "~0.11.3"
}
}

+ 1
- 1
client/src/app/+admin/admin.component.html View File

@@ -1,4 +1,4 @@
<div>
<div class="root">
<my-top-menu-dropdown [menuEntries]="menuEntries"></my-top-menu-dropdown>

<div class="margin-content" [ngClass]="{ 'offset-content': !isBroadcastMessageDisplayed }">


+ 3
- 1
client/src/app/+admin/admin.component.scss View File

@@ -5,4 +5,6 @@ my-top-menu-dropdown {
flex-grow: 1;
}

@include sub-menu-h1;
.root {
@include sub-menu-h1;
}

+ 0
- 1
client/src/app/+admin/follows/following-list/following-list.component.ts View File

@@ -6,7 +6,6 @@ import { BatchDomainsModalComponent } from '@app/shared/shared-moderation'
import { ActorFollow } from '@shared/models'

@Component({
selector: 'my-followers-list',
templateUrl: './following-list.component.html',
styleUrls: [ '../follows.component.scss', './following-list.component.scss' ]
})


+ 0
- 28
client/src/app/+admin/plugins/shared/toggle-plugin-type.scss View File

@@ -5,32 +5,4 @@
display: flex;
justify-content: center;
margin-bottom: 30px;

p-selectButton {
::ng-deep {
.ui-button-text {
font-size: 15px;
font-weight: 600;
}

.ui-button.ui-state-default {
background-color: #f0f0f0;
border: 1px solid #f0f0f0;
}

.ui-button.ui-state-active {
background-color: pvar(--mainColor);
border-color: pvar(--mainColor);

&:hover {
background-color: pvar(--mainHoverColor);
border-color: pvar(--mainHoverColor);
}
}

.ui-button:not(.ui-state-active).ui-state-focus {
box-shadow: 0 0 0 .1rem rgba(87, 85, 217, .2);
}
}
}
}

+ 8
- 2
client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html View File

@@ -9,11 +9,17 @@
<div>{{ labelNotifications[notificationType] }}</div>

<div>
<p-inputSwitch [(ngModel)]="webNotifications[notificationType]" (onChange)="updateWebSetting(notificationType, $event.checked)"></p-inputSwitch>
<my-input-switch
[(ngModel)]="webNotifications[notificationType]"
(ngModelChange)="updateWebSetting(notificationType, webNotifications[notificationType])"
></my-input-switch>
</div>

<div *ngIf="emailEnabled">
<p-inputSwitch [(ngModel)]="emailNotifications[notificationType]" (onChange)="updateEmailSetting(notificationType, $event.checked)"></p-inputSwitch>
<my-input-switch
[(ngModel)]="emailNotifications[notificationType]"
(ngModelChange)="updateEmailSetting(notificationType, emailNotifications[notificationType])"
></my-input-switch>
</div>
</div>
</ng-container>

+ 0
- 2
client/src/app/+my-account/my-account.module.ts View File

@@ -1,5 +1,4 @@
import { AutoCompleteModule } from 'primeng/autocomplete'
import { InputSwitchModule } from 'primeng/inputswitch'
import { TableModule } from 'primeng/table'
import { DragDropModule } from '@angular/cdk/drag-drop'
import { NgModule } from '@angular/core'
@@ -29,7 +28,6 @@ import { MyAccountComponent } from './my-account.component'

AutoCompleteModule,
TableModule,
InputSwitchModule,
DragDropModule,

SharedMainModule,


+ 1
- 1
client/src/app/+my-library/+my-video-channels/my-video-channels.component.html View File

@@ -42,7 +42,7 @@
</div>

<div *ngIf="!isInSmallView" class="w-100 d-flex justify-content-end">
<p-chart *ngIf="videoChannelsChartData && videoChannelsChartData[i]" type="line" [data]="videoChannelsChartData[i]" [options]="chartOptions" width="40vw" height="100px"></p-chart>
<p-chart *ngIf="chartOptions && videoChannelsChartData && videoChannelsChartData[i]" type="line" [data]="videoChannelsChartData[i]" [options]="chartOptions" width="40vw" height="100px"></p-chart>
</div>
</div>
</div>


+ 54
- 49
client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts View File

@@ -21,6 +21,8 @@ export class MyVideoChannelsComponent implements OnInit {
channelsSearch: string
channelsSearchChanged = new Subject<string>()

chartOptions: any

private user: User

constructor (
@@ -47,55 +49,6 @@ export class MyVideoChannelsComponent implements OnInit {
return this.screenService.isInSmallView()
}

get chartOptions () {
return {
legend: {
display: false
},
scales: {
xAxes: [{
display: false
}],
yAxes: [{
display: false,
ticks: {
min: Math.max(0, this.videoChannelsMinimumDailyViews - (3 * this.videoChannelsMaximumDailyViews / 100)),
max: Math.max(1, this.videoChannelsMaximumDailyViews)
}
}]
},
layout: {
padding: {
left: 15,
right: 15,
top: 10,
bottom: 0
}
},
elements: {
point: {
radius: 0
}
},
tooltips: {
mode: 'index',
intersect: false,
custom: function (tooltip: any) {
if (!tooltip) return
// disable displaying the color box
tooltip.displayColors = false
},
callbacks: {
label: (tooltip: any, data: any) => `${tooltip.value} views`
}
},
hover: {
mode: 'index',
intersect: false
}
}
}

resetSearch () {
this.channelsSearch = ''
this.onChannelsSearchChanged()
@@ -159,6 +112,7 @@ channel with the same name (${videoChannel.name})!`,
day => day.views
).views) // the object returned is a ViewPerDate, so we still need to get the views attribute
)

this.videoChannelsMaximumDailyViews = max(
// compute local maximum daily views for each channel, by their "views" attribute
this.videoChannels.map(v => maxBy(
@@ -166,6 +120,57 @@ channel with the same name (${videoChannel.name})!`,
day => day.views
).views) // the object returned is a ViewPerDate, so we still need to get the views attribute
)

this.buildChartOptions()
})
}

private buildChartOptions () {
this.chartOptions = {
legend: {
display: false
},
scales: {
xAxes: [{
display: false
}],
yAxes: [{
display: false,
ticks: {
min: Math.max(0, this.videoChannelsMinimumDailyViews - (3 * this.videoChannelsMaximumDailyViews / 100)),
max: Math.max(1, this.videoChannelsMaximumDailyViews)
}
}]
},
layout: {
padding: {
left: 15,
right: 15,
top: 10,
bottom: 0
}
},
elements: {
point: {
radius: 0
}
},
tooltips: {
mode: 'index',
intersect: false,
custom: function (tooltip: any) {
if (!tooltip) return
// disable displaying the color box
tooltip.displayColors = false
},
callbacks: {
label: (tooltip: any, data: any) => `${tooltip.value} views`
}
},
hover: {
mode: 'index',
intersect: false
}
}
}
}

+ 1
- 1
client/src/app/+my-library/my-history/my-history.component.html View File

@@ -5,7 +5,7 @@

<div class="top-buttons">
<div class="history-switch">
<p-inputSwitch [(ngModel)]="videosHistoryEnabled" (ngModelChange)="onVideosHistoryChange()"></p-inputSwitch>
<my-input-switch [(ngModel)]="videosHistoryEnabled" (ngModelChange)="onVideosHistoryChange()"></my-input-switch>
<label i18n>Video history</label>
</div>



+ 5
- 1
client/src/app/+my-library/my-history/my-history.component.ts View File

@@ -47,7 +47,11 @@ export class MyHistoryComponent extends AbstractVideoList implements OnInit, OnD
ngOnInit () {
super.ngOnInit()

this.videosHistoryEnabled = this.authService.getUser().videosHistoryEnabled
this.authService.userInformationLoaded
.subscribe(() => {
this.videosHistoryEnabled = this.authService.getUser().videosHistoryEnabled
})

}

ngOnDestroy () {


+ 0
- 2
client/src/app/+my-library/my-library.module.ts View File

@@ -1,5 +1,4 @@
import { AutoCompleteModule } from 'primeng/autocomplete'
import { InputSwitchModule } from 'primeng/inputswitch'
import { TableModule } from 'primeng/table'
import { DragDropModule } from '@angular/cdk/drag-drop'
import { NgModule } from '@angular/core'
@@ -34,7 +33,6 @@ import { MyVideosComponent } from './my-videos/my-videos.component'

AutoCompleteModule,
TableModule,
InputSwitchModule,
DragDropModule,

SharedMainModule,


+ 2
- 3
client/src/app/+videos/+video-edit/shared/video-edit.component.scss View File

@@ -150,12 +150,11 @@ p-calendar {
display: block;

::ng-deep {
input,
.ui-calendar {
.p-calendar {
width: 100%;
}

input {
.p-inputtext {
@include peertube-input-text(100%);
color: #000;
}


+ 4
- 3
client/src/app/+videos/+video-watch/recommendations/recommendations.module.ts View File

@@ -1,6 +1,7 @@
import { InputSwitchModule } from 'primeng/inputswitch'
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { SharedFormModule } from '@app/shared/shared-forms'
import { SharedMainModule } from '@app/shared/shared-main'
import { SharedSearchModule } from '@app/shared/shared-search'
import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature'
@@ -12,12 +13,12 @@ import { RecommendedVideosStore } from './recommended-videos.store'
@NgModule({
imports: [
CommonModule,
InputSwitchModule,

SharedMainModule,
SharedSearchModule,
SharedVideoPlaylistModule,
SharedVideoMiniatureModule
SharedVideoMiniatureModule,
SharedFormModule
],
declarations: [
RecommendedVideosComponent


+ 1
- 1
client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.html View File

@@ -8,7 +8,7 @@
[ngbTooltip]="autoPlayNextVideoTooltip" placement="bottom-right auto"
>
<span i18n>AUTOPLAY</span>
<p-inputSwitch class="small" [(ngModel)]="autoPlayNextVideo" (ngModelChange)="switchAutoPlayNextVideo()"></p-inputSwitch>
<my-input-switch class="small" [(ngModel)]="autoPlayNextVideo" (ngModelChange)="switchAutoPlayNextVideo()"></my-input-switch>
</div>
</div>



+ 5
- 2
client/src/app/app.component.ts View File

@@ -11,7 +11,7 @@ import { PluginService } from '@app/core/plugins/plugin.service'
import { CustomModalComponent } from '@app/modal/custom-modal.component'
import { InstanceConfigWarningModalComponent } from '@app/modal/instance-config-warning-modal.component'
import { WelcomeModalComponent } from '@app/modal/welcome-modal.component'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbConfig, NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
import { getShortLocale, is18nPath } from '@shared/core-utils/i18n'
import { BroadcastMessageLevel, ServerConfig, UserRole } from '@shared/models'
@@ -54,8 +54,11 @@ export class AppComponent implements OnInit, AfterViewInit {
private location: PlatformLocation,
private modalService: NgbModal,
private markdownService: MarkdownService,
private ngbConfig: NgbConfig,
public menu: MenuService
) { }
) {
this.ngbConfig.animation = false
}

get instanceName () {
return this.serverConfig.instance.name


+ 5
- 4
client/src/app/core/notification/peertube-socket.service.ts View File

@@ -3,18 +3,19 @@ import { Injectable, NgZone } from '@angular/core'
import { LiveVideoEventPayload, LiveVideoEventType, UserNotification as UserNotificationServer } from '@shared/models'
import { environment } from '../../../environments/environment'
import { AuthService } from '../auth'
import { io, Socket } from 'socket.io-client'

export type NotificationEvent = 'new' | 'read' | 'read-all'

@Injectable()
export class PeerTubeSocket {
private io: typeof import ('socket.io-client')
private io: typeof io

private notificationSubject = new Subject<{ type: NotificationEvent, notification?: UserNotificationServer }>()
private liveVideosSubject = new Subject<{ type: LiveVideoEventType, payload: LiveVideoEventPayload }>()

private notificationSocket: SocketIOClient.Socket
private liveVideosSocket: SocketIOClient.Socket
private notificationSocket: Socket
private liveVideosSocket: Socket

constructor (
private auth: AuthService,
@@ -77,7 +78,7 @@ export class PeerTubeSocket {
private async importIOIfNeeded () {
if (this.io) return

this.io = (await import('socket.io-client') as any).default
this.io = (await import('socket.io-client')).io
}

private dispatchLiveVideoEvent (type: LiveVideoEventType, payload: LiveVideoEventPayload) {


+ 2
- 1
client/src/app/menu/menu.component.html View File

@@ -54,7 +54,8 @@
<a ngbDropdownItem class="dropdown-item" (click)="toggleUseP2P()">
<my-global-icon iconName="p2p" aria-hidden="true"></my-global-icon>
<ng-container i18n>Help share videos</ng-container>
<input type="checkbox" [checked]="user.webTorrentEnabled"/><label class="ml-auto" for="switch">Toggle p2p</label>

<my-input-switch class="ml-auto" [checked]="user.webTorrentEnabled"></my-input-switch>
</a>

<div class="dropdown-divider"></div>


+ 0
- 42
client/src/app/menu/menu.component.scss View File

@@ -352,48 +352,6 @@ menu {
color: #6c757d;
}

input[type=checkbox]{
position: absolute;
visibility: hidden;
}

label {
cursor: pointer;
text-indent: -9999px;
width: 35px;
height: 20px;
background: #cccccc;
display: block;
border-radius: 100px;
position: relative;
margin: 0;

&:after {
content: '';
position: absolute;
top: 3px;
left: 3px;
width: 14px;
height: 14px;
background: pvar(--mainBackgroundColor);
border-radius: 50%;
transition: 0.3s ease-out;
}

&:active:after {
width: 40px;
}
}

input:checked + label {
background: pvar(--mainColor);

&:after {
left: calc(100% - 3px);
transform: translateX(-100%);
}
}

@media screen and (max-width: $mobile-view) {
.menu-wrapper {
width: 100% !important;


+ 1
- 0
client/src/app/shared/shared-forms/index.ts View File

@@ -2,6 +2,7 @@ export * from './form-validator.service'
export * from './form-reactive'
export * from './select'
export * from './input-readonly-copy.component'
export * from './input-switch.component'
export * from './markdown-textarea.component'
export * from './peertube-checkbox.component'
export * from './preview-upload.component'


+ 4
- 0
client/src/app/shared/shared-forms/input-switch.component.html View File

@@ -0,0 +1,4 @@
<div (click)="update()">
<input type="checkbox" [checked]="checked"/>
<label class="ml-auto">Toggle</label>
</div>

+ 44
- 0
client/src/app/shared/shared-forms/input-switch.component.scss View File

@@ -0,0 +1,44 @@
@import '_variables';
@import '_mixins';

input {
position: absolute;
visibility: hidden;

& + label {
cursor: pointer;
text-indent: -9999px;
width: 35px;
height: 20px;
background: #cccccc;
display: block;
border-radius: 100px;
position: relative;
margin: 0;

&:after {
content: '';
position: absolute;
top: 3px;
left: 3px;
width: 14px;
height: 14px;
background: pvar(--mainBackgroundColor);
border-radius: 50%;
transition: 0.3s ease-out;
}

&:active:after {
width: 40px;
}
}

&:checked + label {
background: pvar(--mainColor);

&:after {
left: calc(100% - 3px);
transform: translateX(-100%);
}
}
}

+ 38
- 0
client/src/app/shared/shared-forms/input-switch.component.ts View File

@@ -0,0 +1,38 @@
import { Component, forwardRef, Input } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'

@Component({
selector: 'my-input-switch',
styleUrls: [ './input-switch.component.scss' ],
templateUrl: './input-switch.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputSwitchComponent),
multi: true
}
]
})
export class InputSwitchComponent implements ControlValueAccessor {
@Input() checked = false
@Input() inputName: string

propagateChange = (_: any) => { /* empty */ }

writeValue (checked: boolean) {
this.checked = checked
}

registerOnChange (fn: (_: any) => void) {
this.propagateChange = fn
}

registerOnTouched () {
// Unused
}

update () {
this.checked = !this.checked
this.propagateChange(this.checked)
}
}

+ 6
- 4
client/src/app/shared/shared-forms/shared-form.module.ts View File

@@ -1,13 +1,14 @@

import { InputMaskModule } from 'primeng/inputmask'
import { InputSwitchModule } from 'primeng/inputswitch'
import { NgModule } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgSelectModule } from '@ng-select/ng-select'
import { SharedGlobalIconModule } from '../shared-icons'
import { SharedMainModule } from '../shared-main/shared-main.module'
import { DynamicFormFieldComponent } from './dynamic-form-field.component'
import { FormValidatorService } from './form-validator.service'
import { InputReadonlyCopyComponent } from './input-readonly-copy.component'
import { InputSwitchComponent } from './input-switch.component'
import { MarkdownTextareaComponent } from './markdown-textarea.component'
import { PeertubeCheckboxComponent } from './peertube-checkbox.component'
import { PreviewUploadComponent } from './preview-upload.component'
@@ -15,7 +16,6 @@ import { ReactiveFileComponent } from './reactive-file.component'
import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select'
import { TextareaAutoResizeDirective } from './textarea-autoresize.directive'
import { TimestampInputComponent } from './timestamp-input.component'
import { DynamicFormFieldComponent } from './dynamic-form-field.component'

@NgModule({
imports: [
@@ -23,7 +23,6 @@ import { DynamicFormFieldComponent } from './dynamic-form-field.component'
ReactiveFormsModule,

InputMaskModule,
InputSwitchModule,
NgSelectModule,

SharedMainModule,
@@ -39,6 +38,8 @@ import { DynamicFormFieldComponent } from './dynamic-form-field.component'
TextareaAutoResizeDirective,
TimestampInputComponent,

InputSwitchComponent,

SelectChannelComponent,
SelectOptionsComponent,
SelectTagsComponent,
@@ -52,7 +53,6 @@ import { DynamicFormFieldComponent } from './dynamic-form-field.component'
ReactiveFormsModule,

InputMaskModule,
InputSwitchModule,
NgSelectModule,

InputReadonlyCopyComponent,
@@ -63,6 +63,8 @@ import { DynamicFormFieldComponent } from './dynamic-form-field.component'
TextareaAutoResizeDirective,
TimestampInputComponent,

InputSwitchComponent,

SelectChannelComponent,
SelectOptionsComponent,
SelectTagsComponent,


+ 5
- 0
client/src/app/shared/shared-forms/timestamp-input.component.scss View File

@@ -11,5 +11,10 @@ p-inputmask {
&:focus {
box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest);
}

&:disabled {
background: pvar(--mainBackgroundColor);
opacity: 0.5;
}
}
}

+ 1
- 1
client/src/assets/player/p2p-media-loader/hls-plugin.ts View File

@@ -13,7 +13,7 @@ type Metadata = {
levels: Hlsjs.Level[]
}

type CustomAudioTrack = Hlsjs.AudioTrack & { name?: string, lang?: string }
type CustomAudioTrack = Hlsjs.HlsAudioTrack & { name?: string, lang?: string }

const registerSourceHandler = function (vjs: typeof videojs) {
if (!Hlsjs.isSupported()) {


+ 0
- 24
client/src/hmr.ts View File

@@ -1,24 +0,0 @@
import { NgModuleRef, ApplicationRef } from '@angular/core'
import { createNewHosts } from '@angularclass/hmr'
import { enableDebugTools } from '@angular/platform-browser'

export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
let ngModule: NgModuleRef<any>
module.hot.accept()
bootstrap()
.then(mod => {
ngModule = mod

const applicationRef = ngModule.injector.get(ApplicationRef)
const componentRef = applicationRef.components[ 0 ]
// allows to run `ng.profiler.timeChangeDetection();`
enableDebugTools(componentRef)
})
module.hot.dispose(() => {
const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef)
const elements = appRef.components.map(c => c.location.nativeElement)
const makeVisible = createNewHosts(elements)
ngModule.destroy()
makeVisible()
})
}

+ 1
- 12
client/src/main.ts View File

@@ -4,8 +4,6 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
import { AppModule } from './app/app.module'
import { environment } from './environments/environment'

import { hmrBootstrap } from './hmr'

if (environment.production) {
enableProdMode()
}
@@ -36,13 +34,4 @@ const bootstrap = () => platformBrowserDynamic()
return null
})

if (environment.hmr) {
if (module[ 'hot' ]) {
hmrBootstrap(module, bootstrap)
} else {
console.error('HMR is not enabled for webpack-dev-server!')
console.log('Are you using the --hmr flag for ng serve?')
}
} else {
bootstrap()
}
bootstrap()

+ 1
- 1
client/src/sass/application.scss View File

@@ -21,7 +21,7 @@ $assets-path: '../../assets/';

body {
/*** theme ***/
// now beware node-sass requires interpolation
// now beware sass requires interpolation
// for css custom properties #{$var}
--mainColor: #{$main-color};
--mainColorLighter: #{$main-color-lighter};


+ 552
- 92
client/src/sass/primeng-custom.scss View File

@@ -2,7 +2,487 @@
@import '_mixins';

@import '~primeng/resources/primeng.css';
@import '~primeng/resources/themes/nova-light/theme.css';

// Taken from old nova light theme

body .p-disabled {
opacity: 0.5;
}

// Checkbox
body .p-checkbox {
display: inline-block;
vertical-align: middle;
margin: 0;
width: 20px;
height: 20px;
}
body .p-checkbox .p-checkbox-box {
border: 1px solid #a6a6a6;
background-color: #ffffff;
width: 20px;
height: 20px;
text-align: center;
border-radius: 3px;
transition: background-color 0.2s, border-color 0.2s, box-shadow 0.2s;
}
body .p-checkbox .p-checkbox-box:not(.p-disabled):hover {
border-color: #212121;
}
body .p-checkbox .p-checkbox-box .p-checkbox-icon {
overflow: hidden;
position: relative;
font-size: 18px;
}

// Paginator
body .p-paginator {
background-color: #f4f4f4;
border: 1px solid #c8c8c8;
padding: 0;
}
body .p-paginator .p-paginator-first,
body .p-paginator .p-paginator-prev,
body .p-paginator .p-paginator-next,
body .p-paginator .p-paginator-last {
color: #848484;
height: 2.286em;
min-width: 2.286em;
border: 0 none;
line-height: 2.286em;
padding: 0;
margin: 0;
vertical-align: top;
transition: box-shadow 0.2s;
border-radius: 0;
}
body .p-paginator .p-paginator-first:not(.p-disabled):not(.p-highlight):hover,
body .p-paginator .p-paginator-prev:not(.p-disabled):not(.p-highlight):hover,
body .p-paginator .p-paginator-next:not(.p-disabled):not(.p-highlight):hover,
body .p-paginator .p-paginator-last:not(.p-disabled):not(.p-highlight):hover {
background-color: #e0e0e0;
color: #333333;
}
body .p-paginator .p-paginator-first:focus,
body .p-paginator .p-paginator-prev:focus,
body .p-paginator .p-paginator-next:focus,
body .p-paginator .p-paginator-last:focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2em pvar(--mainColorLightest);
}
body .p-paginator .p-paginator-current {
color: #333333;
height: 2.286em;
min-width: 2.286em;
line-height: 2.286em;
}
body .p-paginator .p-dropdown {
border: 0 none;
}
body .p-paginator .p-dropdown .p-dropdown-trigger, body .p-paginator .p-dropdown .p-dropdown-label {
color: #848484;
}
body .p-paginator .p-dropdown:hover .p-dropdown-trigger, body .p-paginator .p-dropdown:hover .p-dropdown-label {
color: #333333;
}
body .p-paginator .p-paginator-first:before {
position: relative;
top: 1px;
}
body .p-paginator .p-paginator-prev:before {
position: relative;
top: 1px;
}
body .p-paginator .p-paginator-next:before {
position: relative;
top: 1px;
}
body .p-paginator .p-paginator-last:before {
position: relative;
top: 1px;
}
body .p-paginator .p-paginator-pages {
vertical-align: top;
display: inline-block;
padding: 0;
}
body .p-paginator .p-paginator-pages .p-paginator-page {
color: #848484;
height: 2.286em;
min-width: 2.286em;
border: 0 none;
line-height: 2.286em;
padding: 0;
margin: 0;
vertical-align: top;
transition: box-shadow 0.2s;
border-radius: 0;
}
body .p-paginator .p-paginator-pages .p-paginator-page:not(.p-highlight):hover {
background-color: #e0e0e0;
color: #333333;
}
body .p-paginator .p-paginator-pages .p-paginator-page:focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2em pvar(--mainColorLightest);
}
body .p-paginator .p-dropdown {
margin-left: 0.5em;
height: 2.286em;
min-width: auto;
}

// Dropdown

body .p-dropdown {
background: #ffffff;
border: 1px solid #a6a6a6;
transition: border-color 0.2s, box-shadow 0.2s;
}
body .p-dropdown:not(.p-disabled):hover {
border-color: #212121;
}
body .p-dropdown:not(.p-disabled).p-focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2em pvar(--mainColorLightest);
border-color: pvar(--mainColor);
}
body .p-dropdown .p-dropdown-label {
padding-right: 2em;
}
body .p-dropdown .p-dropdown-trigger {
background-color: #ffffff;
width: 2em;
line-height: 2em;
text-align: center;
padding: 0;
color: #848484;
}
body .p-dropdown .p-dropdown-clear-icon {
color: #848484;
}
body .p-dropdown.p-dropdown-clearable .p-dropdown-label {
padding-right: 4em;
}
body .p-dropdown-panel {
padding: 0;
border: 1px solid #c8c8c8;
background-color: #ffffff;
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
}
body .p-dropdown-panel .p-dropdown-filter-container {
padding: 0.429em 0.857em 0.429em 0.857em;
border-bottom: 1px solid #eaeaea;
color: #333333;
background-color: #ffffff;
margin: 0;
}
body .p-dropdown-panel .p-dropdown-filter-container .p-dropdown-filter {
width: 100%;
padding-right: 2em;
}
body .p-dropdown-panel .p-dropdown-filter-container .p-dropdown-filter-icon {
top: 50%;
margin-top: -0.5em;
right: 1.357em;
color: pvar(--mainColor);
}
body .p-dropdown-panel .p-dropdown-items {
padding: 0;
}
body .p-dropdown-panel .p-dropdown-items .p-dropdown-item, body .p-dropdown-panel .p-dropdown-items .p-dropdown-item-group {
margin: 0;
padding: 0.429em 0.857em;
border: 0 none;
color: #333333;
background-color: transparent;
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
}
body .p-dropdown-panel .p-dropdown-items .p-dropdown-item.p-highlight,
body .p-dropdown-panel .p-dropdown-items .p-dropdown-item-group.p-highlight {
color: #ffffff;
background-color: pvar(--mainColor);
}
body .p-dropdown-panel .p-dropdown-items .p-dropdown-item:not(.p-highlight):not(.p-disabled):hover,
body .p-dropdown-panel .p-dropdown-items .p-dropdown-item-group:not(.p-highlight):not(.p-disabled):hover {
color: #333333;
background-color: #eaeaea;
}
body p-dropdown.ng-dirty.ng-invalid > .p-dropdown {
border: 1px solid #a80000;
}

// p-toast
body .p-toast .p-toast-message {
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
margin: 0 0 1em 0;
}

// p-calendar
body .p-datepicker {
padding: 0.857em;
min-width: 20em;
background-color: #ffffff;
color: #333333;
border: 1px solid #a6a6a6;
}

body .p-datepicker:not(.p-datepicker-inline) {
border: 1px solid #c8c8c8;
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
}
body .p-datepicker:not(.p-disabled) .p-datepicker-header .p-datepicker-prev:focus,
body .p-datepicker:not(.p-disabled) .p-datepicker-header .p-datepicker-next:focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2em pvar(--mainColorLightest);
}
body .p-datepicker:not(.p-disabled) table td a:not(.p-highlight):not(.p-highlight):hover {
background-color: #eaeaea;
}
body .p-datepicker:not(.p-disabled) .p-monthpicker a.p-monthpicker-month:not(.p-highlight):hover {
background-color: #eaeaea;
}
body .p-datepicker .p-datepicker-header {
padding: 0.429em 0.857em 0.429em 0.857em;
background-color: #ffffff;
color: #333333;
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
}
body .p-datepicker .p-datepicker-header .p-datepicker-prev,
body .p-datepicker .p-datepicker-header .p-datepicker-next {
cursor: pointer;
top: 0;
color: #a6a6a6;
transition: color 0.2s, box-shadow 0.2s;
}
body .p-datepicker .p-datepicker-header .p-datepicker-title {
margin: 0;
padding: 0;
line-height: 1;
}
body .p-datepicker .p-datepicker-header .p-datepicker-title select {
margin-top: -0.35em;
margin-bottom: 0;
transition: color 0.2s, box-shadow 0.2s;
}
body .p-datepicker .p-datepicker-header .p-datepicker-title select:focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2em pvar(--mainColorLightest);
}
body .p-datepicker table {
font-size: 14px;
margin: 0.857em 0 0 0;
}
body .p-datepicker table th {
padding: 0.5em;
}
body .p-datepicker table th.p-datepicker-weekheader {
border-right: 1px solid #a6a6a6;
}
body .p-datepicker table td {
padding: 0.5em;
}
body .p-datepicker table td > a,
body .p-datepicker table td > span {
display: block;
text-align: center;
color: #333333;
padding: 0.5em;
transition: box-shadow 0.2s;
border-radius: 3px;
}
body .p-datepicker table td > a.p-highlight,
body .p-datepicker table td > span.p-highlight {
color: #ffffff;
background-color: pvar(--mainColor);
}
body .p-datepicker table td > a {
cursor: pointer;
}
body .p-datepicker table td > a:focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2em pvar(--mainColorLightest);
}
body .p-datepicker table td.p-datepicker-today > a,
body .p-datepicker table td.p-datepicker-today > span {
background-color: #d0d0d0;
color: #333333;
}
body .p-datepicker table td.p-datepicker-today > a.p-highlight,
body .p-datepicker table td.p-datepicker-today > span.p-highlight {
color: #ffffff;
background-color: pvar(--mainColor);
}
body .p-datepicker table td.p-datepicker-weeknumber {
border-right: 1px solid #a6a6a6;
}
body .p-datepicker .p-datepicker-buttonbar {
border-top: 1px solid #d8dae2;
}
body .p-datepicker .p-timepicker {
border: 0 none;
border-top: 1px solid #d8dae2;
padding: 0.857em;
}
body .p-datepicker .p-timepicker a {
color: #333333;
font-size: 1.286em;
}
body .p-datepicker .p-timepicker a:hover {
color: pvar(--mainColor);
}
body .p-datepicker .p-timepicker span {
font-size: 1.286em;
}
body .p-datepicker .p-monthpicker .p-monthpicker-month {
color: #333333;
}
body .p-datepicker .p-monthpicker .p-monthpicker-month.p-highlight {
color: #ffffff;
background-color: pvar(--mainColor);
}
body .p-datepicker.p-datepicker-timeonly {
padding: 0;
}
body .p-datepicker.p-datepicker-timeonly .p-timepicker {
border-top: 0 none;
}
body .p-datepicker.p-datepicker-multiple-month .p-datepicker-group {
border-right: 1px solid #d8dae2;
padding-right: 0.857em;
padding-left: 0.857em;
padding-top: 0;
padding-bottom: 0;
}
body .p-datepicker.p-datepicker-multiple-month .p-datepicker-group:first-child {
padding-left: 0;
}
body .p-datepicker.p-datepicker-multiple-month .p-datepicker-group:last-child {
padding-right: 0;
border-right: 0 none;
}
body .p-calendar.p-calendar-w-btn .p-inputtext {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0 none;
}
body .p-calendar.p-calendar-w-btn .p-inputtext:enabled:hover:not(.p-error),
body .p-calendar.p-calendar-w-btn .p-inputtext:enabled:focus:not(.p-error) {
border-right: 0 none;
}
body .p-calendar.p-calendar-w-btn .p-datepicker-trigger.p-button {
width: 2.357em;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
body .ui-fluid .p-calendar.p-calendar-w-btn input.p-inputtext {
width: calc(100% - 2.357em);
}
body p-calendar.ng-dirty.ng-invalid > .p-calendar > .p-inputtext {
border: 1px solid #a80000;
}
body .p-timepicker .p-separator {
margin-left: 0;
min-width: 0.75rem;
}

// auto complete
body .p-autocomplete .p-autocomplete-input {
padding: 0.429em;
}
body .p-autocomplete-panel {
padding: 0;
border: 1px solid #c8c8c8;
background-color: #ffffff;
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
}
body .p-autocomplete-panel .p-autocomplete-items {
padding: 0;
}
body .p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item {
margin: 0;
padding: 0.429em 0.857em;
border: 0 none;
color: #333333;
background-color: transparent;
border-radius: 0;
}
body .p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item.p-highlight,
body .p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item:hover {
color: #ffffff;
background-color: pvar(--mainColor);
}
body .p-autocomplete-panel .p-autocomplete-items .p-autocomplete-group {
padding: 0.429em 0.857em;
background-color: #d8dae2;
color: #333333;
}
body p-autocomplete.ng-dirty.ng-invalid > .p-autocomplete > .p-inputtext {
border: 1px solid #a80000;
}

// select button
body .p-selectbutton .p-button {
background-color: #dadada;
border: 1px solid #dadada;
color: #333333;
overflow: hidden;
transition: background-color 0.2s, box-shadow 0.2s;
}
body .p-selectbutton .p-button .p-button-icon-left {
color: #666666;
}
body .p-selectbutton .p-button:not(.p-disabled):not(.p-highlight):hover {
background-color: #c8c8c8;
border-color: #c8c8c8;
color: #333333;
}
body .p-selectbutton .p-button:not(.p-disabled):not(.p-highlight):hover .p-button-icon-left {
color: #212121;
}
body .p-selectbutton .p-button:not(.p-disabled):not(.p-highlight).ui-state-focus {
box-shadow: 0 0 0 0.2em #8dcdff;
z-index: 1;
}
body .p-selectbutton .p-button.p-highlight {
background-color: pvar(--mainColor);
border-color: pvar(--mainColor);
color: #ffffff;
}
body .p-selectbutton .p-button.p-highlight .p-button-icon-left {
color: #ffffff;
}
body .p-selectbutton .p-button.p-highlight:not(.p-disabled):hover {
background-color: pvar(--mainColorLighter);
border-color: pvar(--mainColorLighter);
color: #ffffff;
}
body .p-selectbutton .p-button.p-highlight:not(.p-disabled):hover .p-button-icon-left {
color: #ffffff;
}
body .p-selectbutton .p-button:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
body .p-selectbutton .p-button:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
body p-selectbutton.ng-dirty.ng-invalid .p-button {
border: 1px solid #a80000;
}

//

@mixin glyphicon-light {
font-family: 'Glyphicons Halflings';
@@ -11,20 +491,9 @@
font-display: swap;
}

my-edit-button,
my-delete-button,
my-button {
height: max-content;
}

// focus box-shadow for primeng
.ui-inputtext:enabled:focus:not(.ui-state-error) {
box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest) !important;
}

// data table customizations
p-table {
.ui-table-caption {
.p-datatable-header {
border: none !important;
background-color: pvar(--mainBackgroundColor) !important;

@@ -54,6 +523,10 @@ p-table {
td {
padding-left: 15px !important;

&.expand-cell {
padding: 10px 15px;
}

&:not(.action-cell):not(.expand-cell):not(.checkbox-cell) {
overflow: hidden !important;
text-overflow: ellipsis !important;
@@ -66,7 +539,7 @@ p-table {
background-color: pvar(--mainBackgroundColor) !important;
height: 46px;

&.ui-state-highlight {
&.p-highlight {
background-color: pvar(--submenuColor) !important;

td, td > a {
@@ -75,7 +548,7 @@ p-table {
}
}

.ui-table-tbody {
.p-datatable-tbody {
tr {
&:hover {
background-color: pvar(--submenuColor) !important;
@@ -115,7 +588,7 @@ p-table {
font-weight: $font-semibold !important;
color: pvar(--mainForegroundColor) !important;

&.ui-sortable-column:hover {
&.p-sortable-column:hover {
background-color: pvar(--submenuColor) !important;
border: 1px solid !important;
border-color: pvar(--submenuColor) !important;
@@ -126,7 +599,7 @@ p-table {
}
}

&.ui-state-highlight {
&.p-highlight {
background-color: pvar(--submenuColor) !important;

.pi {
@@ -170,7 +643,7 @@ p-table {
}

p-paginator {
.ui-paginator-bottom {
.p-paginator-bottom {
background-color: pvar(--mainBackgroundColor) !important;
position: relative;
border: none;
@@ -181,30 +654,31 @@ p-table {
justify-content: center;
align-items: center;

.ui-dropdown {
.p-dropdown {
position: absolute;
top: 3px;
top: 10px;
left: 0;

&.ui-state-focus {
&.p-focus {
box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest);
}

.ui-dropdown-label {
.p-label {
color: pvar(--inputPlaceholderColor);
}
}

.ui-paginator-current {
.p-paginator-current {
position: absolute;
right: 0;
color: pvar(--inputPlaceholderColor);
overflow: visible;
}

.ui-paginator-first,
.ui-paginator-prev,
.ui-paginator-next,
.ui-paginator-last {
.p-paginator-first,
.p-paginator-prev,
.p-paginator-next,
.p-paginator-last {
@include glyphicon-light;
padding: 5px 2px;
height: auto;
@@ -217,42 +691,40 @@ p-table {
box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest);
}

&.ui-state-disabled:hover {
&.p-disabled:hover {
background-color: #fff !important;
}

&.ui-paginator-first {
&.p-paginator-first {
@extend .glyphicon-step-backward;
}

&.ui-paginator-prev {
&.p-paginator-prev {
@extend .glyphicon-chevron-left;

margin-right: 10px;
}

&.ui-paginator-next {
&.p-paginator-next {
@extend .glyphicon-chevron-right;

margin-left: 10px;
}

&.ui-paginator-last {
&.p-paginator-last {
@extend .glyphicon-step-forward;
}
}

.ui-paginator-pages {
.p-paginator-pages {
height: auto !important;

.ui-paginator-page {
.p-paginator-page {
&.focus-within,
&:focus {
box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest) !important;
}
}

a {
color: pvar(--mainForegroundColor) !important;
font-weight: $font-semibold !important;
margin: 0 5px !important;
@@ -262,7 +734,7 @@ p-table {
height: auto !important;
line-height: initial !important;

&.ui-state-active {
&.p-highlight {
&, &:hover, &:active, &:focus {
color: #fff !important;
background-color: pvar(--mainColor) !important;
@@ -277,7 +749,7 @@ p-table {
// overflow data table
@mixin overflow-datatable ($table-min-width, $horizontal-margins, $mobile-paginator: true) {
p-table {
.ui-table-wrapper {
.p-datatable-wrapper {
overflow-x: auto;
max-width: calc(100vw - #{$horizontal-margins * 2});

@@ -287,15 +759,15 @@ p-table {
}

@if $mobile-paginator {
p-paginator .ui-paginator-bottom {
p-paginator .p-paginator-bottom {
display: block;

.ui-paginator-current {
.p-paginator-current {
position: relative;
display: block;
}

a, .ui-paginator-pages {
a, .p-paginator-pages {
vertical-align: middle;
}
}
@@ -304,18 +776,18 @@ p-table {
}

// PrimeNG calendar tweaks
p-calendar .ui-datepicker {
p-calendar .p-datepicker {
a {
@include disable-default-a-behaviour;
}

.ui-datepicker-header {
.p-datepicker-header {

.ui-datepicker-year {
.p-datepicker-year {
margin-left: 5px;
}

.ui-datepicker-next {
.p-datepicker-next {
@extend .glyphicon-chevron-right;
@include glyphicon-light;

@@ -327,7 +799,7 @@ p-calendar .ui-datepicker {
}
}

.ui-datepicker-prev {
.p-datepicker-prev {
@extend .glyphicon-chevron-left;
@include glyphicon-light;

@@ -340,7 +812,7 @@ p-calendar .ui-datepicker {
}
}

.ui-timepicker {
.p-timepicker {

.pi.pi-chevron-up {
@extend .glyphicon-chevron-up;
@@ -358,32 +830,32 @@ p-calendar .ui-datepicker {
}
}

p-tablecheckbox:hover div .ui-chkbox-box {
p-tablecheckbox:hover div .p-checkbox-box {
box-shadow: 0 0 0 .1rem rgba(87, 85, 217, .2);
}

.ui-chkbox {
.p-checkbox {

&, .ui-chkbox-box {
&, .p-checkbox-box {
width: 18px !important;
height: 18px !important;
}

.ui-chkbox-box {
&.ui-state-active {
.p-checkbox-box {
&.p-highlight {
border-color: pvar(--mainColor) !important;
background-color: pvar(--mainColor) !important;
}

.ui-chkbox-icon {
.p-checkbox-icon {
position: relative;
overflow: visible !important;

&:after {
content: '';
position: absolute;
top: 1px;
left: 6px;
bottom: -5px;
left: -2px;
width: 5px;
height: 12px;
opacity: 0;
@@ -400,51 +872,30 @@ p-tablecheckbox:hover div .ui-chkbox-box {
}
}

p-inputswitch {
height: 26px;

.ui-inputswitch-checked .ui-inputswitch-slider {
background-color: pvar(--mainColor) !important;
}

&.small {
height: 20px;

.ui-inputswitch {
width: 2.5em !important;
height: 1.45em !important;

.ui-inputswitch-slider::before {
height: 1em !important;
width: 1em !important;
}
}

.ui-inputswitch-checked .ui-inputswitch-slider::before {
transform: translateX(1em) !important;
}
}
}

p-toast {
.ui-toast {
.p-toast {
width: auto;
max-width: 300px;
z-index: z(notification) !important;

.ui-toast-close-icon {
.p-toast-icon-close {
font-family: "Glyphicons Halflings";
opacity: 0;
position: absolute;
right: 5px;
top: 5px;

&:after {
content: "\e014";
}
}

&:hover .ui-toast-close-icon {
&:hover .p-toast-icon-close {
opacity: .3;
}
}

.ui-toast-message {
.p-toast-message {
font-family: $main-fonts;
background-color: pvar(--mainBackgroundColor) !important;
color: pvar(--mainForegroundColor) !important;
@@ -454,29 +905,30 @@ p-toast {
box-shadow: 0 2px 12px 0 rgba(0, 0 , 0, .1);
overflow: hidden;

&.ui-toast-message-success .glyphicon {
&.p-toast-message-success .glyphicon {
color: #8BC34A !important;
}

&.ui-toast-message-error .glyphicon {
&.p-toast-message-error .glyphicon {
color: #F44336 !important;
}

&.ui-toast-message-warn .glyphicon {
&.p-toast-message-warn .glyphicon {
color: #F1680D !important;
}

&.ui-toast-message-info .glyphicon {
&.p-toast-message-info .glyphicon {
color: #03A9F4 !important;
}

.notification-block {
display: flex;
align-items: center;
padding: 5px;
padding: 10px;

.message {
flex-grow: 1;
margin-right: 20px;

h3 {
font-size: 21px;
@@ -496,6 +948,14 @@ p-toast {
}
}

.ui-widget {
font-family: $main-fonts !important;
.p-selectbutton {
.p-button:focus {
outline: none;
}

.p-button-label {
padding: 5px 15px;
font-size: 15px;
font-weight: 600;
}
}

+ 22
- 22
client/webpack/webpack.video-embed.js View File

@@ -4,8 +4,8 @@ const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const PurifyCSSPlugin = require('purifycss-webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = function () {
const configuration = {
@@ -64,29 +64,29 @@ module.exports = function () {

{
test: /\.(sass|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
use: [
MiniCssExtractPlugin.loader,

{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1
}
},

{
loader: 'sass-loader',
options: {
sassOptions: {
sourceMap: true,
importLoaders: 1
}
},
{
loader: 'sass-loader',
options: {
sassOptions: {
sourceMap: true,
includePaths: [
helpers.root('src/sass/include')
]
}
includePaths: [
helpers.root('src/sass/include')
]
}
}
]
})
}
]
},

{
@@ -111,7 +111,7 @@ module.exports = function () {
},

plugins: [
new ExtractTextPlugin({
new MiniCssExtractPlugin({
filename: process.env.ANALYZE_BUNDLE === 'true'
? '[name].css'
: '[name].[hash].css'


+ 2218
- 2044
client/yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save